QML and Qt for Python interaction
May 14, 2018 by Friedemann Kleint | Comments
Besides QtWidgets for desktop applications, Qt has another UI technology, QML.
Today, I would like to show how QML interacts with Qt for Python, roughly based on the tutorial example declarative/extending/chapter3-bindings.
First, let's have a look at the typical boiler plate code for loading a .qml file. We instantiate a QGuiApplication and a QQuickView.
We set its resize mode property to SizeRootObjectToView so that the QML element is expanded to the view size.
app = QGuiApplication(sys.argv)
view = QQuickView()
view.setResizeMode(QQuickView.SizeRootObjectToView)
We then instruct the view to load the QML file, using the method setSource.
Since a QML file typically is to be found next to the Python script, we construct a complete path using functions of the os module:
current_path = os.path.abspath(os.path.dirname(__file__))
qml_file = os.path.join(current_path, 'app.qml')
view.setSource(QUrl.fromLocalFile(qmlFile))
if view.status() == QQuickView.Error:
sys.exit(-1)
Now, the view can be shown and the application run. To ensure the correct destruction order, del must be invoked on the view object before quitting the application
view.show()
res = app.exec_()
del view
sys.exit(res)
With this code, we can display QML files. For example, a minimal hello world is shown when creating app.qml as follows:
import QtQuick 2.0
Text {
text : 'Hello, world!'
}
Extending QML by using classes written in Python
Let's implement something on top of QQuickPaintedItem:
class PieChart (QQuickPaintedItem):
def __init__(self, parent = None):
QQuickPaintedItem.__init__(self, parent)
self.color = QColor()
def paint(self, painter):
pen = QPen(self.color, 2)
painter.setPen(pen);
painter.setRenderHints(QPainter.Antialiasing, True);
# From drawPie(const QRect &rect, int startAngle, int spanAngle)
painter.drawPie(self.boundingRect().adjusted(1,1,-1,-1),
90 * 16, 290 * 16);
def getColor(self):
return self.color
def setColor(self, value):
if value != self.color:
self.color = value
self.update()
self.colorChanged.emit()
colorChanged = Signal()
color = Property(QColor, getColor, setColor, notify=colorChanged)
This overrides the QQuickPaintedItem.paint() method to draw simple pie chart. The color is defined as property so that it is exposed to Qt. To make the type known to QML, we insert:
qmlRegisterType(PieChart, 'Charts', 1, 0, 'PieChart');
right after creating the QGuiApplication.
app.qml can then be changed to:
import Charts 1.0
import QtQuick 2.0
Item {
width: 300; height: 200
PieChart {
id: chartA
width: 100; height: 100
color: "red"
anchors.centerIn:parent
}
MouseArea {
anchors.fill: parent
onClicked: { chartA.color = "blue" }
}
Text {
anchors {
bottom: parent.bottom;
horizontalCenter: parent.horizontalCenter;
bottomMargin: 20
}
text: "Click anywhere to change the chart color"
}
}
for our custom type to appear.
Additionally, clicking with the mouse will change the color property.
Blog Topics:
Comments
Subscribe to our newsletter
Subscribe Newsletter
Try Qt 6.5 Now!
Download the latest release here: www.qt.io/download.
Qt 6.5 is the latest Long-Term-Support release with all you need for C++ cross-platform app development.
Qt World Summit 2023: Berlin awaits!
We're Hiring
Check out all our open positions here and follow us on Instagram to see what it's like to be #QtPeople.