MadeOfAir
MadeOfAir

Reputation: 3163

PySide signals alternative using events not working

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

Answers (1)

mguijarr
mguijarr

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

Related Questions