QML - .qml 文件中的“连接”不会触发来自 python 脚本的信号
Posted
技术标签:
【中文标题】QML - .qml 文件中的“连接”不会触发来自 python 脚本的信号【英文标题】:QML - The "Connections" from .qml file doesn't fire the signal from python script 【发布时间】:2020-12-16 01:26:29 【问题描述】:这是 main.py 脚本:
import sys, os, math
import numpy as np
from PyQt5 import *
class Tab(QFrame):
def __init__(self):
super().__init__()
self.setGeometry(600, 600, 600, 600)
self.setWindowTitle("PyQt5 Tab Widget")
self.setWindowIcon(QIcon("../QML Files/Icons/Tab.png"))
vbox = QVBoxLayout()
tabWidget = QTabWidget()
tabWidget.addTab(Example01(), "Ex1")
vbox.addWidget(tabWidget)
self.setLayout(vbox)
class GG(QObject):
def __init__(self, parent=None):
super().__init__(parent)
self._polygons = []
@pyqtSlot()
def modify_Polygons(self) -> None:
animation = QVariantAnimation(self)
animation.setStartValue(0)
animation.setEndValue(10)
animation.valueChanged.connect(
lambda value: GG.set_dynamic_polygons(value, self)
)
animation.setDuration(10 * 1000)
animation.start(QAbstractAnimation.DeleteWhenStopped)
polygonschanged = pyqtSignal(str)
def get_polygons(self) -> None:
return self._polygons
def set_polygons(self, polygons):
self._polygons = polygons
self.polygonschanged.emit("Test")
polygons = pyqtProperty(
"QVariant", fget=get_polygons, fset=set_polygons,
notify=polygonschanged
)
def set_dynamic_polygons(i, p_gg) -> None:
numpy_arrays = np.array(
[[[100+3*i, 100], [150, 200], [50, 300]],
[[50, 60], [160, 20], [400, 10]]]
)
def set_polygons(myArray) -> []:
polygons = []
for ps in myArray:
polygon = []
# print("ps = "); print(ps)
for p in ps:
# print("p = "); print(p)
e = QPointF(*p)
polygon.append(e)
polygons.append(polygon)
return polygons
p_gg.polygons = set_polygons(numpy_arrays)
class Example01(QWidget):
def __init__(self):
super().__init__()
vbox = QVBoxLayout(self)
vbox.setContentsMargins(0, 0, 0, 0)
self.gg = GG()
GG.set_dynamic_polygons(0, self.gg)
view = QQuickWidget()
view.rootContext().setContextProperty("gg", self.gg)
ROOT_DIR = os.path.realpath(os.path.dirname(sys.argv[0]))
qml = os.path.join(ROOT_DIR, "QML Files", "Demo02.qml")
view.setSource(QUrl.fromLocalFile(qml))
view.setResizeMode(QQuickWidget.SizeRootObjectToView)
vbox.addWidget(view)
if __name__ == "__main__":
App = QApplication(sys.argv)
tabDialog = Tab()
tabDialog.show()
App.exec()
这是 Demo02.qml 脚本:
import QtQuick 2.14
import QtQuick.Window 2.14
import QtGraphicalEffects 1.0
import QtQuick.Controls 2.15
Rectangle
id: rect
visible: true
anchors.fill: parent
LinearGradient
anchors.fill: parent
//setting gradient at 45 degrees
start: Qt.point(rect.width, 0)
end: Qt.point(0, rect.height)
gradient: Gradient
GradientStop position: 0.0; color: "#ee9d9d"
GradientStop position: 1.0; color: "#950707"
Button
id: btn
width: 100
height: 30
x: parent.width - btn.width - 20
y: parent.height - btn.height - 20
text: "Animate!"
onClicked: gg.modify_Polygons()
Canvas
id: drawingCanvas
anchors.fill: parent
onPaint:
var ctx = getContext("2d")
ctx.fillStyle = "rgb(100%,70%,30%)"
ctx.lineWidth = 5
ctx.strokeStyle = "blue"
//console.log(gg)
for(var i in gg.polygons)
var polygon = gg.polygons[i]
ctx.beginPath()
for(var j in polygon)
var p = polygon[j]
if(j === 0)
ctx.moveTo(p.x, p.y)
else
ctx.lineTo(p.x, p.y)
ctx.closePath()
ctx.fill()
ctx.stroke()
Connections
target: gg
function onpolygonschanged(strng)
console.log(strng)
drawingCanvas.requestPaint()
除了 Demo02.qml 文件末尾的 Connections 指令并没有真正调用 polygonschanged 之外,一切运行正常来自 python 的信号。
我刚刚插入了console.log("Test")
来检查是否发出信号以便被.qml 文件看到,但我没有收到任何反应。
我不得不提一下,画布最初显示了 2 个三角形,但是当我单击“激活!”时按钮画布显示相同的三角形,但不对其进行动画处理。
有人可以建议如何正确设置 .qml 文件中的“连接”吗?
【问题讨论】:
【参考方案1】:在qml中与信号关联的函数名必须是CamelCase,即:
Connections
target: gg
function onPolygonsChanged(strng)
console.log(strng)
drawingCanvas.requestPaint()
【讨论】:
是的。它正在工作。感谢您的回答。以上是关于QML - .qml 文件中的“连接”不会触发来自 python 脚本的信号的主要内容,如果未能解决你的问题,请参考以下文章
在 Component.onCompleted 之前初始化 QML 信号