PyQt和QML:如何在一个插槽或函数中处理多个信号

2024-10-04 05:33:49 发布

您现在位置:Python中文网/ 问答频道 /正文

我现在花了相当长的时间来研究如何将QML信号连接到python中的插槽,以及如何再次与qmlgui通信。但是我不知道如何在python中将多个GUI输入发送到同一个slot/函数。在

下面是一个关于应该发生的事情的基本示例: 用户在GUI中操纵spinbox,它们的总和再次显示在GUI中。 我假设这可以通过将多个信号路由到一个插槽来完成,或者将每个信号路由到一个单独的插槽中,然后让python以某种方式进行组合。但显然pyqt插槽也不允许“返回”。在

非常感谢您的帮助!在

质量管理: (这些评论行是我认为可能有用的,但实际上行不通。当信号行未被注释时,它会导致“预期的标记‘identifier’”。)

import QtQuick 2.6
import QtQuick.Controls 2.0

ApplicationWindow{
    visible:true
    width:200
    height:300
    id:window
    title: "Signal/Slot Test"

    Rectangle{

        //signal somethingChanged(int, int)

        //function exportSignals() {
        //    somethingChanged(spin1.value, spin2.value)
        //}

        Column {
            spacing: 20
            width: parent.width


            SpinBox {
                id: spin1
                signal sig_spin1(int spin1_int)
                objectName: "spin1"
                value: 50
                width: 120
                editable: true
                Component.onCompleted: {
                    console.log("Spin1: " + spin1.value)
                    sig_spin1(spin1.value)
                    //exportSignals()
                }
                onValueChanged: {
                    console.log("Spin1: " + spin1.value)
                    sig_spin1(spin1.value)
                    //exportSignals()
                }
            }

            SpinBox {
                id: spin2
                signal sig_spin2(int spin2_int)
                objectName: "spin2"
                value: 50
                width: 120
                editable: true
                Component.onCompleted: {
                    console.log("Spin2: " + spin2.value)
                    sig_spin2(spin2.value)
                    //exportSignals()
                }
                onValueChanged: {
                    console.log("Spin2: " + spin2.value)
                    sig_spin2(spin2.value)
                    //exportSignals()
                }
            }

            Label {
                id: label_spin1
                objectName: "label_spin1"
                text: "Start Value"
            }

            Label {
                id: label_spin2
                objectName: "label_spin2"
                text: "Start Value"
            }

            Label {
                id: label_result
                objectName: "label_result"
                text: "Sum"
            }

        }
    }
}

以及python代码:

^{pr2}$

更新。为了完整起见,请举一个工作示例: 主.py公司名称:

import sys

from PyQt5.QtCore import pyqtSignal, pyqtSlot, pyqtProperty,     QCoreApplication, QObject, QUrl
from PyQt5.QtQml import QQmlEngine, QQmlApplicationEngine
from PyQt5.QtWidgets import QApplication



class GuiInteraction(QObject):


    def __init__(self, parent=None):
        super().__init__(parent)


    @pyqtSlot(int, int, result=int)
    def get_sum(self, spin1, spin2):
        print("Spin1 from python: ", spin1)
        print("Spin2 from the same python slot: ", spin2)
        my_sum = spin1 + spin2
        print(my_sum)
        print()
        return my_sum




if __name__ == "__main__":
    app = QApplication(sys.argv)
    guiInteraction = GuiInteraction()

    engine = QQmlApplicationEngine()
    ctx = engine.rootContext()
    ctx.setContextProperty("guiInteraction", guiInteraction)
    engine.load('main.qml')
    win = engine.rootObjects()[0]


    win.show()
    sys.exit(app.exec_())

以及主.qml公司名称:

import QtQuick 2.6
import QtQuick.Controls 2.0

ApplicationWindow{
    visible:true
    width:200
    height:300
    id:window
    title: "Signal/Slot Test"



    Rectangle{

        Column {
            spacing: 20
            width: parent.width


            SpinBox {
                id: spin1
                value: 50
                width: 120
                editable: true
                Component.onCompleted: {
                    console.log("Spin1: " + spin1.value)

                }
                onValueChanged: {
                    console.log("Spin1: " + spin1.value)

                    label_result.text = guiInteraction.get_sum(spin1.value, spin2.value)
                }
            }

            SpinBox {
                id: spin2
                value: 50
                width: 120
                editable: true
                Component.onCompleted: {
                    console.log("Spin2: " + spin2.value)

                }
                onValueChanged: {
                    console.log("Spin2: " + spin2.value)
                    label_result.text = guiInteraction.get_sum(spin1.value, spin2.value)
                }
            }


            Label {
                id: label_result
                objectName: "label_result"
                text: "Nothing yet."
            }

        }
    }
}

Tags: textimportlogidtruevalueresultwidth
2条回答

你不能用你建议的方式把两个信号连接到同一个插槽。信号所做的只是触发插槽中的代码运行一次;它不像电子设备中的物理线那样是真正的连续连接(这正是我想象中你可能会想到的)。在

当一个spinbox值更改时,您需要检索另一个spinbox值(从spinbox本身、标签或存储它的另一个变量)来执行加法。例如:

def spin1_update(spin1_int):
    print("Spin 1 updated")
    label_spin1 = win.findChild(QObject, "label_spin1")
    label_spin1.setProperty("text", spin1_int)
    spin_sum()

def spin2_update(spin2_int):
    print("Spin 2 updated")
    label_spin2 = win.findChild(QObject, "label_spin2")
    label_spin2.setProperty("text", spin2_int)
    spin_sum()

def spin_sum():
    spin1 = win.findChild(QObject, "spin1")
    spin2 = win.findChild(QObject, "spin2")
    my_sum = spin1.value() + spin2.value()

    label_result = win.findChild(QObject, "label_result")
    label_result.setProperty("text", my_sum)

在这种情况下,不需要将spin_sum()连接到任何东西。它已经被前面两个slot函数直接调用了。在

首先,在Python或C++方面,你不会做任何这些,特别是不更新值标签。在

对于值标签,您只需使用属性绑定,例如:

Label {
    text: "Start value: " + spin1.value
}

对于像求和这样的琐碎计算,你也会这样做。在

现在,假设计算更复杂,并且您希望在Python端执行此操作,那么在QML端就不需要任何信号。在

相反,一种选择是在Python中有一个QObject派生类,该类提供一个接受两个参数的slot。在

该对象的实例将通过QML引擎的setContextProperty()机制公开给QML。 然后,每个spinbox'onValueChanged处理程序可以使用这两个值来调用这个插槽。在

对于结果,slot可以返回值,或者对象可以提供由slot更新的result属性,该属性在QML中用作结果标签上的绑定。在

相关问题 更多 >