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. Connecting signals and slots
Forum Updated to NodeBB v4.3 + New Features

Connecting signals and slots

Scheduled Pinned Locked Moved Solved General and Desktop
9 Posts 4 Posters 2.7k 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.
  • JimmyMarsJ Offline
    JimmyMarsJ Offline
    JimmyMars
    wrote on last edited by
    #1

    I want to connect the signals and slots of the lcd and slider widgets.
    I have created my own slider class, in which a QSlider object is created.
    The lcd object is created inside main.cpp.
    How do I connect these two widgets together?
    What have I done wrong?

    I get the following errors:

    0_1497021647486_Screen Shot 2017-06-09 at 17.20.16.png

    0_1497021727504_Screen Shot 2017-06-09 at 17.21.07.png

    0_1497021747666_Screen Shot 2017-06-09 at 17.21.22.png

    0_1497021759061_Screen Shot 2017-06-09 at 17.21.39.png

    main.cpp:

    #include <QSlider>
    #include <QLCDNumber>
    #include <QApplication>
    #include <QVBoxLayout>
    
    #include "slider.h"
    
    int main(int argc, char *argv[]) {
        QApplication app(argc, argv);
    
        Slider *slider = new Slider(Qt::Horizontal);
        slider->setRange(-100, 100);
        slider->setValue(20);
    
        QLCDNumber *lcd = new QLCDNumber;
        lcd->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding));
    
        connect(slider, &Slider::valueChanged, lcd, &QLCDNumber::display);
    
        QWidget *top = new QWidget;
        QVBoxLayout *layout = new QVBoxLayout(top);
        layout->addWidget(slider);
        layout->addWidget(lcd);
    
        top->show();
        return app.exec();
    }
    

    slider.cpp:

    #include "slider.h"
    
    
    Slider::Slider(Qt::Orientation orient, QWidget *parent) : QWidget(parent) {
        m_slider = new QSlider(orient);
        QVBoxLayout *layout = new QVBoxLayout;
        layout->addWidget(m_slider);
        setLayout(layout);
        connect(m_slider, &QSlider::valueChanged, this, &Slider::setValue );
    }
    
    void Slider::setRange(int min, int max) {
        m_slider->setRange(min, max);
    }
    
    void Slider::setValue(int newValue) {
        if (newValue != m_value) {
            m_slider->setValue(newValue);
            m_value = newValue;
            emit valueChanged(newValue);
        }
    }
    

    slider.h:

    #ifndef SLIDER_H
    #define SLIDER_H
    
    #include <QSlider>
    #include <QVBoxLayout>
    #include <QLCDNumber>
    
    
    class QSlider;
    
    class Slider : public QWidget {
        Q_OBJECT
    public:
        Slider(Qt::Orientation orient = Qt::Horizontal, QWidget *parent = 0);
        void setRange(int min, int max);
    
    public slots:
        void setValue(int newValue);
    signals:
        void valueChanged(int newValue);
    private:
        QSlider *m_slider;
        int m_value;
    };
    
    #endif // SLIDER_H
    
    
    K 1 Reply Last reply
    0
    • ? Offline
      ? Offline
      A Former User
      wrote on last edited by
      #2

      Hi! The image-upload feature on our forum is broken, you might see the picture but other users don't. Please upload your image to a image hoster of your choice (e.g. postimage.org) and embed the pic here with the following markup: ![alternate text](image-url). See also How to insert image on this forum and Hitchhiker's Visual Guide to the Qt Forum.

      K 1 Reply Last reply
      0
      • JimmyMarsJ JimmyMars

        I want to connect the signals and slots of the lcd and slider widgets.
        I have created my own slider class, in which a QSlider object is created.
        The lcd object is created inside main.cpp.
        How do I connect these two widgets together?
        What have I done wrong?

        I get the following errors:

        0_1497021647486_Screen Shot 2017-06-09 at 17.20.16.png

        0_1497021727504_Screen Shot 2017-06-09 at 17.21.07.png

        0_1497021747666_Screen Shot 2017-06-09 at 17.21.22.png

        0_1497021759061_Screen Shot 2017-06-09 at 17.21.39.png

        main.cpp:

        #include <QSlider>
        #include <QLCDNumber>
        #include <QApplication>
        #include <QVBoxLayout>
        
        #include "slider.h"
        
        int main(int argc, char *argv[]) {
            QApplication app(argc, argv);
        
            Slider *slider = new Slider(Qt::Horizontal);
            slider->setRange(-100, 100);
            slider->setValue(20);
        
            QLCDNumber *lcd = new QLCDNumber;
            lcd->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding));
        
            connect(slider, &Slider::valueChanged, lcd, &QLCDNumber::display);
        
            QWidget *top = new QWidget;
            QVBoxLayout *layout = new QVBoxLayout(top);
            layout->addWidget(slider);
            layout->addWidget(lcd);
        
            top->show();
            return app.exec();
        }
        

        slider.cpp:

        #include "slider.h"
        
        
        Slider::Slider(Qt::Orientation orient, QWidget *parent) : QWidget(parent) {
            m_slider = new QSlider(orient);
            QVBoxLayout *layout = new QVBoxLayout;
            layout->addWidget(m_slider);
            setLayout(layout);
            connect(m_slider, &QSlider::valueChanged, this, &Slider::setValue );
        }
        
        void Slider::setRange(int min, int max) {
            m_slider->setRange(min, max);
        }
        
        void Slider::setValue(int newValue) {
            if (newValue != m_value) {
                m_slider->setValue(newValue);
                m_value = newValue;
                emit valueChanged(newValue);
            }
        }
        

        slider.h:

        #ifndef SLIDER_H
        #define SLIDER_H
        
        #include <QSlider>
        #include <QVBoxLayout>
        #include <QLCDNumber>
        
        
        class QSlider;
        
        class Slider : public QWidget {
            Q_OBJECT
        public:
            Slider(Qt::Orientation orient = Qt::Horizontal, QWidget *parent = 0);
            void setRange(int min, int max);
        
        public slots:
            void setValue(int newValue);
        signals:
            void valueChanged(int newValue);
        private:
            QSlider *m_slider;
            int m_value;
        };
        
        #endif // SLIDER_H
        
        
        K Offline
        K Offline
        koahnig
        wrote on last edited by koahnig
        #3

        @JimmyMars

        You might want to check with the string-based connect version

         connect(slider, SIGNAL(valueChanged(int) ), lcd, SLOT(display(int));
        

        You have most likely have a problem with the fifth case of too much complexity for functor-based connect

        Vote the answer(s) that helped you to solve your issue(s)

        JimmyMarsJ 1 Reply Last reply
        1
        • ? A Former User

          Hi! The image-upload feature on our forum is broken, you might see the picture but other users don't. Please upload your image to a image hoster of your choice (e.g. postimage.org) and embed the pic here with the following markup: ![alternate text](image-url). See also How to insert image on this forum and Hitchhiker's Visual Guide to the Qt Forum.

          K Offline
          K Offline
          koahnig
          wrote on last edited by
          #4

          @Wieland
          Funnily, I see the picture ;)

          Is there a pattern?

          Vote the answer(s) that helped you to solve your issue(s)

          ? 1 Reply Last reply
          0
          • K koahnig

            @Wieland
            Funnily, I see the picture ;)

            Is there a pattern?

            ? Offline
            ? Offline
            A Former User
            wrote on last edited by
            #5

            @koahnig If I understood Tero's explanation correctly, it's pure luck: the forum is distributed over a couple of servers and thanks to some bug they don't share their image files. So you can see an image if the website you're looking at now comes from the same machine that the user uploaded the image to.

            1 Reply Last reply
            0
            • K koahnig

              @JimmyMars

              You might want to check with the string-based connect version

               connect(slider, SIGNAL(valueChanged(int) ), lcd, SLOT(display(int));
              

              You have most likely have a problem with the fifth case of too much complexity for functor-based connect

              JimmyMarsJ Offline
              JimmyMarsJ Offline
              JimmyMars
              wrote on last edited by
              #6

              @koahnig
              I have now replaced it as you said with:

              QObject::connect(slider, SIGNAL(valueChanged(int)), lcd, SLOT(display(int)));
              

              and it works.
              Thanks.

              But why doesn't it work using function pointers?
              I am using Qt 5.8.0 with Qt Creator.

              K ? 2 Replies Last reply
              0
              • JimmyMarsJ JimmyMars

                @koahnig
                I have now replaced it as you said with:

                QObject::connect(slider, SIGNAL(valueChanged(int)), lcd, SLOT(display(int)));
                

                and it works.
                Thanks.

                But why doesn't it work using function pointers?
                I am using Qt 5.8.0 with Qt Creator.

                K Offline
                K Offline
                koahnig
                wrote on last edited by
                #7

                @JimmyMars

                Frankly, I do not know, yet.

                The documentation just says that it is more complex with the functor-based connect and with string-based versions it is simple.
                I love the functor because it is checked during compilation. So far, I assumed that the functor-based connect does not allow overloading. While trying to find the reference for you, I just saw that it is more complex. So either the documentation has changed since I started to use functors or I simply pushed it aside until I was comfortable with the functors and forgot. Now it is on my todo list ;)

                Vote the answer(s) that helped you to solve your issue(s)

                1 Reply Last reply
                0
                • JimmyMarsJ JimmyMars

                  @koahnig
                  I have now replaced it as you said with:

                  QObject::connect(slider, SIGNAL(valueChanged(int)), lcd, SLOT(display(int)));
                  

                  and it works.
                  Thanks.

                  But why doesn't it work using function pointers?
                  I am using Qt 5.8.0 with Qt Creator.

                  ? Offline
                  ? Offline
                  A Former User
                  wrote on last edited by
                  #8

                  @JimmyMars said in Connecting signals and slots:

                  But why doesn't it work using function pointers?

                  Using the function pointers syntax, the signatures of the signal and slot must match. In this case, QLCDNumber::display(...) has three overloads:

                  void display(const QString &s)
                  void display(int num)
                  void display(double num)
                  

                  You have to explicitly state which of these overloads you want to use:

                  QObject::connect(slider, &QSlider::valueChanged, lcd, static_cast<void (QLCDNumber::*)(int)>(&QLCDNumber::display));
                  
                  JKSHJ 1 Reply Last reply
                  4
                  • ? A Former User

                    @JimmyMars said in Connecting signals and slots:

                    But why doesn't it work using function pointers?

                    Using the function pointers syntax, the signatures of the signal and slot must match. In this case, QLCDNumber::display(...) has three overloads:

                    void display(const QString &s)
                    void display(int num)
                    void display(double num)
                    

                    You have to explicitly state which of these overloads you want to use:

                    QObject::connect(slider, &QSlider::valueChanged, lcd, static_cast<void (QLCDNumber::*)(int)>(&QLCDNumber::display));
                    
                    JKSHJ Offline
                    JKSHJ Offline
                    JKSH
                    Moderators
                    wrote on last edited by JKSH
                    #9

                    @Wieland said in Connecting signals and slots:

                    QObject::connect(slider, &QSlider::valueChanged, lcd, static_cast<void (QLCDNumber::*)(int)>(&QLCDNumber::display));
                    

                    Or, for shorter code:

                    QObject::connect(slider, &QSlider::valueChanged, lcd, QOverload<int>::of(&QLCDNumber::display));
                    

                    Or even shorter still, if your compiler supports C++14:

                    QObject::connect(slider, &QSlider::valueChanged, lcd, qOverload<int>(&QLCDNumber::display));
                    

                    (P.S. These exact examples, including @Wieland's code, can be found at http://doc.qt.io/qt-5/signalsandslots-syntaxes.html#selecting-overloaded-signals-and-slots )

                    @JimmyMars said in Connecting signals and slots:

                    But why doesn't it work using function pointers?

                    Because when the slot is an overloaded function, the compiler doesn't know which overload to choose. static_cast or QOverload gives the compiler the information that it needs.

                    In contrast, the string-based connection states exactly which overload to choose: display(int).

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

                    1 Reply Last reply
                    5

                    • Login

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