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. connect to a function
Forum Updated to NodeBB v4.3 + New Features

connect to a function

Scheduled Pinned Locked Moved Solved General and Desktop
17 Posts 4 Posters 1.1k 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.
  • O Offline
    O Offline
    ofmrew
    wrote on last edited by VRonin
    #1

    In MainWiondow.h I have

    public:
        void button1();
        void button5();
    

    and in MainWiondow.cpp I have

        connect(ui->button5, &QPushButton::clicked, button5);
    and 
    void MainWindow::button5(){
        ui->statusbar->showMessage("Button_5_Pressed", 0);
    }
    

    I get an error about reference to non-static member. . . .

    I have buttons 1..4 that work with new, and old and lambda. Know I am trying to connect to just a function.

    What am I missing?

    JonBJ 1 Reply Last reply
    0
    • O ofmrew

      In MainWiondow.h I have

      public:
          void button1();
          void button5();
      

      and in MainWiondow.cpp I have

          connect(ui->button5, &QPushButton::clicked, button5);
      and 
      void MainWindow::button5(){
          ui->statusbar->showMessage("Button_5_Pressed", 0);
      }
      

      I get an error about reference to non-static member. . . .

      I have buttons 1..4 that work with new, and old and lambda. Know I am trying to connect to just a function.

      What am I missing?

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

      @ofmrew

      connect(ui->button5, &QPushButton::clicked, this, &MainWindow::button5);
      
      1 Reply Last reply
      3
      • O Offline
        O Offline
        ofmrew
        wrote on last edited by
        #3

        Please note that I stated that it "work(s) with new, old, and lambda" I had tried what you suggested, but the documentation states:
        New: connecting to simple function
        The new syntax can even connect to functions, not just QObjects:

        connect(
        sender, &Sender::valueChanged,
        someFunction

        That is what I am trying to accomplish thus:
        connect(ui->button5, &QPushButton::clicked, button5);.

        What is required to make that work?

        JonBJ 1 Reply Last reply
        0
        • O ofmrew

          Please note that I stated that it "work(s) with new, old, and lambda" I had tried what you suggested, but the documentation states:
          New: connecting to simple function
          The new syntax can even connect to functions, not just QObjects:

          connect(
          sender, &Sender::valueChanged,
          someFunction

          That is what I am trying to accomplish thus:
          connect(ui->button5, &QPushButton::clicked, button5);.

          What is required to make that work?

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

          @ofmrew said in connect to a function:

          What is required to make that work?

          That button5 be a free (or they called it "simple") function, which it is not in your case (MainWindow::button5()).

          O 1 Reply Last reply
          2
          • JonBJ JonB

            @ofmrew said in connect to a function:

            What is required to make that work?

            That button5 be a free (or they called it "simple") function, which it is not in your case (MainWindow::button5()).

            O Offline
            O Offline
            ofmrew
            wrote on last edited by
            #5

            @JonB
            I thought that I tried that, but apparently I broke the cardinal rule of debugging: make a single change and evaluate, never make more than one change! I must add, however, that it would be nice if the writers of documentation specified that the function must be a non- member (free) function. I included ```
            void button5(){
            // ui->statusbar->showMessage("Button_4_Pressed", 0);
            qDebug() << "Button_5_Pressed";
            }

            in mainwindow.cpp after the includes and ```
            void button5(); 
            

            before the connect statements. That worked, however, it was not what I desired: I wanted the text displayed in the statusbar as shown by the commented statement. What would be the best way to get what is desired? Is sending an event the best way?

            jsulmJ JonBJ 2 Replies Last reply
            0
            • O ofmrew

              @JonB
              I thought that I tried that, but apparently I broke the cardinal rule of debugging: make a single change and evaluate, never make more than one change! I must add, however, that it would be nice if the writers of documentation specified that the function must be a non- member (free) function. I included ```
              void button5(){
              // ui->statusbar->showMessage("Button_4_Pressed", 0);
              qDebug() << "Button_5_Pressed";
              }

              in mainwindow.cpp after the includes and ```
              void button5(); 
              

              before the connect statements. That worked, however, it was not what I desired: I wanted the text displayed in the statusbar as shown by the commented statement. What would be the best way to get what is desired? Is sending an event the best way?

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

              @ofmrew said in connect to a function:

              would be nice if the writers of documentation specified that the function must be a non- member

              Well, a function in C++ is a stand-alone function like in C. A member function is called method.

              "I wanted the text displayed in the statusbar as shown by the commented statement" - then you need to connect to a slot which is a method (not stand-alone function).

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

              1 Reply Last reply
              2
              • O ofmrew

                @JonB
                I thought that I tried that, but apparently I broke the cardinal rule of debugging: make a single change and evaluate, never make more than one change! I must add, however, that it would be nice if the writers of documentation specified that the function must be a non- member (free) function. I included ```
                void button5(){
                // ui->statusbar->showMessage("Button_4_Pressed", 0);
                qDebug() << "Button_5_Pressed";
                }

                in mainwindow.cpp after the includes and ```
                void button5(); 
                

                before the connect statements. That worked, however, it was not what I desired: I wanted the text displayed in the statusbar as shown by the commented statement. What would be the best way to get what is desired? Is sending an event the best way?

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

                @ofmrew
                As @jsulm has said, you do not want to connect to a non-member function and never did want to, I don't understand why you seemed to insist on it.

                Since you want to access ui->statusbar, and ui is a member variable in MainWindow, what was wrong with my first:

                connect(ui->button5, &QPushButton::clicked, this, &MainWindow::button5);
                

                which you immediately rejected?

                O 1 Reply Last reply
                1
                • JonBJ JonB

                  @ofmrew
                  As @jsulm has said, you do not want to connect to a non-member function and never did want to, I don't understand why you seemed to insist on it.

                  Since you want to access ui->statusbar, and ui is a member variable in MainWindow, what was wrong with my first:

                  connect(ui->button5, &QPushButton::clicked, this, &MainWindow::button5);
                  

                  which you immediately rejected?

                  O Offline
                  O Offline
                  ofmrew
                  wrote on last edited by
                  #8

                  @JonB
                  Absolutely nothing! In fact I used exactly that with another button. Let me explain. I have five button each using a different kind of connection:

                      connect(ui->button1, &QPushButton::clicked, this, &MainWindow::button1);
                      connect(ui->button2, &QPushButton::clicked, this, &MainWindow::button2);
                      connect(ui->button3, &QPushButton::clicked, [this](){ui->statusbar->showMessage("Button_3_Pressed", 0);});
                      connect(ui->button4, SIGNAL(clicked()), this, SLOT(button4()));
                      connect(ui->button5, &QPushButton::clicked, button5);
                  

                  To answer the question of why am I trying a free function: because is is allowed and I wanted to know the boundaries, which is that the function seems to be limited to free function. Why do I also what to now how to send text from a free function to the statusbar, because I am writing a book about graphics programming using Qt and this was to be an example of Signals and Slots. I wanted the example to be consistent, but the free function example is putting a crimp in that. Bottom line, I want to learn how to do it if it is possible. I hope that answers your question.

                  JonBJ 1 Reply Last reply
                  0
                  • O ofmrew

                    @JonB
                    Absolutely nothing! In fact I used exactly that with another button. Let me explain. I have five button each using a different kind of connection:

                        connect(ui->button1, &QPushButton::clicked, this, &MainWindow::button1);
                        connect(ui->button2, &QPushButton::clicked, this, &MainWindow::button2);
                        connect(ui->button3, &QPushButton::clicked, [this](){ui->statusbar->showMessage("Button_3_Pressed", 0);});
                        connect(ui->button4, SIGNAL(clicked()), this, SLOT(button4()));
                        connect(ui->button5, &QPushButton::clicked, button5);
                    

                    To answer the question of why am I trying a free function: because is is allowed and I wanted to know the boundaries, which is that the function seems to be limited to free function. Why do I also what to now how to send text from a free function to the statusbar, because I am writing a book about graphics programming using Qt and this was to be an example of Signals and Slots. I wanted the example to be consistent, but the free function example is putting a crimp in that. Bottom line, I want to learn how to do it if it is possible. I hope that answers your question.

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

                    @ofmrew said in connect to a function:

                    Why do I also what to now how to send text from a free function to the statusbar,

                    Preferably you should not have a free function which wants to do this! Unless it is "outside of your code".

                    The problem will be: how can a free function get as far as accessing anything in the UI or the MainWindow where the ui->stausbar is located?

                    and this was to be an example of Signals and Slots

                    Indeed so. What you have been trying to use is a connect() where there is no object for the slot. But what you are asking about is where there is no object for the signaller.

                    In the example you have at present, the signaller is ui->button1, &QPushButton::clicked. If you have some independent function, which knows nothing about the UI, have it emit a signal you invent. So that in MainWindow you have something for the signalling side of connect(), and this, &MainWindow::putTextOnStatusbar for the slot side.

                    This means there has to be an object, which inherits from QObject, as the object which does the emit of the desired text. If you truly are in a free function, you will have to have access to such an object, e.g. so that you can go emit thatObject->sendTextToStatusbar("Some text"). And MainWindow must have sight of that to go:

                    connect(thatObject, &ThatObject::sendTextToStatusbar, this, &MainWindow::putTextOnStatusbar);
                    
                    O 1 Reply Last reply
                    2
                    • Chris KawaC Offline
                      Chris KawaC Offline
                      Chris Kawa
                      Lifetime Qt Champion
                      wrote on last edited by Chris Kawa
                      #10

                      To look at it from another angle - to access an object (statusbar in this case) you have to have a pointer or a reference to it. If you're inside a method of the MainWindow class you have access to it through this->ui->statusbar member.

                      If you're in a free function there are basically two ways (well, there are more, but let's not make this difficult) you can get that pointer inside - through a global static variable or through that function parameter.

                      You can't use the parameter option here because the function signature must match the signal for the connect call to be possible, so that's out.

                      You can use a global static variable - assign it e.g. in the constructor of main window and then you can use it in the free function. But communication through global variables is a terrible application architecture and that's the last thing you should be considering. Also this is error prone, as there's nothing stopping someone from creating multiple instances of your main window class and they will all fight for that static variable to set their member pointer there. While possible to do that's just asking for trouble.

                      Qt widgets are an object oriented system and it is designed around objects and instances. You can work against it with globals and free functions, but that's just making things harder than they need to be. The intended usage of connections is for objects (QObjects specifically) to communicate, so the best option here is to go with the flow and use an object instance and a method, not a free function.

                      O 1 Reply Last reply
                      4
                      • JonBJ JonB

                        @ofmrew said in connect to a function:

                        Why do I also what to now how to send text from a free function to the statusbar,

                        Preferably you should not have a free function which wants to do this! Unless it is "outside of your code".

                        The problem will be: how can a free function get as far as accessing anything in the UI or the MainWindow where the ui->stausbar is located?

                        and this was to be an example of Signals and Slots

                        Indeed so. What you have been trying to use is a connect() where there is no object for the slot. But what you are asking about is where there is no object for the signaller.

                        In the example you have at present, the signaller is ui->button1, &QPushButton::clicked. If you have some independent function, which knows nothing about the UI, have it emit a signal you invent. So that in MainWindow you have something for the signalling side of connect(), and this, &MainWindow::putTextOnStatusbar for the slot side.

                        This means there has to be an object, which inherits from QObject, as the object which does the emit of the desired text. If you truly are in a free function, you will have to have access to such an object, e.g. so that you can go emit thatObject->sendTextToStatusbar("Some text"). And MainWindow must have sight of that to go:

                        connect(thatObject, &ThatObject::sendTextToStatusbar, this, &MainWindow::putTextOnStatusbar);
                        
                        O Offline
                        O Offline
                        ofmrew
                        wrote on last edited by
                        #11

                        @JonB
                        Thank you for the very detailed response. Give me some time to digest what you posted. Again thanks.

                        JonBJ 1 Reply Last reply
                        0
                        • O ofmrew

                          @JonB
                          Thank you for the very detailed response. Give me some time to digest what you posted. Again thanks.

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

                          @ofmrew
                          BTW. If, for whatever reason, you are determined to stick with a free function. There is an existing object which meets the criteria of being able to send a signal and being known to MainWindow: it is the QApplication object/instance of your program. If you subclass that for your application you can add new desired signal(s) for your use case(s). Any code you have which includes Qt, even if it is a free function, can access that to send a signal. MainWindow can access it to connect the slot which updates its statusbar. So you are effectively sending "application signals".

                          1 Reply Last reply
                          1
                          • Chris KawaC Chris Kawa

                            To look at it from another angle - to access an object (statusbar in this case) you have to have a pointer or a reference to it. If you're inside a method of the MainWindow class you have access to it through this->ui->statusbar member.

                            If you're in a free function there are basically two ways (well, there are more, but let's not make this difficult) you can get that pointer inside - through a global static variable or through that function parameter.

                            You can't use the parameter option here because the function signature must match the signal for the connect call to be possible, so that's out.

                            You can use a global static variable - assign it e.g. in the constructor of main window and then you can use it in the free function. But communication through global variables is a terrible application architecture and that's the last thing you should be considering. Also this is error prone, as there's nothing stopping someone from creating multiple instances of your main window class and they will all fight for that static variable to set their member pointer there. While possible to do that's just asking for trouble.

                            Qt widgets are an object oriented system and it is designed around objects and instances. You can work against it with globals and free functions, but that's just making things harder than they need to be. The intended usage of connections is for objects (QObjects specifically) to communicate, so the best option here is to go with the flow and use an object instance and a method, not a free function.

                            O Offline
                            O Offline
                            ofmrew
                            wrote on last edited by
                            #13

                            @Chris-Kawa
                            Thank you for your reply, you and @JonB , have been very helpful. As an old assembler programmer, I knew that all that was needed was a pointer to both the statusbar and the displayMessage function, but then I had to consider the text message.

                            And to answer why, the reason its purely pedagogical: this is not the first time I have wanted this type of linkage. I will take the information you provided and work on it some more. Again, thanks to both of you.

                            JonBJ 1 Reply Last reply
                            1
                            • O ofmrew

                              @Chris-Kawa
                              Thank you for your reply, you and @JonB , have been very helpful. As an old assembler programmer, I knew that all that was needed was a pointer to both the statusbar and the displayMessage function, but then I had to consider the text message.

                              And to answer why, the reason its purely pedagogical: this is not the first time I have wanted this type of linkage. I will take the information you provided and work on it some more. Again, thanks to both of you.

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

                              @ofmrew said in connect to a function:

                              As an old assembler programmer

                              It was indeed all much simpler when we just wrote assembler... You didn't have to worry about this complex stuff because you simply didn't have it! :D

                              O 1 Reply Last reply
                              0
                              • JonBJ JonB

                                @ofmrew said in connect to a function:

                                As an old assembler programmer

                                It was indeed all much simpler when we just wrote assembler... You didn't have to worry about this complex stuff because you simply didn't have it! :D

                                O Offline
                                O Offline
                                ofmrew
                                wrote on last edited by
                                #15

                                @JonB
                                The real complexity was not in what you were doing, but keeping clear were everything was being placed, We were, however, younger and our short term memory was better. The bottom line was you had total control, that is until you interacted with the OS--MVS, DOS, OS2, Windows, WindowsNT, etc.

                                1 Reply Last reply
                                0
                                • O Offline
                                  O Offline
                                  ofmrew
                                  wrote on last edited by
                                  #16

                                  I want to thank JonB and Chris-Kawa for their input. I have decided not to pursue this issue further as there is not point because connecting to a free function seems to be of little use, being able to is interesting, but that is all. I must decide if consistency is important, if it is then switch all to Debug else be inconsistent.

                                  Given that I started programming with FORTRAN II where all functions were free--recall "algorithms + data = programs". Even before C and the C++ preprocessor to convert C++ to C for compiling. Then came Object Oriented Programming where some languages eliminated the free function. I prefer not to use them.

                                  Chris KawaC 1 Reply Last reply
                                  0
                                  • O ofmrew

                                    I want to thank JonB and Chris-Kawa for their input. I have decided not to pursue this issue further as there is not point because connecting to a free function seems to be of little use, being able to is interesting, but that is all. I must decide if consistency is important, if it is then switch all to Debug else be inconsistent.

                                    Given that I started programming with FORTRAN II where all functions were free--recall "algorithms + data = programs". Even before C and the C++ preprocessor to convert C++ to C for compiling. Then came Object Oriented Programming where some languages eliminated the free function. I prefer not to use them.

                                    Chris KawaC Offline
                                    Chris KawaC Offline
                                    Chris Kawa
                                    Lifetime Qt Champion
                                    wrote on last edited by
                                    #17

                                    Thankfully C++ does not subscribe to single style of programming. One of its strengths is support for multiple paradigms. OOP is just one of many of them and it is suited for some tasks and detrimental to others.

                                    It is quite a good fit for retained mode ui programming though, so Qt was designed to embrace it, while still allowing for other patterns if need be. Buttons, windows, events and such can just pretty naturally be described as classes and their instances.

                                    Functional style of programming has its uses in ui too, especially in immediate mode ui libraries like ImGui.

                                    1 Reply Last reply
                                    1

                                    • Login

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