如何通过不同的类式启用来连接信号和插槽
我有具有相应自定义模型的自定义列表视图。我将QML用于前端,然后将主文件加载为Python,然后将Python用于后端。 不同模型的模型数据相互取决于彼此。一切都按照预期的方式工作, test - 模型和代表。
由于模型相互依赖,因此我引入了一个“ pythondatamanager”类别,该类别应该从三个模型中获取数据,使用它并将手输出回到相应的模型实例中。 我认为使用信号/老虎机技术QT提供的来做。我连接了不同类别实例的信号和插槽。我宣布了一个从QML中按下按钮调用的插槽。该插槽被执行并应该发出一个信号,因此应在其他类/实例中调用其他插槽。 当我在信号上调用.emit()函数时,什么都不会发生。
我的问题是,如何将不同类别的不同类别与信号和插槽与Pyside连接起来?
以下示例代码的目的是读取self.db属性的timeseriesesmodel类,并将其发送到将其打印出来的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级的相关代码:
@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()slot()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())
}
}
}
}
感谢您的帮助:感谢您的帮助:
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?
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 shorted 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()
def request_handling(self):
self.send_ts_model_data.emit(self.db)
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)
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)
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())
}
}
}
}
Thanks for helping
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我现在自己解决了这个问题。
在 Python 中定义 QML 组件,然后将它们导入到 QML 中,并使用“Connections{}”QML 类型连接 QML 中的信号和槽(请参阅:https://doc.qt.io/qt-6/qml-qtqml-connections.html)有效。
例如,在 QML 文件中添加:
并从 main.py 中删除:
I solved the issue by now by myself.
Defining QML components in Python, importing them afterwards in QML and connecting the signals and slots in the QML with the "Connections{}" QML Type (see: https://doc.qt.io/qt-6/qml-qtqml-connections.html) works.
For example add in the QML File:
and remove from the main.py: