views:

382

answers:

3
+2  Q: 

PyQt 4 UI freezes

The following programm should just count up and int and displays its value in a label. But after a while the GUI stops working, while the loop continous.

from PyQt4 import QtGui,QtCore
import sys

class main_window(QtGui.QWidget):
    def __init__(self,parent=None):
        #Layout       
        QtGui.QWidget.__init__(self,parent)
        self.bt=QtGui.QPushButton('crash')
        self.lbl=QtGui.QLabel('count')
        ver=QtGui.QHBoxLayout(self)
        ver.addWidget(self.bt)
        ver.addWidget(self.lbl)
        self.cnt=0
        self.running=False
        self.connect(self.bt,QtCore.SIGNAL("clicked()"),self.count)

    def count(self):
        self.running=True
        while self.running:
            self.cnt+=1
            print self.cnt
            self.lbl.setText(str(self.cnt))
            self.repaint()

if __name__ == '__main__':

    app = QtGui.QApplication(sys.argv)
    mw=main_window()
    mw.show()
    sys.exit(app.exec_())

Any help?

+4  A: 
def count(self):
    self.running=True
    while self.running:
        self.cnt+=1
        print self.cnt
        self.lbl.setText(str(self.cnt))
        self.repaint()

Have you thought about any exit from this endless loop? E.g. self.running=False.
GUI may stop working because it doesn't have enough time to perform repaint. You may want to add some time.sleep in the loop to wait for the GUI to repaint.

Upd.: You should use QTimer, not a simple while loop, for the behavior you're implementing.

Li0liQ
I tried to simplify my problem as much as possible, so yes, a stop button is planed.Putting in a time sleep command even crashs the gui faster.
tillsten
You'd better be using QTimer(http://doc.trolltech.com/3.3/qtimer.html) instead of while loop and start/stop it as desired.
Li0liQ
Besides, your stop button won't work so long as the while loop is being executed if you are using single thread. So, as I've mentioned, try using QTimer.
Li0liQ
Ok, got it working with using a QTimer with 0 ms instead. Thaks.
tillsten
+2  A: 

You have to let the main event loop run, something you're not doing.

Virgil Dupras
Sorry, i am quite new to pyqt, but dosent paint invoke the main loop?
tillsten
+2  A: 

You're not letting Qt's event loop run, so the GUI is not responding. Also, repaint() is not needed, the QLabel.setText() will repaint the label. All it does is queue up an extra paint event, but this never gets processed.

What you need to do is replace self.repaint() with QtGui.QApplication.processEvents(). This will give the app a chance to process any pending events (including that repaint, as well as ui interaction) while you're in the loop.

dF
Thanks, this should be working too.
tillsten