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. Example of calling a function to parent?
QtWS25 Last Chance

Example of calling a function to parent?

Scheduled Pinned Locked Moved Unsolved General and Desktop
38 Posts 5 Posters 4.1k Views
  • 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.
  • P Offline
    P Offline
    Panoss
    wrote on last edited by Panoss
    #1

    I 'm searching for a simple example of calling (from a form) a function to another form.

    Let me explain: I have FormA with a button on it. Clicking this button I open FormB which also has a button.
    When I click on FormB's button I want to call a function in FormA.

    From what I read it will be done with Signal, Slots and emit() (but to tell the truth I don't understand much).
    Is there some example?

    1 Reply Last reply
    0
    • P Offline
      P Offline
      Panoss
      wrote on last edited by
      #2

      Ok, I found a python example that works.

      #!/usr/bin/python3
      # Threading example with QThread and moveToThread (PyQt5)
      import sys
      import time
      from PyQt5 import QtWidgets, QtCore
      
      
      class WorkerThread(QtCore.QObject):
          signalExample = QtCore.pyqtSignal(str, int)
      
          def __init__(self):
              super().__init__()
      
          @QtCore.pyqtSlot()
          def run(self):
              while True:
                  # Long running task ...
                  self.signalExample.emit("leet", 1337)
                  time.sleep(5)
      
      
      class Main(QtWidgets.QMainWindow):
          def __init__(self):
              super().__init__()
              self.worker = WorkerThread()
              self.workerThread = QtCore.QThread()
              self.workerThread.started.connect(self.worker.run)  # Init worker run() at startup (optional)
              self.worker.signalExample.connect(self.signalExample)  # Connect your signals/slots
              self.worker.moveToThread(self.workerThread)  # Move the Worker object to the Thread object
              self.workerThread.start()
      
          def signalExample(self, text, number):
              print(text)
              print(number)
      
      
      if __name__ == '__main__':
          app = QtWidgets.QApplication(sys.argv)
          gui = Main()
          sys.exit(app.exec_())
      

      I want to modify it (in python code for now) so that the WorkerThread class' code will 'move' to mainWindow (and WorkerThread class to be completely removed).
      How can I do this?

      JonBJ 1 Reply Last reply
      0
      • P Panoss

        Ok, I found a python example that works.

        #!/usr/bin/python3
        # Threading example with QThread and moveToThread (PyQt5)
        import sys
        import time
        from PyQt5 import QtWidgets, QtCore
        
        
        class WorkerThread(QtCore.QObject):
            signalExample = QtCore.pyqtSignal(str, int)
        
            def __init__(self):
                super().__init__()
        
            @QtCore.pyqtSlot()
            def run(self):
                while True:
                    # Long running task ...
                    self.signalExample.emit("leet", 1337)
                    time.sleep(5)
        
        
        class Main(QtWidgets.QMainWindow):
            def __init__(self):
                super().__init__()
                self.worker = WorkerThread()
                self.workerThread = QtCore.QThread()
                self.workerThread.started.connect(self.worker.run)  # Init worker run() at startup (optional)
                self.worker.signalExample.connect(self.signalExample)  # Connect your signals/slots
                self.worker.moveToThread(self.workerThread)  # Move the Worker object to the Thread object
                self.workerThread.start()
        
            def signalExample(self, text, number):
                print(text)
                print(number)
        
        
        if __name__ == '__main__':
            app = QtWidgets.QApplication(sys.argv)
            gui = Main()
            sys.exit(app.exec_())
        

        I want to modify it (in python code for now) so that the WorkerThread class' code will 'move' to mainWindow (and WorkerThread class to be completely removed).
        How can I do this?

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

        @Panoss
        You have picked an example with threads. Why? That is the last thing you should be doing as a newcomer. In any case you cannot perform any UI actions in anything but the main thread in Qt, so what you describe will not work anyway.

        Have you read https://doc.qt.io/qt-5/signalsandslots.html ? That shows the sort of thing you were asking about, and does not mention threads.

        P 2 Replies Last reply
        0
        • JonBJ JonB

          @Panoss
          You have picked an example with threads. Why? That is the last thing you should be doing as a newcomer. In any case you cannot perform any UI actions in anything but the main thread in Qt, so what you describe will not work anyway.

          Have you read https://doc.qt.io/qt-5/signalsandslots.html ? That shows the sort of thing you were asking about, and does not mention threads.

          P Offline
          P Offline
          Panoss
          wrote on last edited by Panoss
          #4

          @JonB said in Example of calling a function to parent?:

          @Panoss
          You have picked an example with threads. Why? That is the last thing you should be doing as a newcomer.

          Yes I know, but this was the only one I found that works.

          1 Reply Last reply
          0
          • JonBJ JonB

            @Panoss
            You have picked an example with threads. Why? That is the last thing you should be doing as a newcomer. In any case you cannot perform any UI actions in anything but the main thread in Qt, so what you describe will not work anyway.

            Have you read https://doc.qt.io/qt-5/signalsandslots.html ? That shows the sort of thing you were asking about, and does not mention threads.

            P Offline
            P Offline
            Panoss
            wrote on last edited by Panoss
            #5

            @JonB said in Example of calling a function to parent?:

            Have you read https://doc.qt.io/qt-5/signalsandslots.html ? That shows the sort of thing you were asking about, and does not mention threads.

            This was the first I read, but as I mentioned, didn't understand much. This is why I'm looking for a working, simple, example.

            P 1 Reply Last reply
            0
            • P Panoss

              @JonB said in Example of calling a function to parent?:

              Have you read https://doc.qt.io/qt-5/signalsandslots.html ? That shows the sort of thing you were asking about, and does not mention threads.

              This was the first I read, but as I mentioned, didn't understand much. This is why I'm looking for a working, simple, example.

              P Offline
              P Offline
              Panoss
              wrote on last edited by
              #6

              Ok, I have an example in python which is exactly as I want it:

              from PySide6 import QtWidgets, QtCore
              
              
              class FormB(QtWidgets.QWidget):
                  form_done = QtCore.Signal(str)
              
                  def __init__(self, *args, steps=5, **kwargs):
                      super().__init__(*args, **kwargs)
              
                      self.entry = QtWidgets.QLineEdit("Enter value here")
                      self.button = QtWidgets.QPushButton("Done")
                      self.button.clicked.connect(self.button_pressed)
                      layout = QtWidgets.QVBoxLayout(self)
                      layout.addWidget(self.entry)
                      layout.addWidget(self.button)
              
                  def button_pressed(self):
                      #self.hide()
                      self.form_done.emit(self.entry.text())
              
              
              class FormA(QtWidgets.QWidget):
                  def __init__(self, *args, **kwargs):
                      super().__init__(*args, **kwargs)
              
                      self.form_b = None
                      self.button = QtWidgets.QPushButton("Draw B")
                      self.button.clicked.connect(self.draw_b)
                      self.label = QtWidgets.QLabel("I display the result in this label")
                      layout = QtWidgets.QVBoxLayout(self)
                      layout.addWidget(self.button)
                      layout.addWidget(self.label)
              
                  def draw_b(self):
                      if self.form_b is None:
                          self.form_b = FormB()
                          self.form_b.form_done.connect(self.b_done)
                      self.form_b.show()
              
                  def b_done(self, text):
                      self.label.setText(text)
              
              
              def main():
                  app = QtWidgets.QApplication([])
                  form_a = FormA()
                  form_a.show()
                  app.exec()
              
              
              main()
              

              So, how do I convert this python code:

              form_done = QtCore.Signal(str)
              

              to c++?

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

                Hi,

                The Qt documentation contains quite a lot of examples using signals and slots. You should go through the ones from the widgets module since it's the one you are implementing your application with.

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

                P 1 Reply Last reply
                0
                • SGaistS SGaist

                  Hi,

                  The Qt documentation contains quite a lot of examples using signals and slots. You should go through the ones from the widgets module since it's the one you are implementing your application with.

                  P Offline
                  P Offline
                  Panoss
                  wrote on last edited by
                  #8

                  @SGaist said in Example of calling a function to parent?:

                  The Qt documentation contains quite a lot of examples using signals and slots

                  Didn't find a full working example, only fragments of code I 'm trying to put together.
                  If you have found a full working example please post it!

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

                    Here you have the full list of the widgets examples.

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

                    P 1 Reply Last reply
                    1
                    • SGaistS SGaist

                      Here you have the full list of the widgets examples.

                      P Offline
                      P Offline
                      Panoss
                      wrote on last edited by
                      #10

                      @SGaist impressive selection of examples, I confess I had not discovered it!
                      But reading their description I see nothing that suits my needs (two classes (Forms) communicating with Signals and Slots)

                      1 Reply Last reply
                      0
                      • P Offline
                        P Offline
                        Panoss
                        wrote on last edited by Panoss
                        #11

                        Ok, let me show you what I tried so far:

                        In my FormB 's class declaration added:

                        public slots:
                            void setValue(int value);
                        signals:
                            void valueChanged(int newValue);
                        

                        Am I on the correct way?

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

                          These lines are to be found in the class declaration.

                          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
                          1
                          • P Offline
                            P Offline
                            Panoss
                            wrote on last edited by
                            #13

                            Yes you 're right, I corrected it!

                            1 Reply Last reply
                            0
                            • P Offline
                              P Offline
                              Panoss
                              wrote on last edited by Panoss
                              #14

                              And this is the function in my FormB: ()

                              void FormB::setValue(int value)
                              {       
                                      emit valueChanged(value);   
                              }
                              

                              Correct?

                              1 Reply Last reply
                              0
                              • P Offline
                                P Offline
                                Panoss
                                wrote on last edited by Panoss
                                #15

                                And now this:

                                QObject::connect(&a, &Counter::valueChanged,
                                                     &b, &Counter::setValue);
                                

                                I modified it to (this code is in the constructor of FormB):

                                connect(&parent, &parent::valueChanged,
                                                         this, &FormB::setValue);
                                

                                ???
                                It's wrong...The 'parent' I mean.
                                The sender is FormB...so..

                                M 1 Reply Last reply
                                0
                                • P Panoss

                                  And now this:

                                  QObject::connect(&a, &Counter::valueChanged,
                                                       &b, &Counter::setValue);
                                  

                                  I modified it to (this code is in the constructor of FormB):

                                  connect(&parent, &parent::valueChanged,
                                                           this, &FormB::setValue);
                                  

                                  ???
                                  It's wrong...The 'parent' I mean.
                                  The sender is FormB...so..

                                  M Offline
                                  M Offline
                                  mpergand
                                  wrote on last edited by mpergand
                                  #16

                                  @Panoss
                                  Everything is upside down :)

                                  let's recap, you want the main window (formA) to be inform when a value has changed in second window (formB)

                                  The main window register to receive a signal from the second window.

                                  In formA:

                                  connect(formB, &FormB::valueChanged, this , &FormA::valueChangedInFormB);
                                  
                                  1 Reply Last reply
                                  3
                                  • P Offline
                                    P Offline
                                    Panoss
                                    wrote on last edited by Panoss
                                    #17

                                    @mpergand it works!!!
                                    Thank you all!

                                    The actual name of FormA is 'ArticlesWindow' and of FormB 'positionsForm'.
                                    (FormB is the sender)
                                    I post the code in case someone needs it:

                                    articleswindow.h
                                    private slots:    
                                        void positionChanged();
                                    
                                    articleswindow.cpp
                                    void ArticlesWindow::positionChanged(){
                                        qDebug() << "ArticlesWindow::positionChanged";
                                    }
                                    void ArticlesWindow::openPositionsForm(){    
                                        class positionsForm *form = new class positionsForm(model, this);
                                        connect(form, &positionsForm::valueChanged, this , &ArticlesWindow::positionChanged);
                                    
                                    

                                    And:

                                    positionsform.h
                                      public slots:
                                        void setValue(int value);
                                    
                                      signals:
                                        void valueChanged(int newValue);
                                    
                                    positionsform.cpp
                                     void positionsForm::setValue(int value)
                                     {          
                                       emit valueChanged(value);    
                                     }
                                    
                                    
                                    P 1 Reply Last reply
                                    0
                                    • P Panoss

                                      @mpergand it works!!!
                                      Thank you all!

                                      The actual name of FormA is 'ArticlesWindow' and of FormB 'positionsForm'.
                                      (FormB is the sender)
                                      I post the code in case someone needs it:

                                      articleswindow.h
                                      private slots:    
                                          void positionChanged();
                                      
                                      articleswindow.cpp
                                      void ArticlesWindow::positionChanged(){
                                          qDebug() << "ArticlesWindow::positionChanged";
                                      }
                                      void ArticlesWindow::openPositionsForm(){    
                                          class positionsForm *form = new class positionsForm(model, this);
                                          connect(form, &positionsForm::valueChanged, this , &ArticlesWindow::positionChanged);
                                      
                                      

                                      And:

                                      positionsform.h
                                        public slots:
                                          void setValue(int value);
                                      
                                        signals:
                                          void valueChanged(int newValue);
                                      
                                      positionsform.cpp
                                       void positionsForm::setValue(int value)
                                       {          
                                         emit valueChanged(value);    
                                       }
                                      
                                      
                                      P Offline
                                      P Offline
                                      Panoss
                                      wrote on last edited by
                                      #18

                                      It works but the message is printed twice, like if function ArticlesWindow::positionChanged is called twice??

                                      M 1 Reply Last reply
                                      0
                                      • P Panoss

                                        It works but the message is printed twice, like if function ArticlesWindow::positionChanged is called twice??

                                        M Offline
                                        M Offline
                                        mpergand
                                        wrote on last edited by mpergand
                                        #19

                                        @Panoss

                                        class positionsForm *form = new class positionsForm(model, this);

                                        What is that ?

                                        You seem to create an new instance each time openPositionsForm() is called ...

                                        1 Reply Last reply
                                        0
                                        • P Offline
                                          P Offline
                                          Panoss
                                          wrote on last edited by Panoss
                                          #20

                                          Why is this wrong?
                                          Every time I want to open the form I create an instance of it 's class.
                                          When I close the form the instance is destroyed, right?

                                          What 's the correct way?

                                          M jsulmJ JonBJ 3 Replies 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