简体   繁体   English

Pyside6 中的信号

[英]Signals in Pyside6

I can't figure out why the signals don't work.我无法弄清楚为什么信号不起作用。 In PyQt5, this code worked (the difference was that instead of Signal, it was pyqtSignal).在 PyQt5 中,此代码有效(不同之处在于它不是 Signal,而是 pyqtSignal)。

When you click on the button, TextEdit should display the message "connecting to the device", if you replace pyside with pyqt, the code will work as it should单击按钮时,TextEdit 应显示消息“正在连接到设备”,如果将 pyside 替换为 pyqt,代码将正常工作

import sys
from PySide6.QtCore import *
from PySide6.QtWidgets import *


class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        if not MainWindow.objectName():
            MainWindow.setObjectName(u"MainWindow")
        MainWindow.resize(188, 267)
        self.centralwidget = QWidget(MainWindow)
        self.centralwidget.setObjectName(u"centralwidget")
        self.pushButton = QPushButton(self.centralwidget)
        self.pushButton.setObjectName(u"pushButton")
        self.pushButton.setGeometry(QRect(50, 140, 75, 24))
        self.textEdit = QTextEdit(self.centralwidget)
        self.textEdit.setObjectName(u"textEdit")
        self.textEdit.setGeometry(QRect(30, 40, 104, 71))
        MainWindow.setCentralWidget(self.centralwidget)
        self.retranslateUi(MainWindow)
        QMetaObject.connectSlotsByName(MainWindow)
    def retranslateUi(self, MainWindow):
        MainWindow.setWindowTitle(QCoreApplication.translate("MainWindow", u"MainWindow", None))
        self.pushButton.setText(QCoreApplication.translate("MainWindow", u"PushButton", None))

class MainWindow(QMainWindow):
    def __init__(self):
        QMainWindow.__init__(self, parent=None)
        self.dragPos = None
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
        self.show()

def update_text(value, textEdit):
    textEdit.setText(textEdit.toPlainText() + value)
    textEdit.verticalScrollBar().setValue(textEdit.verticalScrollBar().maximum())
class account(QThread):
    textUpdate = Signal(str, QTextEdit)

    def __init__(self):
        super().__init__(parent=None)
        self.textUpdate.connect(update_text)

    def run(self):
        print("thread is work")
        self.textUpdate.emit("Connect to device\n", ui.textEdit)
        
if __name__ == "__main__":
    app = QApplication()
    acc_instance = account()
    main = MainWindow()
    ui = main.ui
    ui.pushButton.clicked.connect(acc_instance.start)
    sys.exit(app.exec_())

PS I know that override run method is incorrect. PS我知道覆盖运行方法不正确。

PSS Added a small example PSS 加了一个小例子

Your code has several problems:您的代码有几个问题:

  1. The scope of "ui" is limited, it is not a global variable so you cannot use it in the run method. "ui" 的 scope 是有限的,它不是一个全局变量,所以你不能在 run 方法中使用它。

  2. Only some data types are registered (which can only be done in C++) so that they can be sent through signals, and that is not the case with QTextEdit.只注册了一些数据类型(只能在 C++ 中完成),以便它们可以通过信号发送,而 QTextEdit 不是这种情况。 A workaround is to look for a parent class of the QTextEdit that is registered as a QObject or an object.一种解决方法是查找注册为 QObject 或 object 的 QTextEdit 的父 class。

But in this case I do not see the need to send QTextEdit but only the data and then modify the GUI to set it since that is its task.但在这种情况下,我认为不需要发送 QTextEdit,而只需要发送数据,然后修改 GUI 以设置它,因为这是它的任务。

class MainWindow(QMainWindow):
    def __init__(self, parent=None):
        QMainWindow.__init__(self, parent)
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)

    @Slot(str)
    def update_text(self, value):
        self.ui.textEdit.setText(self.ui.textEdit.toPlainText() + value)
        self.ui.textEdit.verticalScrollBar().setValue(
            self.ui.textEdit.verticalScrollBar().maximum()
        )


class Account(QThread):
    textUpdate = Signal(str)

    def run(self):
        print("thread is work")
        self.textUpdate.emit("Connect to device\n")


if __name__ == "__main__":
    app = QApplication()

    main = MainWindow()
    acc_instance = Account()

    acc_instance.textUpdate.connect(main.update_text)
    main.ui.pushButton.clicked.connect(acc_instance.start)

    main.show()

    sys.exit(app.exec_())

Note: In pyqt6 your initial code doesn't work either.注意:在 pyqt6 中,您的初始代码也不起作用。

If you want to send texts to several QTextEdit then it is better to create a key that associates each type of text to a QTextEdit group:如果要将文本发送到多个 QTextEdit,那么最好创建一个将每种类型的文本关联到 QTextEdit 组的键:

from collections import defaultdict
from functools import cached_property


class MainWindow(QMainWindow):
    def __init__(self):
        QMainWindow.__init__(self, parent=None)
        self.dragPos = None
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
        self.show()

        self.register("device_viewer", self.ui.textEdit)
        # self.register("another_key", another_textedit)

    def register(self, key, textedit):
        if not isinstance(textedit, QTextEdit):
            raise TypeError(f"{textedit} must be a QTextEdit")
        self.registry_viewers[key].append(textedit)

    @cached_property
    def registry_viewers(self):
        return defaultdict(list)

    @Slot(str, str)
    def update_text(self, key, value):
        for textedit in self.registry_viewers[key]:
            textedit.setText(textedit.toPlainText() + value)
            textedit.verticalScrollBar().setValue(
                textedit.verticalScrollBar().maximum()
            )


class Account(QThread):
    textUpdate = Signal(str, str)

    def run(self):
        print("thread is work")
        self.textUpdate.emit("device_viewer", "Connect to device\n")
        # self.textUpdate.emit("another_key", "message")


if __name__ == "__main__":
    app = QApplication()

    main = MainWindow()
    acc_instance = Account()

    acc_instance.textUpdate.connect(main.update_text)
    main.ui.pushButton.clicked.connect(acc_instance.start)

    sys.exit(app.exec_())

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

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