Qt Forum

    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    • Unsolved

    Update: Forum Guidelines & Code of Conduct

    [SOLVED] PyQt threading error while passing a signal to a QMessageBox

    Language Bindings
    3
    8
    11544
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • E
      ete83 last edited by

      I tried to receive a string from a thread to my main GUI using SIGNALs. Everything works fine until I want to use the string in a QMessageBox. Printing out is no problem but starting a QMessageBox gives me several errors (some are about QPixmap which I even do not use in the GUI.

      Here is a short working example of my code:

      @import sys
      import urllib2
      import time
      from PyQt4 import QtCore, QtGui

      class DownloadThread(QtCore.QThread):
      def init(self):
      QtCore.QThread.init(self)

      def run(self):
          time.sleep(3)
          self.emit(QtCore.SIGNAL("threadDone(QString)"), 'test')
      

      class MainWindow(QtGui.QWidget):
      def init(self):
      super(MainWindow, self).init()
      self.list_widget = QtGui.QListWidget()
      self.button = QtGui.QPushButton("Start")
      self.button.clicked.connect(self.start_download)
      layout = QtGui.QVBoxLayout()
      layout.addWidget(self.button)
      layout.addWidget(self.list_widget)
      self.setLayout(layout)

          self.downloader = DownloadThread()
          self.connect(self.downloader, QtCore.SIGNAL("threadDone(QString)"), self.threadDone, QtCore.Qt.DirectConnection)
      
      def start_download(self):
          self.downloader.start()
      
      def threadDone(self, info_message):
          print info_message
          QtGui.QMessageBox.information(self,
                      u"Information",
                      info_message
                      )
          #self.show_info_message(info_message)
      

      if name == "main":
      app = QtGui.QApplication(sys.argv)
      window = MainWindow()
      window.resize(640, 480)
      window.show()
      sys.exit(app.exec_())@

      I'm getting this erros:

      QObject::setParent: Cannot set parent, new parent is in a different thread
      QPixmap: It is not safe to use pixmaps outside the GUI thread

      This error only while moving the mouse and QMessageBox is still open:

      QObject::startTimer: timers cannot be started from another thread
      QApplication: Object event filter cannot be in a different thread.

      Can anyone tell me what I'm doing wrong?
      This is the first time I'm using threads.

      Thank you!
      Stefanie

      1 Reply Last reply Reply Quote 0
      • SGaist
        SGaist Lifetime Qt Champion last edited by

        Hi and welcome to devnet,

        You are imposing a direct connection which means the slot will be called from your thread context and doing GUI related stuff in another thread than the GUI thread is wrong.

        Either use a QueuedConnection or let Qt decide of the connection type

        Hope it helps

        Interested in AI ? www.idiap.ch
        Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

        1 Reply Last reply Reply Quote 0
        • E
          ete83 last edited by

          Hi!

          Thank you very much for the answer and nice welcome!
          It worked like charm and solved the problem!

          Cheers,
          Stefanie

          1 Reply Last reply Reply Quote 0
          • SGaist
            SGaist Lifetime Qt Champion last edited by

            You're welcome !

            Since it's working now, can you update the thread's title to solved ? So other forum users may know a solution has been found :)

            Interested in AI ? www.idiap.ch
            Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

            1 Reply Last reply Reply Quote 0
            • jazzycamel
              jazzycamel last edited by

              Its also worth noting that the way in which PyQt handles signals has changed so, rather than using strings to specify signals and there arguments, you can do it in a a clearer, more pythonic way as follows:

              • To Connect:
                <source_object>.<signal_name>.connect(<target_object>.<slot>)
              • To Emit:
                <source_object>.<signal_name>.emit(<arguments>)

              So, your example from above would read:

              @
              import sys
              import time
              from PyQt4 import QtCore, QtGui

              class DownloadThread(QtCore.QThread):
              def init(self):
              QtCore.QThread.init(self)

              def run(self):
                  time.sleep(3)
                  self.threadDone.emit('test')
              

              class MainWindow(QtGui.QWidget):
              def init(self):
              super(MainWindow, self).init()
              self.list_widget = QtGui.QListWidget()
              self.button = QtGui.QPushButton("Start")
              self.button.clicked.connect(self.start_download)
              layout = QtGui.QVBoxLayout()
              layout.addWidget(self.button)
              layout.addWidget(self.list_widget)
              self.setLayout(layout)

                  self.downloader = DownloadThread()
                  self.downloader.threadDone.connect(self.threadDone)
              
              def start_download(self):
                  self.downloader.start()
              
              def threadDone(self, info_message):
                  print info_message
                  QtGui.QMessageBox.information(self,
                              u"Information",
                              info_message
                              )
              

              if name == "main":
              app = QtGui.QApplication(sys.argv)
              window = MainWindow()
              window.resize(640, 480)
              window.show()
              sys.exit(app.exec_())
              @

              See "here":http://pyqt.sourceforge.net/Docs/PyQt4/new_style_signals_slots.html for more info.

              Also, to further SGaists comment, its very rarely necessary to specify the connection type when connecting signals and slots, let PyQt/Qt select the most appropriate.

              Hope this helps ;o)

              For the avoidance of doubt:

              1. All my code samples (C++ or Python) are tested before posting
              2. As of 23/03/20, my Python code is formatted to PEP-8 standards using black from the PSF (https://github.com/psf/black)
              1 Reply Last reply Reply Quote 0
              • E
                ete83 last edited by

                @SGaist
                Done!

                @
                Thank you very much for your suggestion, I'll change it!

                This forum is great! I want to switch from wxPython to PyQt and it is great to have such a good support! Just started to implement my software and I'm very surprised that everything works out of the box, especially switching all the time between Windows and Unix OS.

                Thanks again!
                Stefanie

                1 Reply Last reply Reply Quote 0
                • SGaist
                  SGaist Lifetime Qt Champion last edited by

                  That's what Qt does :) (no I don't forget the bugs but nothing's perfect)

                  Interested in AI ? www.idiap.ch
                  Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                  1 Reply Last reply Reply Quote 0
                  • E
                    ete83 last edited by

                    At least thousands times better then what I did up to now.
                    It's took me several month to decide which framework to use for the change but I think I took the right one. Not sorry up to now.

                    Sorry for off-topic. I'm just astonished how easy live can be.

                    Greetings from Germany!
                    Stefanie

                    1 Reply Last reply Reply Quote 0
                    • First post
                      Last post