1

I have an application in which I tried using a while loop but the application just hangs, and now I think I need to use QEventLoop to make the application work here is some of the relevant code

def ex_initialator(self):
    """ sets up things for the problem runner """

    print "ayadara"
    print "self.start_button_status this is...::" ,self.start_button_status

    #:Pop up dialogs       
    no_options_selected = QtGui.QMessageBox()

    select_range = QtGui.QMessageBox()

    select_op_type = QtGui.QMessageBox()



    #:Shows message if no options selected       
    if len(self.op_types) < 1 and len(self.num_range) < 1 and self.start_button_status == 0:
        print "Please pick from the options provided"
        no_options_selected.exec_()

    #:Shows message if range is not selected
    if len(self.op_types) >= 1 and len(self.num_range) < 1 and self.start_button_status == 0 :
        print "Please pick at least one of the ranges"
        select_range.exec_()

    #:Shows message if op_type/s not selected
    if len(self.op_types) < 1 and len(self.num_range) >= 1 and self.start_button_status == 0:
        print "Please pick at least one of the operation types"        
        select_op_type.exec_()

    #:Correct inputs initiates problem maker
    if len(self.op_types) >= 1 and len(self.num_range) >= 1 and (self.start_button_status == 0 or self.start_button_status == 1):

       self.start_button_status = 1
       self.prob_signal.runner_sig.connect(self.problem_runner)
       self.prob_signal.runner_sig.emit()


    def problem_runner(self):
    """ Expression Makers """
    while self.start_button_status == 1:

        #:picks range types
        range_type = random.choice(self.num_range)

        D = decimal.Decimal

        self.answer_lineEdit.returnPressed.connect(self.ex_evaluator)
        self.answer_lineEdit.clear()

what I want is to be able to start, pause, and stop buttons, I'm a beginner so I might have gone wrong in using QLineEdit in which case I would appreciate some suggestions as to a better implementation

enter image description here

eyllanesc
  • 235,170
  • 19
  • 170
  • 241
H.J_Rios
  • 125
  • 4
  • 12

1 Answers1

1

If you are performing long operation, you need either move it to separate thread or call QApplication::processEvents() periodically. It allows GUI to remain responsible. Here is a simple example:

from PySide import QtGui, QtCore
import time

class MyWidget(QtGui.QWidget):
  def __init__(self):
    QtGui.QWidget.__init__(self)
    layout = QtGui.QVBoxLayout(self)
    self.label = QtGui.QLabel()
    self.button_start = QtGui.QPushButton("Start")
    self.button_stop = QtGui.QPushButton("Stop")
    self.button_stop.setEnabled(False)
    self.button_pause = QtGui.QPushButton("Pause")
    self.button_pause.setEnabled(False)
    layout.addWidget(self.label)
    layout.addWidget(self.button_start)
    layout.addWidget(self.button_stop)
    layout.addWidget(self.button_pause)
    self.button_start.clicked.connect(self.processing)
    self.button_pause.clicked.connect(self.pause)
    self.button_stop.clicked.connect(self.stop)

  def processing(self):
    self.button_start.setEnabled(False)
    self.button_stop.setEnabled(True)
    self.button_pause.setEnabled(True)
    self.stop_requested = False
    self.paused = False
    i = 0
    while not self.stop_requested:
      QtGui.QApplication.processEvents()
      if self.paused:
        time.sleep(0.1)
      else:
        i += 1
        self.label.setText(unicode(i))
    self.button_start.setEnabled(True)
    self.button_stop.setEnabled(False)
    self.button_pause.setEnabled(False)

  def pause(self):
    self.paused = not self.paused

  def stop(self):
    self.stop_requested = True

if __name__ == '__main__':
    import sys
    app = QtGui.QApplication(sys.argv)
    widget = MyWidget()
    widget.show()
    sys.exit(app.exec_())  
Pavel Strakhov
  • 39,123
  • 5
  • 88
  • 127
  • I tried your example and it does what I need it to do, however when its running it takes > 90 of the CPU..could you tell me why or how to get around that ? – H.J_Rios Jun 17 '13 at 20:42
  • Fixed CPU usage when paused. – Pavel Strakhov Jun 18 '13 at 08:03
  • it seems to do fine when it is paused even the first part of your code, however it is when its displaying the numbers that it actually eats up all the CPU – H.J_Rios Jun 18 '13 at 09:55
  • Well, it performs calculations constantly. How do you expect it to do so without CPU usage? On the contrary, high CPU usage means it works fine. – Pavel Strakhov Jun 18 '13 at 10:00
  • instead of setting the Label I made it print out to the console and the processing went down to a max of about 27% it seems the calls to show it is expensive – H.J_Rios Jun 20 '13 at 04:36
  • Yes. In real programs GUI updates should be done several times in a second, not constantly. – Pavel Strakhov Jun 20 '13 at 08:07