2013-10-02 39 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