gpt4 book ai didi

python - PySide2 中 QScxmlStateMachine.connectToEvent 的奇怪行为

转载 作者:行者123 更新时间:2023-12-01 09:15:46 37 4
gpt4 key购买 nike

我正在尝试在后端使用 Python、在前端使用 QML 以及用于创建状态机的 scxml 来编写桌面应用程序。我正在使用 PySide2。我的目的是通过状态机来描述应用程序的逻辑。根据状态,QML 中的 UI 应做出相应 react 。另外,后端应该根据输入状态等执行方法。

我的项目由 3 个文件组成:带有后端逻辑的 main.py、带有 UI 的 ui.qml、带有状态机的 stateMachine.scxml .

main.py的内容:

from PySide2.QtScxml import QScxmlStateMachine
from PySide2.QtWidgets import QApplication
from PySide2.QtCore import QUrl, QObject, Slot
from PySide2.QtQml import QQmlApplicationEngine


class BackEnd(QObject):
def __init__(self):
super().__init__()

@Slot()
def ev_slot(self):
'''method called on event t1'''
print('event t1')

@Slot(bool)
def st_slot(self, active):
'''method called on entering and exiting state s2'''
if active:
print('s2 entered')
else:
print('s2 exited')


app = QApplication([])
qml_url = QUrl("ui.qml")

engine = QQmlApplicationEngine()

# loading state machine
my_state_machine = QScxmlStateMachine.fromFile('stateMachine.scxml')

backend = BackEnd()

# registering state machine in QML context
engine.rootContext().setContextProperty("stateMachine", my_state_machine)
# connecting event of state machine to method of backend
conn1 = my_state_machine.connectToEvent("t1", backend, "aev_slot()")
# connecting state of state machine to method of backend
conn2 = my_state_machine.connectToState("s2", backend, "ast_slot(bool)")

my_state_machine.start()

engine.load(qml_url)

app.exec_()

UI 非常简单:它仅由 3 个按钮组成,这些按钮将事件提交到状态机(ui.qml 文件):

import QtQuick 2.0
import QtQuick.Controls 2.2


ApplicationWindow {
width: column.width
height: column.height
visible: true

Column {
id: column
spacing: 10
Button {
id: button0
text: qsTr("t1")
onClicked: stateMachine.submitEvent('t1')
}

Button {
id: button1
text: qsTr("t2")
onClicked: stateMachine.submitEvent('t2')
}

Button {
id: button2
text: qsTr("t3")
onClicked: stateMachine.submitEvent('t3')
}
}

}

状态机stateMachine.scxml由3个状态组成:s1s2s3和转换t1t2t3:

<?xml version="1.0" encoding="UTF-8"?>
<scxml xmlns="http://www.w3.org/2005/07/scxml" version="1.0" binding="early" xmlns:qt="http://www.qt.io/2015/02/scxml-ext" name="stateMachine" initial="s1">
<state id="s1">
<transition type="external" event="t1" target="s2"/>
<onentry>
<log label="entered" expr="s1"/>
</onentry>
</state>
<state id="s2">
<transition type="external" event="t2" target="s3"/>
<onentry>
<log label="entered" expr="s2"/>
</onentry>
</state>
<state id="s3">
<transition type="external" event="t3" target="s1">
</transition>
<onentry>
<log label="entered" expr="s3"/>
</onentry>
</state>
</scxml>

这里的问题是一切正常。 my_state_machine.connectToEvent("t1", backend, "aev_slot()") 行有一个错误:方法名称是 ev_slot(),而不是 aev_slot()。但如果我将其更改为正确的名称,则会收到以下错误:

QObject::connect: No such slot BackEnd::v_slot()

不知何故,方法名称中的第一个字母被忽略。难道我做错了什么?我对 Qt 和 PySide2 非常陌生。总体而言这是一个好的方法吗?我正在使用 PySide2 5.11.1a1.dev1530708810518

最佳答案

您必须使用 SLOT() 将方法作为字符串传递(请记住,SLOTSlot 装饰器不同) )。

from PySide2 import QtCore, QtGui, QtQml, QtScxml


class BackEnd(QtCore.QObject):
@QtCore.Slot()
def ev_slot(self):
'''method called on event t1'''
print('event t1')

@QtCore.Slot(bool)
def st_slot(self, active):
'''method called on entering and exiting state s2'''
if active:
print('s2 entered')
else:
print('s2 exited')


if __name__ == '__main__':
import sys
app = QtGui.QGuiApplication(sys.argv)
qml_url = QtCore.QUrl.fromLocalFile("ui.qml")

# loading state machine
my_state_machine = QtScxml.QScxmlStateMachine.fromFile('stateMachine.scxml')

backend = BackEnd()
conn1 = my_state_machine.connectToEvent("t1", backend, QtCore.SLOT("ev_slot()"))
conn2 = my_state_machine.connectToState("s2", backend, QtCore.SLOT("st_slot(bool)"))
my_state_machine.start()

engine = QtQml.QQmlApplicationEngine()
engine.rootContext().setContextProperty("stateMachine", my_state_machine)
engine.load(qml_url)

if not engine.rootObjects():
sys.exit(-1)

sys.exit(app.exec_())
<小时/>

SLOT 仅在插槽名称前添加 1 前缀,而 SIGNAL 对 2 的做法相同,因此如果您不想仅使用前缀 1:(..., backend, "1ev_slot()"),(我不建议这样做,因为它会降低代码的可读性)

关于python - PySide2 中 QScxmlStateMachine.connectToEvent 的奇怪行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51273355/

37 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com