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. same signal-slot connection in two windows
Qt 6.11 is out! See what's new in the release blog

same signal-slot connection in two windows

Scheduled Pinned Locked Moved Solved General and Desktop
60 Posts 9 Posters 9.6k Views 3 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.
  • R russjohn834

    @JonB

    I thought api should be known and accessible to all classes if intialized as global in the main.cpp

    #include <QApplication>
    
    tetra_grip_api api; //-------------> api instance
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
    
        api.openSerialPort();
        QObject::connect(api.serial, SIGNAL(readyRead()), &api, SLOT(readData()));
        QObject::connect(api.serial, SIGNAL(error(QSerialPort::SerialPortError)),&api, SLOT(ErrorHandler(QSerialPort::SerialPortError))); // error handling
    
    
        Settings w(nullptr);
        w.show();
    
        return a.exec();
    }
    

    Correct me if I'm wrong.

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

    @russjohn834
    Your Settings & Patients classes are defined in a different source module from main.cpp, right? So how do they gain access to reference the api symbol in order to compile?

     connect(&api, &tetra_grip_api::tetraGripEvent,this, &Patients::eventHandlerTwo);
    

    I am having to tease out each bit of relevant information, one at a time....

    1 Reply Last reply
    2
    • R Offline
      R Offline
      russjohn834
      wrote on last edited by
      #22

      @JonB
      Correct. I actually did not do anything other that making apiinstance as global in main.cpp. That might be the issue. But dont know how to proceed. How do I make Patients classes know about global api instance?

      jsulmJ JonBJ 2 Replies Last reply
      0
      • R russjohn834

        @JonB
        Correct. I actually did not do anything other that making apiinstance as global in main.cpp. That might be the issue. But dont know how to proceed. How do I make Patients classes know about global api instance?

        jsulmJ Online
        jsulmJ Online
        jsulm
        Lifetime Qt Champion
        wrote on last edited by
        #23

        @russjohn834 You should avoid global variables as much as possible.
        Just pass the pointer to api to Settings & Patients constructors...

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

        1 Reply Last reply
        2
        • J Offline
          J Offline
          jazzco2
          wrote on last edited by jazzco2
          #24

          Did you ensure that the connection in Patients is done before the signal tetra_grip_api::tetraGripEvent is emitted? Some qDebugs around connection, in the very first line of Patients::eventHandlerTwo and in the deconstructor of Patients should help to prove that.

          1 Reply Last reply
          1
          • R russjohn834

            @JonB
            Correct. I actually did not do anything other that making apiinstance as global in main.cpp. That might be the issue. But dont know how to proceed. How do I make Patients classes know about global api instance?

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

            @russjohn834 said in same signal-slot connection in two windows:

            @JonB
            Correct. I actually did not do anything other that making apiinstance as global in main.cpp. That might be the issue. But dont know how to proceed. How do I make Patients classes know about global api instance?

            I truly, truly do not understand. You said your program runs but does/does not behave properly in the cases you mentioned. I asked how you can even compile your Settings/Patients modules/.cpp source files which contain the line connect(&api, ..., when api is defined in main.cpp? From what you have said/shown they should error at compile-time with a "No such variable: api" message. So I will leave others to help, who obviously understand your source code better than I.

            J 1 Reply Last reply
            3
            • JonBJ JonB

              @russjohn834 said in same signal-slot connection in two windows:

              @JonB
              Correct. I actually did not do anything other that making apiinstance as global in main.cpp. That might be the issue. But dont know how to proceed. How do I make Patients classes know about global api instance?

              I truly, truly do not understand. You said your program runs but does/does not behave properly in the cases you mentioned. I asked how you can even compile your Settings/Patients modules/.cpp source files which contain the line connect(&api, ..., when api is defined in main.cpp? From what you have said/shown they should error at compile-time with a "No such variable: api" message. So I will leave others to help, who obviously understand your source code better than I.

              J Offline
              J Offline
              jazzco2
              wrote on last edited by
              #26

              @JonB Yes, that's interesting. You can't include main.cpp in Settings or in Patients. So main.cpps line

              tetra_grip_api api; //-------------> api instance
              

              isn't visible anywhere!

              JonBJ 1 Reply Last reply
              1
              • J Offline
                J Offline
                jazzco2
                wrote on last edited by
                #27

                @russjohn834 If you are using QtCreator: When you go on the &api in your connect statements in both Settings and Patients and press F2 - where does it lead you to?

                1 Reply Last reply
                1
                • R Offline
                  R Offline
                  russjohn834
                  wrote on last edited by
                  #28

                  @jazzco2

                  From both Settings and Patients , &api leads me here:

                  #ifndef TETRA_GRIP_API_H
                  #define TETRA_GRIP_API_H
                  
                  #include <QObject>
                  #include <stdio.h>
                  #include <stdlib.h>
                  #include <iostream>
                  #include <QLabel>
                  #include <QMessageBox>
                  #include <QTimer>
                  
                  #define _CRT_SECURE_NO_DEPRECATE
                  
                  class tetra_grip_api : public QObject
                  {
                      Q_OBJECT
                  
                  public:
                      explicit tetra_grip_api(QObject *parent = nullptr);
                  
                      #define MAX_CONFIG_FILE_LENGTH (10000)
                  
                       void static send_config_file(QByteArray config, bool nonvolatile);
                       void static send_long_register(uint8_t, uint32_t, uint8_t *);
                       void static stimulation_set_current(unsigned int, unsigned int);
                  
                       QSerialPort *serial = nullptr;
                  
                       QTimer autoConnectionTimer;
                       bool tryToAutoconnect;
                  
                  signals:
                  
                       void tetraGripEvent(STIM_GUI_TOPIC_T topic, uint8_t reg, uint32_t value);
                  
                  
                  
                  public slots:
                  
                       void openSerialPort();
                       void closeSerialPort();
                       void readData();
                  
                  
                  private slots:
                  
                       void ErrorHandler(QSerialPort::SerialPortError error);
                  
                  private:
                  
                          QString comPortName;
                  
                  };
                  
                  extern tetra_grip_api api;  //----------> it leads me here
                  
                  #endif // TETRA_GRIP_API_H
                  
                  jsulmJ 1 Reply Last reply
                  0
                  • R russjohn834

                    @jazzco2

                    From both Settings and Patients , &api leads me here:

                    #ifndef TETRA_GRIP_API_H
                    #define TETRA_GRIP_API_H
                    
                    #include <QObject>
                    #include <stdio.h>
                    #include <stdlib.h>
                    #include <iostream>
                    #include <QLabel>
                    #include <QMessageBox>
                    #include <QTimer>
                    
                    #define _CRT_SECURE_NO_DEPRECATE
                    
                    class tetra_grip_api : public QObject
                    {
                        Q_OBJECT
                    
                    public:
                        explicit tetra_grip_api(QObject *parent = nullptr);
                    
                        #define MAX_CONFIG_FILE_LENGTH (10000)
                    
                         void static send_config_file(QByteArray config, bool nonvolatile);
                         void static send_long_register(uint8_t, uint32_t, uint8_t *);
                         void static stimulation_set_current(unsigned int, unsigned int);
                    
                         QSerialPort *serial = nullptr;
                    
                         QTimer autoConnectionTimer;
                         bool tryToAutoconnect;
                    
                    signals:
                    
                         void tetraGripEvent(STIM_GUI_TOPIC_T topic, uint8_t reg, uint32_t value);
                    
                    
                    
                    public slots:
                    
                         void openSerialPort();
                         void closeSerialPort();
                         void readData();
                    
                    
                    private slots:
                    
                         void ErrorHandler(QSerialPort::SerialPortError error);
                    
                    private:
                    
                            QString comPortName;
                    
                    };
                    
                    extern tetra_grip_api api;  //----------> it leads me here
                    
                    #endif // TETRA_GRIP_API_H
                    
                    jsulmJ Online
                    jsulmJ Online
                    jsulm
                    Lifetime Qt Champion
                    wrote on last edited by
                    #29

                    @russjohn834 said in same signal-slot connection in two windows:

                    extern tetra_grip_api api;

                    You really should not do it like this. Pass pointer to the constructors of the classes which need it.

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

                    1 Reply Last reply
                    2
                    • J jazzco2

                      @JonB Yes, that's interesting. You can't include main.cpp in Settings or in Patients. So main.cpps line

                      tetra_grip_api api; //-------------> api instance
                      

                      isn't visible anywhere!

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

                      @jazzco2 said in same signal-slot connection in two windows:

                      @JonB Yes, that's interesting. You can't include main.cpp in Settings or in Patients.

                      No, but you might be including main.h, and maybe you have extern tetra_grip_api api; there, that's the sort of thing I was trying to understand. Which finally you have shown is actually in tetra_grip_api.h, which I guess you are including into each of them?

                      For the line there

                      extern tetra_grip_api api;
                      

                      does the docs for tetra_grip_api say you are responsible for defining tetra_grip_api api; yourself like you have done in main.cpp, or does it say they (the library) are defining that global instance and you are supposed to use their instance?

                      R 1 Reply Last reply
                      2
                      • J Offline
                        J Offline
                        jazzco2
                        wrote on last edited by
                        #31

                        @russjohn834 Yes, pass the pointer - and then your api can be a local variable in main. No need to define it outside as main lives as long as the application is running.

                        1 Reply Last reply
                        1
                        • R Offline
                          R Offline
                          russjohn834
                          wrote on last edited by
                          #32

                          @jazzco2

                          Could you give me an example to show how do I pass a pointer to the constructor of the classes? for ex. if I need to use it in in Settings and Patients classes ?

                          jsulmJ 1 Reply Last reply
                          0
                          • R russjohn834

                            @jazzco2

                            Could you give me an example to show how do I pass a pointer to the constructor of the classes? for ex. if I need to use it in in Settings and Patients classes ?

                            jsulmJ Online
                            jsulmJ Online
                            jsulm
                            Lifetime Qt Champion
                            wrote on last edited by
                            #33

                            @russjohn834 said in same signal-slot connection in two windows:

                            Could you give me an example to show how do I pass a pointer to the constructor of the classes?

                            Well

                            tetra_grip_api api;
                            Settings settings(&api);
                            

                            Of cource you have to change the constructor, but this is C++ basic stuff.

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

                            R 1 Reply Last reply
                            2
                            • JonBJ JonB

                              @jazzco2 said in same signal-slot connection in two windows:

                              @JonB Yes, that's interesting. You can't include main.cpp in Settings or in Patients.

                              No, but you might be including main.h, and maybe you have extern tetra_grip_api api; there, that's the sort of thing I was trying to understand. Which finally you have shown is actually in tetra_grip_api.h, which I guess you are including into each of them?

                              For the line there

                              extern tetra_grip_api api;
                              

                              does the docs for tetra_grip_api say you are responsible for defining tetra_grip_api api; yourself like you have done in main.cpp, or does it say they (the library) are defining that global instance and you are supposed to use their instance?

                              R Offline
                              R Offline
                              russjohn834
                              wrote on last edited by
                              #34

                              @JonB

                              it did not mention anything like that. My primary requirement is to use tetra_grip_api(which is a class containing all serial communication objects) instance in every form class. That's why I made it global, but now I realize it's not a good way of programming!

                              JonBJ 1 Reply Last reply
                              0
                              • R russjohn834

                                @JonB

                                it did not mention anything like that. My primary requirement is to use tetra_grip_api(which is a class containing all serial communication objects) instance in every form class. That's why I made it global, but now I realize it's not a good way of programming!

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

                                @russjohn834 said in same signal-slot connection in two windows:
                                Yes and no, it gets complicated. You may not need to pass it around that way.

                                It looks like the tetra_grip_api is something in-house to you, it does not exist on the web. You have shown that tetra_grip_api.h file contains the line:

                                extern tetra_grip_api api;  //----------> it leads me here
                                

                                You should ask the author of that file whether he intends:

                                1. It is up to you to go tetra_grip_api api once in one of your own files, in order to define it, as you have done in your main.cpp; OR

                                2. The tetra_grip_api library already contains this definition for you, and you are supposed to use that one.

                                For now, humour me:

                                Go into your main.cpp. Locate the line which reads:

                                tetra_grip_api api; //-------------> api instance
                                

                                Now comment out that line.

                                Try to rebuild & relink. What happens? Do you end up, after the linking, with an error message like: "Unresolved symbol: ''tetra_grip_api", or not?

                                • If there is no error, see whether your program behaves correctly now.

                                • If there is an error, unfortunately it's time we saw all your relevant code which should work but does not, because there is way too much incomplete information in what you have posted. I hesitate to say this, because I have a bad feeling that's going to be (at least) 3 .cpp files & 3 .h. files. Which is an awful lot for to paste and for us to look through :( If you could cut it down to a relevant, minimal subset which reproduces the bad behaviour you say you see, that would be really good....

                                1 Reply Last reply
                                2
                                • jsulmJ jsulm

                                  @russjohn834 said in same signal-slot connection in two windows:

                                  Could you give me an example to show how do I pass a pointer to the constructor of the classes?

                                  Well

                                  tetra_grip_api api;
                                  Settings settings(&api);
                                  

                                  Of cource you have to change the constructor, but this is C++ basic stuff.

                                  R Offline
                                  R Offline
                                  russjohn834
                                  wrote on last edited by
                                  #36

                                  @JonB Thanks a lot for your feedback.

                                  Commenting out of tetra_grip_api api in the main.cpp did end up in multiple errors with "Unresolved external symbol class tetra_grip_api api".

                                  From the suggestions from you guys, I feel like there is something wrong in making use of global variables. I should try also the other way of passing pointer to the class.

                                  But I was trying to understand a reason program behaves this way.

                                  As I mentioned earlier , If I call Patients behaves badly if I call it from Settings. But instead If I call both Patieints and Settings in the main (as shown below), both behave as expected. Do you immedatly think of any reason for this!?

                                  #include <QApplication>
                                  
                                  tetra_grip_api api;
                                  
                                  int main(int argc, char *argv[])
                                  {
                                      QApplication a(argc, argv);
                                  
                                      api.openSerialPort();
                                      QObject::connect(api.serial, SIGNAL(readyRead()), &api, SLOT(readData()));
                                      QObject::connect(api.serial, SIGNAL(error(QSerialPort::SerialPortError)),&api, SLOT(ErrorHandler(QSerialPort::SerialPortError))); // error handling
                                  
                                  
                                      Settings  w(nullptr); //---->this behaves right
                                      Patients  v(nullptr); //---- >this behaves right
                                      v.show();
                                      w.show();
                                  
                                      return a.exec();
                                  }
                                  
                                  JonBJ 1 Reply Last reply
                                  0
                                  • R russjohn834

                                    @JonB Thanks a lot for your feedback.

                                    Commenting out of tetra_grip_api api in the main.cpp did end up in multiple errors with "Unresolved external symbol class tetra_grip_api api".

                                    From the suggestions from you guys, I feel like there is something wrong in making use of global variables. I should try also the other way of passing pointer to the class.

                                    But I was trying to understand a reason program behaves this way.

                                    As I mentioned earlier , If I call Patients behaves badly if I call it from Settings. But instead If I call both Patieints and Settings in the main (as shown below), both behave as expected. Do you immedatly think of any reason for this!?

                                    #include <QApplication>
                                    
                                    tetra_grip_api api;
                                    
                                    int main(int argc, char *argv[])
                                    {
                                        QApplication a(argc, argv);
                                    
                                        api.openSerialPort();
                                        QObject::connect(api.serial, SIGNAL(readyRead()), &api, SLOT(readData()));
                                        QObject::connect(api.serial, SIGNAL(error(QSerialPort::SerialPortError)),&api, SLOT(ErrorHandler(QSerialPort::SerialPortError))); // error handling
                                    
                                    
                                        Settings  w(nullptr); //---->this behaves right
                                        Patients  v(nullptr); //---- >this behaves right
                                        v.show();
                                        w.show();
                                    
                                        return a.exec();
                                    }
                                    
                                    JonBJ Offline
                                    JonBJ Offline
                                    JonB
                                    wrote on last edited by JonB
                                    #37

                                    @russjohn834
                                    No, because you show the case which works OK. We need to see exactly how Settings calls Patients, plus the signal connections, with whatever is relevant to that case, to judge where the problem is.

                                    1 Reply Last reply
                                    0
                                    • R Offline
                                      R Offline
                                      russjohn834
                                      wrote on last edited by
                                      #38

                                      @JonB

                                      This is how I call Patients from Settings

                                      void Settings::on_pushButton_patients_clicked()
                                      {
                                          this->close();
                                          stagetwo = new Patients(this);
                                          stagetwo -> show();
                                      }
                                      

                                      where stagetwo is public

                                      public:
                                           Settings(QString,QWidget *parent = nullptr);
                                          ~Settings();
                                           Patients *stagetwo;
                                      

                                      In the Patients signal connection is as below:

                                      Patients::Patients( QWidget *parent) :
                                          QMainWindow(parent),
                                          ui(new Ui::Patients)
                                      {
                                          ui->setupUi(this);
                                      
                                      connect(&api, &tetra_grip_api::tetraGripEvent,this, &StageTwoPatients::eventHandlerTwo);
                                      
                                      }
                                      
                                      JonBJ R 2 Replies Last reply
                                      0
                                      • R russjohn834

                                        @JonB

                                        This is how I call Patients from Settings

                                        void Settings::on_pushButton_patients_clicked()
                                        {
                                            this->close();
                                            stagetwo = new Patients(this);
                                            stagetwo -> show();
                                        }
                                        

                                        where stagetwo is public

                                        public:
                                             Settings(QString,QWidget *parent = nullptr);
                                            ~Settings();
                                             Patients *stagetwo;
                                        

                                        In the Patients signal connection is as below:

                                        Patients::Patients( QWidget *parent) :
                                            QMainWindow(parent),
                                            ui(new Ui::Patients)
                                        {
                                            ui->setupUi(this);
                                        
                                        connect(&api, &tetra_grip_api::tetraGripEvent,this, &StageTwoPatients::eventHandlerTwo);
                                        
                                        }
                                        
                                        JonBJ Offline
                                        JonBJ Offline
                                        JonB
                                        wrote on last edited by
                                        #39

                                        @russjohn834 said in same signal-slot connection in two windows:

                                        void Settings::on_pushButton_patients_clicked()
                                        {
                                        this->close();
                                        stagetwo = new Patients(this);
                                        stagetwo -> show();
                                        }

                                        Just to humour me, replace by

                                        void Settings::on_pushButton_patients_clicked()
                                        {
                                            // this->close();
                                            // stagetwo = new Patients(this);
                                            stagetwo = new Patients(nullptr);
                                            stagetwo -> show();
                                        }
                                        

                                        Any better behaviour?

                                        1 Reply Last reply
                                        1
                                        • R Offline
                                          R Offline
                                          russjohn834
                                          wrote on last edited by
                                          #40

                                          @JonB

                                          Can't see any change.

                                          JonBJ 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