PySide使用不起作用的事件发出替代信号

时间:2013-10-02 19:01:41

标签: python pyqt pyside

我做了类似于答案here的事情。 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处理,然后小部件冻结! 任何线索?感谢

1 个答案:

答案 0 :(得分: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相反)。它将实现相同的结果。