Sunday, April 1, 2012

Return Multiple Values to QML from C++

In some cases it is required to return several values from a C++ function to the QML code. In my case, I call the function that checks the syntax of the Qt script that is passed as a string. The QScriptSyntaxCheckResult class does that check for me. If an error is found inside the script, I want to get back the error message and the line and column where the error was detected. In this case a QVariantMap class is the elegant and effective solution. In my C++ code, I pack the values I want to return into an instance of a QVariantMap class:

QVariantMap QMLFile::checkScriptSyntax(QString input) const
QScriptSyntaxCheckResult result = QScriptEngine::checkSyntax(input);

QVariantMap value;
value.insert("errorMessage", result.errorMessage());
value.insert("errorLineNumber", result.errorLineNumber());
value.insert("errorColumnNumber", result.errorColumnNumber());
return value;

In my QML code, I can now access the values in the following manner, after opening a file that contains a Qt script and passing its contents to the C++ function:

onClicked: {
var fileContent = QMLFile.getFileContents();
var result = QMLFile.checkScriptSyntax(fileContent);

if(result.errorMessage !== "")
console.log("Error on line " + result.errorLineNumber + ", column " + result.errorColumnNumber + " : " + result.errorMessage);
console.log("Script syntax is correct!");

The result is further used in the ToolTipRectangle element, which is a Text element that appears when the mouse is hovered over the line which contains an error.

import QtQuick 1.1

Rectangle {

property string toolTip : ""
property bool showToolTip: false

id: toolTipRectangle
anchors.horizontalCenter: parent.horizontalCenter parent.bottom
width: parent.toolTip.length * toolTipText.font.pixelSize / 2
height: toolTipText.lineCount * (toolTipText.font.pixelSize + 5)

visible: parent.toolTip !== "" && parent.showToolTip
color: "#ffffaa"
border.color: "#0a0a0a"

width: parent.parent.toolTip.length * toolTipText.font.pixelSize / 2
height: toolTipText.lineCount * (toolTipText.font.pixelSize + 5)
text: parent.parent.toolTip
wrapMode: Text.WordWrap

MouseArea {
id: toolTipArea
anchors.fill: parent
onEntered: {
parent.showToolTip = true
onExited: {
parent.showToolTip = false
hoverEnabled: true

The end result looks like this:

Syntax check result


Q_INVOKABLE member function: Valid argument types
Implementing tool tips in QML by . Also posted on my website

No comments: