繁体   English   中英

如何通过不同的类实例连接信号和插槽

[英]How to connect signals and slots over different class-instances

我有带有相应自定义模型的自定义列表视图。 我使用 QML 作为前端并使用 Python 加载主文件并使用 python 作为后端。 不同模型的模型数据相互依赖很大。 使用不同的列表视图、测试模型和委托,一切都按预期工作。

由于模型相互依赖,我引入了一个“PythonDataManager”-Class,它应该从三个模型中获取数据,使用它并将输出返回给相应的模型实例。 我想用 Qt 提供的 Signal/Slot 技术来做到这一点。 我连接了不同类实例的信号和插槽。 我声明了一个通过 QML 中的按钮按下来调用的插槽。 这个槽被执行并且应该发出一个信号,因此应该在不同的类/实例中调用不同的槽。 当我在信号上调用 .emit() 函数时,什么也没有发生。

我的问题是,如何使用 PySide6 将不同类的不同实例与信号和插槽连接起来?

以下示例代码的目标是读取 TimeseriesesModel 类的 self.db 属性并将其发送到 PythonDataManager 打印出来。 预期的结果是:[{“name”:“hello”,“selected”:True},{“name”:“zwei”,“selected”:False}]但我得到一个空列表:[]。

自定义模型之一的短代码:

QML_IMPORT_NAME = "library.measure"
QML_IMPORT_MAJOR_VERSION = 1

@QmlElement
class TimeseriesesModel(QAbstractListModel):
    SelectedRole = Qt.UserRole + 1
    NameRole = Qt.UserRole + 2
    
    # The signal that later gets emitted
    send_ts_model_data = Signal(list)


    def __init__(self, parent=None):
        super().__init__(parent=parent)
        self.db = [
            {"name": "hello", "selected": True},
            {"name": "zwei", "selected": False},
        ]

    # --- In this place I left out a lot of code that shouldn't be relevant
    #----------------------------------------------------------------------
    
    # The slot, that should get called by the "askModelsForData" signal
    @Slot()
    def request_handling(self):
        self.send_ts_model_data.emit(self.db)

PythonDataManager-Class的相关代码:

@QmlElement
class PythonDataManager(QObject):
    askModelsForData = Signal()

    def __init__(self,  parent=None):
        super(PythonDataManager, self).__init__(parent=parent)
        self.ts_model_db = []

    @Slot(list)
    def get_ts_model_data(self, data):
        self.ts_model_db = data
    
    # The slot that get's called successfully from QML
    @Slot()
    def print_something(self):
        self.askModelsForData.emit()
        print(self.ts_model_db)

main.py的相关代码:

if __name__ == "__main__":
    app = QGuiApplication(sys.argv)
    
    data_manager = PythonDataManager()
    ts_model = TimeseriesesModel()

    # Connect the signals and the slots
    data_manager.askModelsForData.connect(ts_model.request_handling)
    ts_model.send_ts_model_data.connect(data_manager.get_ts_model_data)
    

    engine = QQmlApplicationEngine()
    engine.rootContext().setContextProperty("TimeseriesesModel", ts_model)
    engine.rootContext().setContextProperty("PythonDataManager", data_manager)
    engine.load(os.fspath(Path(__file__).resolve().parent / "main.qml"))
    if not engine.rootObjects():
        sys.exit(-1)
    sys.exit(app.exec())

调用 pythonDataManager.print_something() 槽的 qml 文件的代码:

import QtQuick 2.0
import QtQuick.Window
import library.measure // The library that gets invoked in the python part 
import QtQuick.Controls

Item {
    id: root

    PythonDataManager {
        id:pythonDataManager
    }

    // Lists the Different Window/ScreenQMLs--------------------------
    // (In the reprex only one)
    Window {
        id: accessGrantedWindow

        visible: true

        minimumWidth: 955
        minimumHeight: 730

        Button {
            id: resetButton
            x: 0
            y: 0
            width: 88
            height: 25
            text: qsTr("Reset All")

            onClicked: {
                // The print_something() slot gets called successfully
                console.log(pythonDataManager.print_something())
            }
        }
    }
}

感谢您的帮助

我现在自己解决了这个问题。

在 Python 中定义 QML 组件,然后在 QML 中导入它们,并使用“Connections{}”QML 类型连接 QML 中的信号和插槽(参见: https ://doc.qt.io/qt-6/qml-qtqml- connections.html ) 有效。

例如在 QML 文件中添加:

TimeseriesesModel {
        id:ts_model
    }

Connections { 
    target: pythonDataManager
    function onAskModelsForData() {
                console.log("received onAskModelsForData-signal")
                // Call your slot here like id.slot()
                ts_model.request_handling()
    }
}

并从 main.py 中删除:

# Connect the signals and the slots
    data_manager.askModelsForData.connect(ts_model.request_handling)
    ts_model.send_ts_model_data.connect(data_manager.get_ts_model_data)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM