2013-10-02 37 views
0

我做了类似的回答here。 图形用户界面很简单,你点击一个按钮启动一个线程,而不是发送信号它发送事件。事件导致标签改变文本。PySide信号替代使用事件不起作用

下面的代码:

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

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相反)。它会达到相同的结果。

+0

谢谢,似乎很明显。但我实际上已经尝试用'QApplication.notify()'发送事件,它应该自动传播事件,并且它不起作用。 – MadeOfAir

+0

仔细阅读文档可以发现传播只发生在鼠标和键盘事件上,所以这就是为什么'event()'不会传播的原因。 – MadeOfAir