PySide6 QML How to connect signals and slots over different class-instances correctly
-
I have custom listviews with corresponding custom models. I use QML for the frontend and load the main file with Python and use Python for the backend. The model data of the different models depends heavily on each other. Everything works as expected with the different listviews, test-models and delegates.
Since the models depend on each other I introduced a PythonDataManager-class that should get the data from the three models, work with it and hand output back to the the corresponding model instances. I thought to do it with the Signal/Slot technology Qt provides. I connected the signals and slots of the instances of the different classes. I declared a slot I call from a button press in QML. This slot gets executed and should emit one signal, that therefore should call a different slot in a different class/instance. When I call the .emit() function on the signal nothing happens.
My Question is, how can I connect different instances of the different classes with signals and slots with PySide6 correctly?
The goal of the following example code is to read out the self.db attribute of the TimeseriesesModel-class and send it off to the PythonDataManager that prints it out. The expected result is: [{"name": "hello", "selected": True},{"name": "zwei", "selected": False}] but I get a empty list: [].
The shortend code of one of the custom models:
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(result=bool) def request_handling(self): self.send_ts_model_data.emit(self.db) return True
The relevant code of the 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, result=bool) def get_ts_model_data(self, data): self.ts_model_db = data return True # The slot that get's called successfully from QML @Slot(result=bool) def print_something(self): self.askModelsForData.emit() print(self.ts_model_db) return True
The relevant code of the 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())
The code of the qml file that calls the pythonDataManager.print_something() slot:
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()) } } } }
What I am doing wrong? Where/How can I research the problem by myself?(I already looked through the documentation) If you need more information, or if I can improve my question further, please let me know. Thanks
Also Thanks for helping!