floflo29 floflo29 - 3 months ago 67
Python Question

Wait for a clicked() event in while loop in Qt

How can I wait, at each iteration, within a for loop, that the user press a given QPushButton?

for i in range(10):


while (the button has not been pressed):
#do nothing
#do something


The main problem is that I cannot catch the clicked() event in the while loop.

EDIT:

Finally I ended up with:

for i in range(10):
self.hasBeenProcessed = False

# only one function can modify this boolean
# and this function is connected to my button
while (self.hasBeenProcessed is not True):
QtCore.QCoreApplication.processEvents()

Answer

So, I share the slight skepticism as to whether you should want to be doing what you described. Also, I share that it would be better if you show a bit more code to describe the context.

Having said this, the code below is a stab at what you seem to be describing. Note that this is by no means meant to be production-ready code, but more a crude example to illustrate the principle.

What happens is that I call one function on the press of Button1 and I keep the event loop spinning inside the while loop by calling QCoreApplication.processEvents() which means that the GUI will still accept e.g. mouse events. Now, this is something that you should not typically do. There are, however, certain situations where this can be needed, e.g. if you have a non-modal QProgressDialog and you want to keep the GUI updating while the dialog counter increases (see e.g. http://doc.qt.io/qt-4.8/qprogressdialog.html#value-prop)

Then the second part is only to modify the global variable in the second function when you press button 2 and the while loop will exit.

Let me know if this helps

import sys
from PyQt4.QtCore import *
from PyQt4.QtGui import *

btn2pushed = False

def window():
   app = QApplication(sys.argv)
   win = QDialog()
   b1 = QPushButton(win)
   b1.setText("Button1")
   b1.move(50,20)
   b1.clicked.connect(b1_clicked)

   b2 = QPushButton(win)
   b2.setText("Button2")
   b2.move(50,50)
   QObject.connect(b2,SIGNAL("clicked()"),b2_clicked)

   win.setGeometry(100,100,200,100)
   win.setWindowTitle("PyQt")
   win.show()
   sys.exit(app.exec_())

def b1_clicked():
   print "Button 1 clicked"
   i = 0
   while ( btn2pushed != True ):
       # not doing anything                                                                                                                                                                                                   
       if ( i % 100000 == 0 ):
           print "Waiting for user to push button 2"
       QCoreApplication.processEvents()
       i += 1;

   print "Button 2 has been pushed"


def b2_clicked():
    global btn2pushed
    btn2pushed = True

if __name__ == '__main__':
   window()