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. new Signal/Slot syntax with parent QWidget?
QtWS25 Last Chance

new Signal/Slot syntax with parent QWidget?

Scheduled Pinned Locked Moved Unsolved General and Desktop
connectsignal & slotsyntaxparent
10 Posts 3 Posters 5.2k 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
    pauledd
    wrote on 27 Aug 2016, 10:46 last edited by pauledd
    #1

    Hi
    I just try to understand how to use the "new" signal & slot syntax in QT.

    I have a simple QWidget that emits "pi" to a promoted subclass widget.
    It works without problem with the old SIGNAL/SLOT syntax. But how to do it with the new?
    I have commented out the working part. The line after it is wrong.
    the code of the promoted widget "myWidget.cpp":

    #include "mywidget.h"
    #include <QDebug>
    #include <QWidget>
    #include <QLabel>
    #include <QVBoxLayout>
    myWidget::myWidget(QWidget *parent) : QWidget(parent)
    {
    	//connect(parent,SIGNAL(send_pi(double)), this, SLOT(showPi(double)));
    	connect(parent, &QWidget::send_pi(double), this, &myWidget::showPi(double));
    	QVBoxLayout *vl = new QVBoxLayout(this);
    	vl->addWidget(pi_label);
    }
    
    void myWidget::showPi(double x){
    	pi_label->setText(QString::number(x));
    }
    
    

    I get the error

    ./test/mywidget.cpp:9:18: error: 'send_pi' is not a member of 'QWidget'
    

    How do I reach the parent widget signal with the new syntax?

    1 Reply Last reply
    0
    • C Offline
      C Offline
      Chris Kawa
      Lifetime Qt Champion
      wrote on 27 Aug 2016, 10:51 last edited by Chris Kawa
      #2

      The new syntax uses pointers to member functions. This means you just give it a pointer and skip the arguments. It also means you need to know the class of the parent:

      connect(parent, &WhateverParentClassIs::send_pi, this, &myWidget::showPi);
      

      You can't use &QWidget::send_pi because QWidget doesn't have such signal.

      1 Reply Last reply
      0
      • P Offline
        P Offline
        pauledd
        wrote on 27 Aug 2016, 11:10 last edited by
        #3

        hmm okay, when I do:

        	qDebug() << "parent=" << this->parent()->metaObject()->className();
        
        

        I get "parent= Widget".

        Then the line should be:

        	connect(parent,&Widget::send_pi, this, &myWidget::showPi);
        
        

        The parent widget should be this one:
        widget.h

        #ifndef WIDGET_H
        #define WIDGET_H
        
        #include <QWidget>
        
        namespace Ui {
        class Widget;
        }
        
        class Widget : public QWidget
        {
        	Q_OBJECT
        	
        public:
        	explicit Widget(QWidget *parent = 0);
        	~Widget();
        	
        private:
        	Ui::Widget *ui;
        signals:
        	void send_pi(double);
        private slots:
        	void on_pushButton_clicked();
        };
        
        #endif // WIDGET_H
        

        widget.cpp

        #include "widget.h"
        #include "ui_widget.h"
        
        Widget::Widget(QWidget *parent) :
        	QWidget(parent),
        	ui(new Ui::Widget)
        {
        	ui->setupUi(this);
        	
        }
        
        Widget::~Widget()
        {
        	delete ui;
        }
        
        void Widget::on_pushButton_clicked()
        {
        	double pi = 3.141;
        	emit send_pi(pi);
        }
        

        and the missing
        myWidget.h

        #ifndef MYWIDGET_H
        #define MYWIDGET_H
        
        #include <QWidget>
        #include <QLabel>
        
        
        class myWidget : public QWidget
        {
        	Q_OBJECT
        public:
        	explicit myWidget(QWidget *parent = 0);
        	
        signals:
        	
        public slots:
        	void showPi(double x);
        private:
        	QLabel *pi_label = new QLabel;
        };
        
        #endif // MYWIDGET_H
        
        

        There is something else wrong.

        1 Reply Last reply
        0
        • C Offline
          C Offline
          Chris Kawa
          Lifetime Qt Champion
          wrote on 27 Aug 2016, 11:22 last edited by Chris Kawa
          #4

          Then the line should be:
          connect(parent,&Widget::send_pi, this, &myWidget::showPi);

          Yup, except parent is a pointer to QWidget in your first code, not to Widget. If you want to use it here you would need to cast it:

          connect(qobject_cast<Widget*>(parent),&Widget::send_pi, this, &myWidget::showPi);
          

          but that is a bad idea. You can't guarantee from within the function what parent will be given as a parameter (unless you change it to Widget* instead of QWidget*).
          This connect statement should really be taken out of myWidget to the code that sees both the objects that are being connected and their types, e.g.:

          Widget foo;
          myWidget bar;
          connect(&foo, &Widget::send_pi, &bar, &myWidget::showPi);
          

          Btw. You should really decide on your naming convention. One class is camel-case other one not, one function uses lowercase and underscores and another camel-case. It's gonna be mighty confusing what is what.

          kshegunovK P 2 Replies Last reply 27 Aug 2016, 11:55
          2
          • C Chris Kawa
            27 Aug 2016, 11:22

            Then the line should be:
            connect(parent,&Widget::send_pi, this, &myWidget::showPi);

            Yup, except parent is a pointer to QWidget in your first code, not to Widget. If you want to use it here you would need to cast it:

            connect(qobject_cast<Widget*>(parent),&Widget::send_pi, this, &myWidget::showPi);
            

            but that is a bad idea. You can't guarantee from within the function what parent will be given as a parameter (unless you change it to Widget* instead of QWidget*).
            This connect statement should really be taken out of myWidget to the code that sees both the objects that are being connected and their types, e.g.:

            Widget foo;
            myWidget bar;
            connect(&foo, &Widget::send_pi, &bar, &myWidget::showPi);
            

            Btw. You should really decide on your naming convention. One class is camel-case other one not, one function uses lowercase and underscores and another camel-case. It's gonna be mighty confusing what is what.

            kshegunovK Offline
            kshegunovK Offline
            kshegunov
            Moderators
            wrote on 27 Aug 2016, 11:55 last edited by
            #5

            @Chris-Kawa said in new Signal/Slot syntax with parent QWidget?:

            Yup, except parent is a pointer to QWidget in your first code, not to Widget. If you want to use it here you would need to cast it:

            connect(qobject_cast<Widget*>(parent),&Widget::send_pi, this, &myWidget::showPi);
            

            Are you sure, Chris? I'm quite convinced any QObject * will do. :)

            Read and abide by the Qt Code of Conduct

            1 Reply Last reply
            0
            • C Offline
              C Offline
              Chris Kawa
              Lifetime Qt Champion
              wrote on 27 Aug 2016, 12:00 last edited by
              #6

              @kshegunov Pretty sure, but you had me doubting for a second there ;) So I checked and sure enough:

              connect(someQObject, &SomeClass::whatever, ...
              

              results in a compile error:

              (...) cannot convert argument1 from `QObject *` to `const SomeClass*`
              
              1 Reply Last reply
              1
              • kshegunovK Offline
                kshegunovK Offline
                kshegunov
                Moderators
                wrote on 27 Aug 2016, 12:01 last edited by
                #7

                Awww, that's upcasting ... :(
                Silly me!

                Read and abide by the Qt Code of Conduct

                1 Reply Last reply
                0
                • C Chris Kawa
                  27 Aug 2016, 11:22

                  Then the line should be:
                  connect(parent,&Widget::send_pi, this, &myWidget::showPi);

                  Yup, except parent is a pointer to QWidget in your first code, not to Widget. If you want to use it here you would need to cast it:

                  connect(qobject_cast<Widget*>(parent),&Widget::send_pi, this, &myWidget::showPi);
                  

                  but that is a bad idea. You can't guarantee from within the function what parent will be given as a parameter (unless you change it to Widget* instead of QWidget*).
                  This connect statement should really be taken out of myWidget to the code that sees both the objects that are being connected and their types, e.g.:

                  Widget foo;
                  myWidget bar;
                  connect(&foo, &Widget::send_pi, &bar, &myWidget::showPi);
                  

                  Btw. You should really decide on your naming convention. One class is camel-case other one not, one function uses lowercase and underscores and another camel-case. It's gonna be mighty confusing what is what.

                  P Offline
                  P Offline
                  pauledd
                  wrote on 27 Aug 2016, 12:22 last edited by
                  #8

                  @Chris-Kawa said in new Signal/Slot syntax with parent QWidget?:

                  This connect statement should really be taken out of myWidget to the code that sees both the objects

                  I have no code that sees both, I will think about that place.

                  Btw. You should really decide on your naming convention. One class is camel-case other one not, one function uses lowercase and underscores and another camel-case. It's gonna be mighty confusing what is what.

                  I absolutely agree and I will work on it.

                  Thank you for the hints. Just one more question. Is the commented out connect line correct in that case? Or is that as well problematic as the new signal/slot syntax?

                  1 Reply Last reply
                  0
                  • C Offline
                    C Offline
                    Chris Kawa
                    Lifetime Qt Champion
                    wrote on 27 Aug 2016, 12:27 last edited by
                    #9

                    connect(parent,SIGNAL(send_pi(double)), this, SLOT(showPi(double)));
                    It might work in your particular case but It has exactly the same general problem i.e. if the parent is not a Widget* there's no such signal and the connection won't work.
                    The difference is that this will compile fine and only silently fail at runtime (with a warning on the output), while the new syntax won't let you even compile this, which is much better because it gives you a chance to fix it right away and not after a user of your app reports a bug :)

                    1 Reply Last reply
                    0
                    • P Offline
                      P Offline
                      pauledd
                      wrote on 27 Aug 2016, 12:34 last edited by
                      #10

                      thanks for the enlightening!

                      1 Reply Last reply
                      0

                      1/10

                      27 Aug 2016, 10:46

                      • Login

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