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. [solved] slots and signals, any good tutorial and some help ?

[solved] slots and signals, any good tutorial and some help ?

Scheduled Pinned Locked Moved General and Desktop
13 Posts 4 Posters 3.9k 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.
  • T3STYT Offline
    T3STYT Offline
    T3STY
    wrote on last edited by
    #1

    I read the Qt manual about signals and slots and I understood how this signals and slots system works - in theory. In practice, I still don't know how to actually use that system in code. For instance, I have a QSlider object that, when I drag the slider, I'd like it to notify the new slider value in a qDebug message.

    Can someone link me a good practical use tutorial? And if that's not too much "do my homework for me", could you give me an example code for outputting the new slider position in a qDebug message, please?

    Thank you in advance to anyone! :)

    1 Reply Last reply
    0
    • JKSHJ Offline
      JKSHJ Offline
      JKSH
      Moderators
      wrote on last edited by
      #2

      http://doc.qt.digia.com/4.3/tutorial-t5.html Old but good :)

      Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

      1 Reply Last reply
      0
      • T3STYT Offline
        T3STYT Offline
        T3STY
        wrote on last edited by
        #3

        Nice one, thanks!

        Now, how may I use it to output to qDebug() ? Should I create my own signal and slot for this?

        1 Reply Last reply
        0
        • P Offline
          P Offline
          poorBob
          wrote on last edited by
          #4

          Hello,

          in Your class header You should create Your own slot and then in implementation of this slot You can insert qDebug() for outputting.

          Here's a small example
          @
          class myClass : public QWidget // 1
          {
          Q_OBJECT // 2

          ///   .... some code
          

          // slots section:
          public slots: // 3
          void slotPrintSliderPostion( int iPos );
          }@

          Here are some comments for the numbers above:

          1. To use the signal/slots feature You need to derive from QObject class. QWidget derives from it either.
          2. "Exlpenation why this macro is important!":http://qt-project.org/doc/qt-5.0/qtcore/qobject.html#Q_OBJECT
          3. Slots are defined in this kind of section

          To connecto You slot You can write something like this in Your constructor:
          @
          Q_ASSERT( connect ( pSlider, SIGNAL(sliderMoved(int), this, SLOT(slotPrintSliderPostion) );
          @
          "Q_ASSERT description":http://qt-project.org/doc/qt-5.0/qtcore/qtglobal.html#Q_ASSERT

          And finally example slotPrintSliderPostion implementtion:
          @
          void myClass:: slotPrintSliderPostion(int iPos)
          {
          qDebug() << "Position changed" << iPos;
          }@

          Hope this will help You :)

          Robert

          1 Reply Last reply
          0
          • T3STYT Offline
            T3STYT Offline
            T3STY
            wrote on last edited by
            #5

            Hey Robert, thank you very much!
            Problem is that the code you wrote is not working. Ok, there was a round bracket missing, no issues fixing that. But anyway, When I connect the signal with the slot in my class at runtime I get this:
            @QObject::connect: No such signal QWidget::sliderMoved(int) in ......\projects\Filter\filter.cpp:35@
            My class is derived from QWidget and inherits a QSlider object pointer:
            @class Filter : public QWidget{
            public:
            /*********** De/Contructor ***********/
            Filter(QWidget * parent=0, Qt::WindowFlags flags = 0, uint frequency=0, uint bandWidth=1000, char gain=0, char min=-6, char max= 6, bool lock=false, bool bypass=false);
            ~Filter();

            /*********** Getters ***********/
            // some getter functions here

            /*********** Setters ***********/
            // some setter functions here

            private:
            /* Filter properties */
            // some filter attributes here

            /* Filter control objects */
            QSlider * GainSlider; // The slider object I want to monitor the slider position change

            public slots:
            void slotPrintSliderPostion(int iPos);
            };@
            The GainSlider control which I'd like to monitor the slider change is created in the Filter class constructor.
            @Filter::Filter(QWidget * parent, Qt::WindowFlags flags, uint Frequency, uint Bandwidth, char Gain, char Min, char Max, bool Lock, bool Bypass){
            /* some less important code here */

            /* Creating the filter controls */
            GainSlider = new QSlider;
            GainSlider->setParent(this); // assigning the new QSlider to this QWidget
            GainSlider->setRange(Min, Max);
            GainSlider->setSliderPosition(Gain);

            connect(GainSlider, SIGNAL(sliderMoved(int)), SLOT(slotPrintSliderPostion(int)));
            /*
            the use of Q_ASSERT will result in a Visual C++ Runtime error
            Q_ASSERT(connect(GainSlider, SIGNAL(sliderMoved(int)), SLOT(slotPrintSliderPostion(int)))));
            */
            }@

            Can you tell me what's wrong here?
            Also, when I run using Q_ASSERT() at runtime I get a Visual C++ Runtime error saying "The application has requested the Runtime to terminate in an unusual way". Why is that?

            1 Reply Last reply
            0
            • P Offline
              P Offline
              poorBob
              wrote on last edited by
              #6

              Ok,

              I wrote that code without compiling it ;), so there might be some problems like missing semicolon after class last bracket ;). I'm running Windows at the moment, where I don't have any C++/Qt tool to compile the code...

              Problem: QObject::connect: No such signal QWidget::sliderMoved(int) in ......\projects\Filter\filter.cpp:35
              Solution: try to add Q_OBJECT macro to Your class
              @
              class Filter : public QWidget{
              Q_OBJECT //!!
              public:
              //....
              };
              @

              Problem: Q_ASSERT and Visual. I can't help You with this, because I code in Qt only on Linux.
              Possible solution 1: try regular assert from "C++ assert":http://www.cplusplus.com/reference/cassert/assert/
              Possible solution might also be here: "StackOverflow topic":http://stackoverflow.com/questions/13893122/q-assert-has-different-behavior-when-my-project-is-built-in-visual-studio-vs-qt

              BTW: Which Qt version do You use?
              Robert :)

              1 Reply Last reply
              0
              • T3STYT Offline
                T3STYT Offline
                T3STY
                wrote on last edited by
                #7

                I'm using Qt 5.1.1 with mingw32 and mingw64 (gcc 4.8 compiler).

                Adding Q_OBJECT to the class results in the "undefined reference to `vtable for Filter'" error. I think it's not necessary since QWidget is already a Q_OBJECT and calling this macro again breaks things.
                Calling C++'s assert doesn't change things, it would only allow me to use a [Retry][Terminate][Ignore] dialog which won't crash the application so I can keep using it.

                I'll try a few different options like monitoring the Filter class instead of the QSlider object, I hope to get a working signal-slot communication, and then I may look further in this issue.

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

                  When adding/removing the Q_OBJECT macro, qmake must be run again in order to generate respectively remove moc generated code for your class.

                  Q_OBJECT must be added as soon as you want to add signals and slots in your classes.

                  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
                  • T3STYT Offline
                    T3STYT Offline
                    T3STY
                    wrote on last edited by
                    #9

                    Nevermind! I found the issue!

                    For those like me who have manually added Qt versions and compilers (in my case mingw32 and mingw64) you should remember that qmake doesn't always run automatically. For this reason adding Q_OBJECT to any class will result in the error "undefined reference to `vtable for YourClassHere’". But if you don't add such macro to the class you won't get the signals and slots on your class.
                    The solution is to manually run qmake by doing right-click on the project name in QtCreator's Projects pane and then select "Run qmake". This will generate all the necessary code needed for the signals and slot system (vtable is one of them).

                    I now successfully connected my slider(s) to qDebug using the exact code I had two posts ago ( http://qt-project.org/forums/viewreply/150095/ ) by only adding Q_OBJECT to the class and manually running qmake.

                    Thank you for your assistance Robert, and thank you for your help too JKSH :)

                    1 Reply Last reply
                    0
                    • JKSHJ Offline
                      JKSHJ Offline
                      JKSH
                      Moderators
                      wrote on last edited by
                      #10

                      [quote author="T3STY" date="1384122716"]Nevermind! I found the issue![/quote]Glad to hear :) Happy coding! Thank you for sharing your solution and explanations.

                      [quote author="poorBob" date="1384103644"]
                      @
                      Q_ASSERT( connect ( pSlider, SIGNAL(sliderMoved(int), this, SLOT(slotPrintSliderPostion) );
                      @
                      [/quote]You don't want to put connect(), or any other function with side effects, inside Q_ASSERT(). Everything inside Q_ASSERT() will disappear in a Release build, meaning that your connection will not be made.

                      Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

                      1 Reply Last reply
                      0
                      • T3STYT Offline
                        T3STYT Offline
                        T3STY
                        wrote on last edited by
                        #11

                        Oh, I missed that point on Q_ASSERT()... I'll be careful using it then. I must say though that it's very useful when you're not sure the code will behave correctly, so I am using it to keep the application working even if any fault happens.

                        BTW, another thing related to Q_OBJECT: header and source must be separated in split files (.h and .cpp), and the Q_OBJECT macro must be called in the class definition in the header file. Including the source in the same file as the headers causes a compilation error. I'm not really sure why is that, but it's good to know there is a workaround.

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

                          You can use a variable for that.

                          @bool success = connet(pSlider, SIGNAL(sliderMoved(int)), SLOT(slotPrintSliderPosition()));
                          Q_ASSERT(success);@

                          What do you mean by including the source in the same file as the header ?

                          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
                          • T3STYT Offline
                            T3STYT Offline
                            T3STY
                            wrote on last edited by
                            #13

                            I mean doing like this:
                            @class myclass : public QWidget{
                            Q_WIDGET
                            myclass();
                            ~myclass();
                            }

                            /* when you define any class function together with the class prototype
                            a lot of compilation error related to vtable or so will popup from nowhere
                            even if the code syntax and semantics is right */
                            myclass::myclass(){
                            // do some stuff here
                            }@

                            An example of this can be found here:
                            http://stackoverflow.com/questions/9272047/undefined-reference-to-vtable-for-digitalclock-undefined-reference-to-digit?lq=1
                            and here:
                            http://stackoverflow.com/questions/6367735/qt-error-undefined-reference-to-vtable-for-thread?rq=1
                            In this last link, the 2 answer explains that the meta-object compiler will only run on header files, not on source files (like .cpp), and that's what causes the issue.

                            Simply put, separating a class in .h and .cpp files will avoid this issue.

                            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