Qt Forum

    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    • Unsolved

    Call for Presentations - Qt World Summit

    Solved Connecting to statusBar()->showMessage gives compile time error in new syntax

    General and Desktop
    6
    16
    543
    Loading More Posts
    • 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.
    • S
      sandro4912 last edited by sandro4912

      I have an old example in qt4 were a class has this connection to statusBar() of QMainWindow:

          connect(&thread, SIGNAL(transactionStarted(const QString &)),
                  statusBar(), SLOT(showMessage(const QString &)));
      

      However when i change to the new compile time syntax in qt5 :

      connect(&thread, &TransactionThread::transactionStarted ,
                  statusBar(), &QStatusBar::showMessage);
      

      It gives me this compile time error:

      /home/sandro/Qt/5.13.0/gcc_64/include/QtCore/qobject.h:-1:
      In instantiation of ‘static QMetaObject::Connection QObject::connect(const typename QtPrivate::FunctionPointer<Func>::Object*, Func1, const typename QtPrivate::FunctionPointer<Func2>::Object*, Func2, Qt::ConnectionType) [with Func1 = void (TransactionThread::)(const QString&); Func2 = void (QStatusBar::)(const QString&, int); typename QtPrivate::FunctionPointer<Func>::Object = TransactionThread; typename QtPrivate::FunctionPointer<Func2>::Object = QStatusBar]’:

      Is it because the slot of QStatusBar has an additional int parameter?

      [slot] void QStatusBar::showMessage(const QString &message, int timeout = 0)
      

      I thought the int gets ignored because it has a default parameter

      raven-worx 1 Reply Last reply Reply Quote 0
      • Christian Ehrlicher
        Christian Ehrlicher Lifetime Qt Champion last edited by

        @sandro4912 said in Connecting to statusBar()->showMessage gives compile time error in new syntax:

        I thought the int gets ignored because it has a default parameter

        No, not in the new syntax - it's not possible there. You have to use a lambda

        Qt has to stay free or it will die.

        1 Reply Last reply Reply Quote 4
        • raven-worx
          raven-worx Moderators @sandro4912 last edited by

          @sandro4912
          https://doc.qt.io/qt-5/signalsandslots-syntaxes.html#using-default-parameters-in-slots-to-connect-to-signals-with-fewer-parameters

          --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
          If you have a question please use the forum so others can benefit from the solution in the future

          1 Reply Last reply Reply Quote 6
          • S
            sandro4912 last edited by

            i also thought about the lambda but how to pass the string send from transactionStarted to statusBar()->showMessage().

            connect(&thread, &TransactionThread::transactionStarted, [=]
                {
                    statusBar()->showMessage();  // how to enter the text send with transactionStarted?
                });
            
            JonB 1 Reply Last reply Reply Quote 0
            • JonB
              JonB @sandro4912 last edited by JonB

              @sandro4912
              I'm throwing my hat in because I'm not C++, but don't you do that by specifying the lambda as:

              connect(&thread, &TransactionThread::transactionStarted, [=](const QString &text)
                  {
                      statusBar()->showMessage(text);  // how to enter the text send with transactionStarted?
                  });
              
              
              O J.Hilk 2 Replies Last reply Reply Quote 2
              • O
                ofmrew @JonB last edited by

                @jonb

                Here is a lambda I use to create a QString for statusBar:

                    connect(ui->unitVector, &QPushButton::clicked, [=](){
                                                                ui->canvas->go.setFlagAndResetAngle(4);
                                                                QString s;
                                                                s.append("Rotation about Unit Vector ");
                                                                s.append(ui->canvas->go.uv.toString());
                                                                ui->statusBar->showMessage(s, 0);});
                
                JonB 1 Reply Last reply Reply Quote 0
                • JonB
                  JonB @ofmrew last edited by

                  @ofmrew
                  But @sandro4912 is asking

                  how to pass the string send from transactionStarted to statusBar()->showMessage()

                  hence my suggestion; how is yours to do with passing a parameter on to the lambda??

                  1 Reply Last reply Reply Quote 0
                  • J.Hilk
                    J.Hilk Moderators @JonB last edited by

                    @jonb said in Connecting to statusBar()->showMessage gives compile time error in new syntax:

                    @sandro4912
                    I'm throwing my hat in because I'm not C++, but don't you do that by specifying the lambda as:

                    connect(&thread, &TransactionThread::transactionStarted, [=](const QString &text)
                        {
                            statusBar()->showMessage(text);  // how to enter the text send with transactionStarted?
                        });
                    
                    

                    absolutely correct!👍
                    just one caveat, you can, but you shall not omit the return type

                    connect(&thread, &TransactionThread::transactionStarted, [=](const QString &text)->void{});
                    

                    Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct

                    Qt Needs YOUR vote: https://bugreports.qt.io/browse/QTQAINFRA-4121


                    Q: What's that?
                    A: It's blue light.
                    Q: What does it do?
                    A: It turns blue.

                    JonB 1 Reply Last reply Reply Quote 3
                    • JonB
                      JonB @J.Hilk last edited by JonB

                      @j-hilk
                      So now C++ has found another use for ->! And I assume the [=] is an array holding this as the context or something, is that a special meaning for the =?

                      I realize this isn't the place for long discussion, but ISTM with these lambdas C++ is using a lot of cryptic symbols all together!

                      J.Hilk 1 Reply Last reply Reply Quote 1
                      • S
                        sandro4912 last edited by sandro4912

                        @jonb said in Connecting to statusBar()->showMessage gives compile time error in new syntax:

                        [=]

                        [=] means that all the variables / objects are also available in the lamda body for usage. you can also specify there just a single variable from the outside.

                        for more see this: https://de.cppreference.com/w/cpp/language/lambda

                        the -> you can also use it for normal functions now hence its not that common.

                        for example int somefunction(); becomes auto someFunction() -> int

                        Anyway guys thanks for the solution

                        1 Reply Last reply Reply Quote 2
                        • J.Hilk
                          J.Hilk Moderators @JonB last edited by

                          @jonb
                          well, i‘m not sure what exactly the compiler does, but I assume you‘re on the right path:

                          [&epsilon] capture by reference
                          [&] captures all variables used in the lambda by reference
                          [=] captures all variables used in the lambda by value
                          [&, epsilon] captures variables like with [&], but epsilon by value
                          [=, &epsilon] captures variables like with [=], but epsilon by reference

                          which makes this lambda actually dangerous as the statusbar could be deleted at any time, qt offers a solution for this:

                          connect(&thread, &TransactionThread::transactionStarted, statusbar, [=](const QString &text)->void{});
                          

                          the connect get becomes resolved, when statusbar gets deleted

                          but from the naming of the variables I would say that the emitter is actually in a different thread compared to statusbar.

                          I‘m not sure how Qt handles this with a Lambda, probably not good, therefore 5th connect paramater is probably a good idea

                          connect(&thread, &TransactionThread::transactionStarted, statusbar, [=](const QString &text)->void{},Qt::QueuedConnection);
                          

                          Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct

                          Qt Needs YOUR vote: https://bugreports.qt.io/browse/QTQAINFRA-4121


                          Q: What's that?
                          A: It's blue light.
                          Q: What does it do?
                          A: It turns blue.

                          O 1 Reply Last reply Reply Quote 3
                          • O
                            ofmrew @J.Hilk last edited by

                            @j-hilk
                            I knew that I had seen this before, try link text

                            1 Reply Last reply Reply Quote 0
                            • S
                              sandro4912 last edited by

                              i tryed to add a fifth parameter like you said:

                                  connect(&thread, &TransactionThread::transactionStarted, 
                                          [=](const QString &text)->void
                                  {
                                      statusBar()->showMessage(text);  
                                  }, Qt::QueuedConnection);
                              

                              Unfortunatey the syntax is not working with lambda.

                              And yes you are right. In the MainWindow were the statusBar is there is thread launced for taskes to be computed in a second thread.

                              JonB 1 Reply Last reply Reply Quote 0
                              • JonB
                                JonB @sandro4912 last edited by JonB

                                @sandro4912

                                i tryed to add a fifth parameter like you said:

                                Count your parameters, you only have 4!
                                Look at @J-Hilk 's code, see what you've missed....

                                O 1 Reply Last reply Reply Quote 2
                                • O
                                  ofmrew @JonB last edited by

                                  @jonb

                                  Note that the st in [this](const QString& st) is the name of the string that is the argument of the signal, which I use in {this->ui->statusBar->showMessage(st, 0);}

                                  O 1 Reply Last reply Reply Quote 0
                                  • O
                                    ofmrew @ofmrew last edited by

                                    @ofmrew
                                    Try this example: ```
                                    void canvasResized(QString s);
                                    QString st = "It opened";
                                    emit canvasResized(st);
                                    connect(ui->canvas, &MyCanvas::canvasResized, [this](const QString& st){this->ui->statusBar->showMessage(st, 0);});

                                    I added the emit to the resizeEvent and it worked.
                                    1 Reply Last reply Reply Quote 0
                                    • First post
                                      Last post