0

I wrote a small application using QT and Python. I Press a button, a wait for serial input for 5 seconds. I have few labels which I want to update e.g., when I press button it should change to 'starting reading' and when I return it should change to 'reading done'. I use a simple thread which calls processEvents but it does not gets updated and when read function finishes I see the last label change.

class MyWindow(QtGui.QMainWindow):

  def __init__(self):
    print 'myWindow'
    super(MyWindow, self).__init__()
    uic.loadUi('test1.ui', self)
    QtCore.QObject.connect(self.pushButton, QtCore.SIGNAL ('clicked()'), self.buttonStartClicked)
    self.show()



  def buttonStartClicked(self):
    thread = threading.Thread(target = self.update_gui, args = ())
    thread.daemon = True
    thread.start()
    self.label.setText('Starting Test')
    response = sRS232_Con.read()
    #QtGui.QApplication.processEvents()
    self.label.setText('Ending Test')


  def update_gui(self):
    while True :
      QtGui.QApplication.processEvents()
      print 'update'
      time.sleep(1)


def main():
  app = QtGui.QApplication(sys.argv)
  window = MyWindow()
  sys.exit(app.exec_())

if __name__ == '__main__':
   main()
user1566277
  • 435
  • 2
  • 5
  • 11
  • why is #QtGui.QApplication.processEvents() in comment? – Martijn van Wezel Nov 04 '15 at 13:38
  • Because I want to call processEvents at one central point, like in a separate thread which could update multiple widgets. – user1566277 Nov 04 '15 at 13:45
  • First of all: forget about multiple threads. They are unnecessary for your application. Second of all, you should never have to call `processEvents` - that you do indicates that your design is broken. `app.exec_` does all the event processing. You then need to use `QStateMachine` to define the states your application is in, and how it should react to state changes. For inspiration in C++, see e.g. [this answer](http://stackoverflow.com/a/32595398/1329652). – Kuba hasn't forgotten Monica Nov 04 '15 at 19:30

1 Answers1

0

In Qt any QObject that is managed by some event loop should not be touch by other thread (at least without any protection).

If for some reason you cannot use QSerialPort library that provides asynchronous API for serial port it is possible to use QThread for separate thread managed by Qt signals and slots.

Events for QtGui are dispatched by the main thread (insided of the loop app.exec_()). Another QThread can work with serial port and it can emit signals on 'Starting Test' and on 'Ending Test'. Those signals can be connected to MyWindow slots that are able to update UI in the main thread.

Orest Hera
  • 6,706
  • 2
  • 21
  • 35