python - Qt : Updating UI (with signals) from another class and thread

标签 python multithreading qt pyqt pyqt4

我正在为 TCP 服务器开发一个简单的 UI,并且需要使用从服务器发送的日志消息来更新 UI,但问题是与该服务器的任何连接都位于单独的线程中,所以我不能直接触摸 UI 的小部件(因为它们不可重入)。

我读过一些有关该主题的文章,并选择了看起来最优雅(且简单)的方法:信号。

我已完成以下操作:

class Ui_Dialog(QtCore.QObject):

    def __init__(self):
        super(QtCore.QObject, self).__init__()

    def setupUi(self, Dialog):        
        Dialog.setObjectName(_fromUtf8("Dialog"))
        Dialog.resize(800, 580)
        self.serverLog = QtGui.QTextEdit(Dialog)
        self.serverLog.setGeometry(QtCore.QRect(0, 0, 800, 480))
        self.serverLog.setObjectName(_fromUtf8("serverLog"))
        #OTHER WIDGETS AND CODE DEFINED HERE

        self.server = None

        #SIGNALS
        self.clearLogButton.clicked.connect(self.serverLog.clear)
        self.stopButton.clicked.connect(self.connectServer)
        self.startButton.clicked.connect(self.connectServer)

    def connectServer(self):
        if (self.server is None):

            host = str(self.ipEdit.text())
            port = int(self.portEdit.text())

            try:
                self.server = server.MainServer((host, port), server.MyHTTPHandler)
                self.server.setup(self)

                self.printLog( "Hooray ! Server connected at {}:{}".format(host, port) )

                # Start a thread with the server -- that thread will then start one more thread for each request
                MainServer_thread = threading.Thread(target=self.server.serve_forever)
                MainServer_thread.daemon = True
                self.server.trigger.connect(QtCore.QObject(self.printLog))
                MainServer_thread.start()         

                self.server.trigger.connect(self.printLog)

            except errno.EADDRINUSE:
                self.printLog("#ERROR: Address already in use. Try a different port.")
            except errno.EADDRNOTAVAIL:
                self.printLog("#ERROR: Address not available.")


    def printLog(self, string):
        self.serverLog.append(_fromUtf8(string))

在服务器类中:

class MainServer(SocketServer.ThreadingMixIn, SocketServer.TCPServer):
    trigger = QtCore.pyqtSignal(str)

    def printLog(self, message):
        print message
        self.trigger.emit(message)

但是当我运行我的应用程序时,我收到此消息错误:

类型错误:pyqtSignal 必须绑定(bind)到 QObject,而不是“实例”

如果有任何其他(简单)方法可以从另一个线程(和类)更新 UI,或者您知道如何修复此错误,请告诉我!

最佳答案

差不多就是这样:

class Signals(QObject):
    trigger = pyqtSignal(str)

要在MainServer中使用它们:

class MainServer(SocketServer.ThreadingMixIn, SocketServer.TCPServer):
   def __init__(self, parent=None):
       self.signals = Signals()
       self.signals.trigger.emit("triggered")

关于python - Qt : Updating UI (with signals) from another class and thread,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13711730/

相关文章:

java - 如何在java中重新启动线程?

c++ - Qt widgets 应用程序中主窗口第一次可见时如何显示对话框?

c++ - 为什么官方的 Qt 示例和教程不使用智能指针?

python - 什么是全局默认超时

python - 使用预训练模型 inception_v3,val_loss 增加,而 val_acc 保持在 60%

multithreading - 超线程对 AVX 有问题吗?

c++ - 在qt c++中替换编码字符串的 "="

python - 在 Python 中将 CSS 选择器转换为 XPath

python - Numpy savez/load 数千个数组,但不是一步完成

multithreading - Haskell:并行代码比顺序版本慢