2009-12-20 5 views
3

Le programme suivant doit juste compter et int et affiche sa valeur dans une étiquette. Mais après un moment, l'interface graphique cesse de fonctionner, tandis que la boucle continue.PyQt 4 UI gèle

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_()) 

Une aide?

Répondre

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

Avez-vous pensé à une sortie de cette boucle sans fin? Par exemple. .
GUI peut cesser de fonctionner car il n'a pas assez de temps pour effectuer repaint. Vous pouvez ajouter quelques time.sleep dans la boucle pour attendre que l'interface graphique soit repeinte.

Mise à jour: Vous devez utiliser QTimer, pas une simple boucle while, pour le comportement que vous implémentez.

+0

J'ai essayé de simplifier mon problème autant que possible, alors oui, un bouton d'arrêt est prévu. Mettre une commande de veille temporelle provoque même une panne de l'interface graphique plus rapidement. – tillsten

+0

Vous feriez mieux d'utiliser QTimer (http://doc.trolltech.com/3.3/qtimer.html) au lieu de while et de démarrer/arrêter comme vous le souhaitez. – Li0liQ

+0

En outre, votre bouton d'arrêt ne fonctionnera pas tant que la boucle while est en cours d'exécution si vous utilisez un thread unique. Donc, comme je l'ai mentionné, essayez d'utiliser QTimer. – Li0liQ

2

Vous devez laisser la boucle d'événement principal fonctionner, ce que vous ne faites pas.

+0

Désolé, je suis assez nouveau à pyqt, mais la peinture dosent invoquer la boucle principale? – tillsten

6

Vous ne laissez pas la boucle d'événements de Qt s'exécuter, donc l'interface graphique ne répond pas. En outre, repaint() n'est pas nécessaire, le QLabel.setText() va repeindre l'étiquette. Tout ce qu'il fait est de mettre en file d'attente un événement de peinture supplémentaire, mais cela ne sera jamais traité.

Ce que vous devez faire est de remplacer self.repaint() par QtGui.QApplication.processEvents(). Cela donnera à l'application une chance de traiter tous les événements en attente (y compris la repeinte, ainsi que l'interaction ui) pendant que vous êtes dans la boucle.

+0

Merci, cela devrait fonctionner aussi. – tillsten