Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. PyQt5 threading communication error
Forum Updated to NodeBB v4.3 + New Features

PyQt5 threading communication error

Scheduled Pinned Locked Moved Unsolved General and Desktop
9 Posts 4 Posters 2.4k Views 1 Watching
  • 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.
  • V Offline
    V Offline
    VincentLiu
    wrote on last edited by
    #1

    Hi everyone,
    I would like to ask for your valuable opinion of my stub program, I tried to make it simple and displayed below:

    class Processing(QObject):
    
        def __init__(self):
            QObject.__init__(self)
    
        def match_tracker(self):
    
            self.match = Matching(QtCore.QVariant(self.some_list), 3)
            self.thread = QThread()
            self.match.moveToThread(self.thread)
            self.thread.started.connect(self.match.match)
            self.match.result_signal.connect(self.receive_match_result)
            
            self.thread.start()
    
        @pygtSlot(str,int)
        def receive_match_result(self, match_id, track_id):
    
            print('{},{}'.format(match_id, track_id))
            
    class Matching(QObject):
    
        result_signal = pyqtSignal(str,int)
        
        def __init__(self, some_list, id):
              
            QObject.__init__(self)
            self.some_list = some_list
            self.id = id
    
         @pygtSlot()
         def match(self):
       
              print('Matching.match()')
    
              # Do processing.....
    
              self.result_signal.emit(str_result, int_result)
    

    These are two classes involved in my program. I am able to emit the signal started from Processing class and received in Matching.match(), i.e., I managed to print 'Matching.match()'. However, after the processing operation in Matching.match(), the result_signal should be emitted and received by Processing.receive_match_result(). I cannot print the '{},{}'.format(match_id, track_id) at the first line of the function which means either the signal failed to emit or the slot failed to receive.

    How do I check whether a signal is emitted? And do I make any mistake so that I failed to receive the result_signal? Thanks

    JonBJ 1 Reply Last reply
    0
    • SGaistS Offline
      SGaistS Offline
      SGaist
      Lifetime Qt Champion
      wrote on last edited by
      #2

      Hi,

      I would rather use the super keyword to handle heritage. Otherwise the code itself looks fine except that you will create a new Matching object each time you call match_tracker which might be a be overkill. Why not git your Match object two setters, one for each parameter, and then start the thread ? That would avoid re-creating self.match each time.

      As for the signal/slot, as a quick debugging technique, I'd add some more print around the signal emit.

      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
      0
      • V VincentLiu

        Hi everyone,
        I would like to ask for your valuable opinion of my stub program, I tried to make it simple and displayed below:

        class Processing(QObject):
        
            def __init__(self):
                QObject.__init__(self)
        
            def match_tracker(self):
        
                self.match = Matching(QtCore.QVariant(self.some_list), 3)
                self.thread = QThread()
                self.match.moveToThread(self.thread)
                self.thread.started.connect(self.match.match)
                self.match.result_signal.connect(self.receive_match_result)
                
                self.thread.start()
        
            @pygtSlot(str,int)
            def receive_match_result(self, match_id, track_id):
        
                print('{},{}'.format(match_id, track_id))
                
        class Matching(QObject):
        
            result_signal = pyqtSignal(str,int)
            
            def __init__(self, some_list, id):
                  
                QObject.__init__(self)
                self.some_list = some_list
                self.id = id
        
             @pygtSlot()
             def match(self):
           
                  print('Matching.match()')
        
                  # Do processing.....
        
                  self.result_signal.emit(str_result, int_result)
        

        These are two classes involved in my program. I am able to emit the signal started from Processing class and received in Matching.match(), i.e., I managed to print 'Matching.match()'. However, after the processing operation in Matching.match(), the result_signal should be emitted and received by Processing.receive_match_result(). I cannot print the '{},{}'.format(match_id, track_id) at the first line of the function which means either the signal failed to emit or the slot failed to receive.

        How do I check whether a signal is emitted? And do I make any mistake so that I failed to receive the result_signal? Thanks

        JonBJ Offline
        JonBJ Offline
        JonB
        wrote on last edited by JonB
        #3

        @VincentLiu said in PyQt5 threading communication error:

        And do I make any mistake so that I failed to receive the result_signal?

        From your code as posted (unless there is other code), the signal is emitted, but the slot is no longer around to receive it!

        self.thread.start()
        

        starts the thread. But that's at the end of match_tracker(). What happens to your Processing object after that is called and the method exits? You need to keep the Processing object in existence till the signal is emitted, e.g. some kind of "wait for thread to terminate" or whatever code is suitable for your purposes. Otherwise if you let it go out of scope it gets destroyed, taking the slot/object (receive_match_result()/self.match) with it, so the slot never gets hit.

        Minor:
        @pygtSlot() both occurrences are misspelt: should be @pyqtSlot(). And (assuming you're PyQt5) somewhere you can Google for says its usage is "deprecated", and you simply shouldn't bother using it any more (I assume it does nothing?).

        @SGaist

        I would rather use the super keyword to handle heritage.

        Totally agree! I always write super().__init__(self) for inheritors. So how come if this is good does C++ not have equivalent (my beloved C# has base for this)? :)

        1 Reply Last reply
        0
        • SGaistS Offline
          SGaistS Offline
          SGaist
          Lifetime Qt Champion
          wrote on last edited by
          #4

          @JonB See here for a nice explanation about super.

          From the reference guide the pyqtSlot decorator seems to be rather nice to use. I also find that it makes the intent of the code clearer.

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

          JonBJ 1 Reply Last reply
          1
          • SGaistS SGaist

            @JonB See here for a nice explanation about super.

            From the reference guide the pyqtSlot decorator seems to be rather nice to use. I also find that it makes the intent of the code clearer.

            JonBJ Offline
            JonBJ Offline
            JonB
            wrote on last edited by JonB
            #5

            @SGaist
            For super/base (lack of) usage in C++, to me it just makes code harder to read & refactor having to explicitly name the base class in each derived function. Also, it may be just me, but when I see QObject::func() being used in each derived function to call the base one, my first thought is that it is a call to a static function, which confuses me.

            For @pyqtSlot, I admit I cannot find where I thought it was "deprecated". Perhaps I read https://stackoverflow.com/a/40330912/489865:

            However, these use-cases are relatively rare, and in most PyQt applications it is not necessary to use pyqtSlot at all. Signals can be connected to any python callable object, whether it is decorated as a slot or not.

            The code I am maintaining has hundreds of slot functions and not one @pyqtSlot, so perhaps I am used not to encountering it. My apologies for suggesting it was deprecated.

            jsulmJ 1 Reply Last reply
            0
            • JonBJ JonB

              @SGaist
              For super/base (lack of) usage in C++, to me it just makes code harder to read & refactor having to explicitly name the base class in each derived function. Also, it may be just me, but when I see QObject::func() being used in each derived function to call the base one, my first thought is that it is a call to a static function, which confuses me.

              For @pyqtSlot, I admit I cannot find where I thought it was "deprecated". Perhaps I read https://stackoverflow.com/a/40330912/489865:

              However, these use-cases are relatively rare, and in most PyQt applications it is not necessary to use pyqtSlot at all. Signals can be connected to any python callable object, whether it is decorated as a slot or not.

              The code I am maintaining has hundreds of slot functions and not one @pyqtSlot, so perhaps I am used not to encountering it. My apologies for suggesting it was deprecated.

              jsulmJ Offline
              jsulmJ Offline
              jsulm
              Lifetime Qt Champion
              wrote on last edited by
              #6

              @JonB C++ supports inheriting from more than one class, using super how would the compiler decide which one you mean?

              https://forum.qt.io/topic/113070/qt-code-of-conduct

              JonBJ 1 Reply Last reply
              1
              • jsulmJ jsulm

                @JonB C++ supports inheriting from more than one class, using super how would the compiler decide which one you mean?

                JonBJ Offline
                JonBJ Offline
                JonB
                wrote on last edited by JonB
                #7

                @jsulm
                OOOhhh! My beloved C# allows only single inheritance, so I didn't think of that! I believe Python allows multiple, I haven't looked into what super() does there, perhaps only allow if single inherited?

                Also, for C++, from the link @SGaist quoted:

                The proposal mentioned the multiple inheritance issue, and would have flagged ambiguous uses.
                ...
                the proposal was implementable, technically sound, and free of major flaws, and handled multiple inheritance.

                So there's the answer!

                jsulmJ 1 Reply Last reply
                0
                • JonBJ JonB

                  @jsulm
                  OOOhhh! My beloved C# allows only single inheritance, so I didn't think of that! I believe Python allows multiple, I haven't looked into what super() does there, perhaps only allow if single inherited?

                  Also, for C++, from the link @SGaist quoted:

                  The proposal mentioned the multiple inheritance issue, and would have flagged ambiguous uses.
                  ...
                  the proposal was implementable, technically sound, and free of major flaws, and handled multiple inheritance.

                  So there's the answer!

                  jsulmJ Offline
                  jsulmJ Offline
                  jsulm
                  Lifetime Qt Champion
                  wrote on last edited by
                  #8

                  @JonB https://www.python-course.eu/python3_multiple_inheritance.php
                  "The question arises how the super functions makes its decision. How does it decide which class has to be used? As we have already mentioned, it uses the so-called method resolution order(MRO)."

                  https://forum.qt.io/topic/113070/qt-code-of-conduct

                  JonBJ 1 Reply Last reply
                  1
                  • jsulmJ jsulm

                    @JonB https://www.python-course.eu/python3_multiple_inheritance.php
                    "The question arises how the super functions makes its decision. How does it decide which class has to be used? As we have already mentioned, it uses the so-called method resolution order(MRO)."

                    JonBJ Offline
                    JonBJ Offline
                    JonB
                    wrote on last edited by
                    #9

                    @jsulm
                    Yep for Python, thanks. See also my reply above for C++.

                    1 Reply Last reply
                    0

                    • Login

                    • Login or register to search.
                    • First post
                      Last post
                    0
                    • Categories
                    • Recent
                    • Tags
                    • Popular
                    • Users
                    • Groups
                    • Search
                    • Get Qt Extensions
                    • Unsolved