Reputation: 3163
I did something similar to the answer here. The GUI is simple, you click a button which starts a thread that instead of emitting signals it sends events. The events cause a label to change text.
Here's the code:
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_())
The problem is that, only the first event get processed by MyReceiver
, then the widget freezes!.
Any clues?. Thanks
Upvotes: 0
Views: 859
Reputation: 7900
The behaviour of the event
method of QWidget is altered in your code: you should
let the base class decide on what to do with events, not returning False
if it is
not a custom event. Do it like this:
def event(self, event):
if event.type() == QEvent.User:
self.label.setText(event.message)
return True
return QWidget.event(self, event)
This fixes your problem.
Also, you may prefer to emit a Qt signal from the thread, and have it connected in your widget to some method to change the label - signals and slots are thread-safe in Qt 4 (contrary to Qt 3). It will achieve the same result.
Upvotes: 1