扩展 QML - 连接到 C++ 方法与信号#
这是关于使用 Python 扩展 QML 的 6 个示例系列中的第二个示例。
假设我们想让 PieChart
具有可以在清除图表后发出 chartCleared
信号的 clearChart()
方法。
4import Charts
5import QtQuick
6
7Item {
8 width: 300; height: 200
9
10 PieChart {
11 id: aPieChart
12 anchors.centerIn: parent
13 width: 100; height: 100
14 color: "red"
15
16 onChartCleared: console.log("The chart has been cleared")
17 }
18
19 MouseArea {
20 anchors.fill: parent
21 onClicked: aPieChart.clearChart()
22 }
23
24 Text {
25 anchors {
26 bottom: parent.bottom;
27 horizontalCenter: parent.horizontalCenter;
28 bottomMargin: 20
29 }
30 text: "Click anywhere to clear the chart"
31 }
32}
为此,我们在我们的 C++ 类中添加一个 clearChart()
方法和一个 chartCleared()
信号。
54 @Slot() # This should be something like @Invokable
55 def clearChart(self):
56 self.color = Qt.transparent
57 self.update()
58 self.chartCleared.emit()
使用 Slot
装饰器使 clearChart()
方法可用于 Qt 元对象系统,进而可用于 QML。该方法只是将颜色更改为 Qt::transparent
,重新绘制图表,然后发出 chartCleared()
信号。
21@QmlElement
22class PieChart(QQuickPaintedItem):
23
24 chartCleared = Signal()
现在当运行应用程序并点击窗口时,饼图消失,应用程序输出
qml: The chart has been cleared
# Copyright (C) 2022 The Qt Company Ltd.
# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
"""PySide6 port of the qml/tutorials/extending-qml/chapter2-methods example from Qt v5.x"""
import os
from pathlib import Path
import sys
from PySide6.QtCore import Property, Signal, Slot, Qt, QUrl
from PySide6.QtGui import QGuiApplication, QPen, QPainter, QColor
from PySide6.QtQml import QmlElement
from PySide6.QtQuick import QQuickPaintedItem, QQuickView
# To be used on the @QmlElement decorator
# (QML_IMPORT_MINOR_VERSION is optional)
QML_IMPORT_NAME = "Charts"
QML_IMPORT_MAJOR_VERSION = 1
@QmlElement
class PieChart(QQuickPaintedItem):
chartCleared = Signal()
nameChanged = Signal()
def __init__(self, parent=None):
QQuickPaintedItem.__init__(self, parent)
self._name = u''
self._color = QColor()
def paint(self, painter):
pen = QPen(self.color, 2)
painter.setPen(pen)
painter.setRenderHints(QPainter.Antialiasing, True)
painter.drawPie(self.boundingRect().adjusted(1, 1, -1, -1), 90 * 16, 290 * 16)
@Property(QColor, final=True)
def color(self):
return self._color
@color.setter
def color(self, value):
self._color = value
@Property(str, notify=nameChanged, final=True)
def name(self):
return self._name
@name.setter
def name(self, value):
self._name = value
@Slot() # This should be something like @Invokable
def clearChart(self):
self.color = Qt.transparent
self.update()
self.chartCleared.emit()
if __name__ == '__main__':
app = QGuiApplication(sys.argv)
view = QQuickView()
view.setResizeMode(QQuickView.SizeRootObjectToView)
qml_file = os.fspath(Path(__file__).resolve().parent / 'app.qml')
view.setSource(QUrl.fromLocalFile(qml_file))
if view.status() == QQuickView.Error:
sys.exit(-1)
view.show()
res = app.exec()
# Deleting the view before it goes out of scope is required to make sure all child QML instances
# are destroyed in the correct order.
del view
sys.exit(res)
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
import Charts
import QtQuick
Item {
width: 300; height: 200
PieChart {
id: aPieChart
anchors.centerIn: parent
width: 100; height: 100
color: "red"
onChartCleared: console.log("The chart has been cleared")
}
MouseArea {
anchors.fill: parent
onClicked: aPieChart.clearChart()
}
Text {
anchors {
bottom: parent.bottom;
horizontalCenter: parent.horizontalCenter;
bottomMargin: 20
}
text: "Click anywhere to clear the chart"
}
}