0

我做了类似于这里的答案的事情。GUI 很简单,您单击一个按钮来启动一个线程,该线程不是发出信号而是发送事件。这些事件导致标签更改文本。

这是代码:

from PySide.QtGui import *
from PySide.QtCore import *
import sys, time

class MyEvent(QEvent):
    def __init__(self, message):
        super().__init__(QEvent.User)
        self.message = message

class MyThread(QThread):
    def __init__(self, widget):
        super().__init__()
        self._widget = widget

    def run(self):
        for i in range(10):
            app.sendEvent(self._widget, MyEvent("Hello, %s!" % i))
            time.sleep(.1)

class MyReceiver(QWidget):
    def __init__(self, parent=None):
        super().__init__()
        layout = QHBoxLayout()
        self.label = QLabel('Test!')
        start_button = QPushButton('Start thread')
        start_button.clicked.connect(self.startThread)
        layout.addWidget(self.label)
        layout.addWidget(start_button)
        self.setLayout(layout)

    def event(self, event):
        if event.type() == QEvent.User:
            self.label.setText(event.message)
            return True
        return False

    def startThread(self):
        self.thread = MyThread(self)
        self.thread.start()

app = QApplication(sys.argv)
main = MyReceiver()
main.show()
sys.exit(app.exec_())

问题是,只有第一个事件被 处理MyReceiver,然后小部件冻结!。任何线索?谢谢

4

1 回答 1

1

QWidget 方法的行为event在您的代码中被更改:您应该让基类决定如何处理事件,False如果它不是自定义事件,则不返回。像这样做:

def event(self, event):
    if event.type() == QEvent.User:
        self.label.setText(event.message)
        return True
    return QWidget.event(self, event)

这解决了你的问题。

此外,您可能更喜欢从线程发出 Qt 信号,并在您的小部件中将其连接到某种方法来更改标签 - 信号和插槽在 Qt 4 中是线程安全的(与 Qt 3 相反)。它将达到相同的结果。

于 2013-10-03T00:33:28.063 回答