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);
}
else
{
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

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

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

Text{
id:toolTipText
width: parent.parent.toolTip.length * toolTipText.font.pixelSize / 2
height: toolTipText.lineCount * (toolTipText.font.pixelSize + 5)
text: parent.parent.toolTip
color:"black"
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

References:

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

No comments: