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. How to connect "menu action" with existing slot programatically
QtWS25 Last Chance

How to connect "menu action" with existing slot programatically

Scheduled Pinned Locked Moved Solved General and Desktop
11 Posts 3 Posters 3.6k 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.
  • ademmlerA Offline
    ademmlerA Offline
    ademmler
    wrote on last edited by ademmler
    #1

    Hi qt pros.

    I try to add a menu entry programatically and connect this one with a slot.
    I get the menu entry - but when I trigger the entry nothing happens.
    pls give me a hint what's wrong in my code. thx in advance.

      QFileInfo fi(fileName);
            recentFileList.append(fileName);
    
            QAction* recentFileAction = new QAction(this);
    
            recentFileAction->setText(fi.baseName() +"."+ fi.suffix());
            recentFileAction->setData(fileName);
            recentFileAction->setEnabled(true);
    
            ui->recentFilesMenu->addAction(recentFileAction);
            ui->recentFilesMenu->update();
    
            QObject::connect(recentFileAction, SIGNAL(&QAction::triggered),
                             this, SLOT(slotOpenRecentFile()));
    
    JonBJ B 3 Replies Last reply
    0
    • ademmlerA ademmler

      Hi qt pros.

      I try to add a menu entry programatically and connect this one with a slot.
      I get the menu entry - but when I trigger the entry nothing happens.
      pls give me a hint what's wrong in my code. thx in advance.

        QFileInfo fi(fileName);
              recentFileList.append(fileName);
      
              QAction* recentFileAction = new QAction(this);
      
              recentFileAction->setText(fi.baseName() +"."+ fi.suffix());
              recentFileAction->setData(fileName);
              recentFileAction->setEnabled(true);
      
              ui->recentFilesMenu->addAction(recentFileAction);
              ui->recentFilesMenu->update();
      
              QObject::connect(recentFileAction, SIGNAL(&QAction::triggered),
                               this, SLOT(slotOpenRecentFile()));
      
      JonBJ Offline
      JonBJ Offline
      JonB
      wrote on last edited by JonB
      #2

      @ademmler
      Looks fine to me. Show slotOpenRecentFile(), and put in a qDebug() to prove it's not being fired.

      Please consider moving over to signal/slot new style syntax, it will make life/error checking easier.

      1 Reply Last reply
      0
      • ademmlerA ademmler

        Hi qt pros.

        I try to add a menu entry programatically and connect this one with a slot.
        I get the menu entry - but when I trigger the entry nothing happens.
        pls give me a hint what's wrong in my code. thx in advance.

          QFileInfo fi(fileName);
                recentFileList.append(fileName);
        
                QAction* recentFileAction = new QAction(this);
        
                recentFileAction->setText(fi.baseName() +"."+ fi.suffix());
                recentFileAction->setData(fileName);
                recentFileAction->setEnabled(true);
        
                ui->recentFilesMenu->addAction(recentFileAction);
                ui->recentFilesMenu->update();
        
                QObject::connect(recentFileAction, SIGNAL(&QAction::triggered),
                                 this, SLOT(slotOpenRecentFile()));
        
        B Offline
        B Offline
        Bonnie
        wrote on last edited by
        #3

        @ademmler
        Your syntax is wrong, either

        QObject::connect(recentFileAction, SIGNAL(triggered()), this, SLOT(slotOpenRecentFile()));
        

        or

        QObject::connect(recentFileAction, &QAction::triggered, this, &YourCurrentClass::slotOpenRecentFile);
        
        ademmlerA 1 Reply Last reply
        3
        • ademmlerA ademmler

          Hi qt pros.

          I try to add a menu entry programatically and connect this one with a slot.
          I get the menu entry - but when I trigger the entry nothing happens.
          pls give me a hint what's wrong in my code. thx in advance.

            QFileInfo fi(fileName);
                  recentFileList.append(fileName);
          
                  QAction* recentFileAction = new QAction(this);
          
                  recentFileAction->setText(fi.baseName() +"."+ fi.suffix());
                  recentFileAction->setData(fileName);
                  recentFileAction->setEnabled(true);
          
                  ui->recentFilesMenu->addAction(recentFileAction);
                  ui->recentFilesMenu->update();
          
                  QObject::connect(recentFileAction, SIGNAL(&QAction::triggered),
                                   this, SLOT(slotOpenRecentFile()));
          
          JonBJ Offline
          JonBJ Offline
          JonB
          wrote on last edited by JonB
          #4

          @ademmler
          Ah, yes, @Bonnie spotted it. You were mixing new & old style syntax attempt.

          Like I said, if you would change to the new style syntax as per his second solution --- don't ever use SIGNAL/SLOT() macros and runtime behaviour --- you would have received a compile-time error and wouldn't have had to ask this question at all....

          1 Reply Last reply
          0
          • B Bonnie

            @ademmler
            Your syntax is wrong, either

            QObject::connect(recentFileAction, SIGNAL(triggered()), this, SLOT(slotOpenRecentFile()));
            

            or

            QObject::connect(recentFileAction, &QAction::triggered, this, &YourCurrentClass::slotOpenRecentFile);
            
            ademmlerA Offline
            ademmlerA Offline
            ademmler
            wrote on last edited by ademmler
            #5

            @Bonnie
            Both suggestion are working perfectly - thx to you !!!

            @JonB
            Thx for clarification

            JonBJ 1 Reply Last reply
            0
            • ademmlerA ademmler

              @Bonnie
              Both suggestion are working perfectly - thx to you !!!

              @JonB
              Thx for clarification

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

              @ademmler
              Purely OOI, with your original SIGNAL(&QAction::triggered) didn't you receive a runtime warning message (stderr, or debugger console) when it executed that connect()?

              EDIT Ah, from https://doc.qt.io/qt-5/qobject.html#connect:

              The function returns a QMetaObject::Connection that represents a handle to a connection if it successfully connects the signal to the slot. The connection handle will be invalid if it cannot create the connection, for example, if QObject is unable to verify the existence of either signal or method, or if their signatures aren't compatible. You can check if the handle is valid by casting it to a bool.

              So the connect() return result should have told you it was invalid, and it's your responsibility to check, certainly if you're using the macros.

              This has inspired me to raise question https://forum.qt.io/topic/118029/connect-new-style-syntax-return-result ....

              ademmlerA 1 Reply Last reply
              0
              • JonBJ JonB

                @ademmler
                Purely OOI, with your original SIGNAL(&QAction::triggered) didn't you receive a runtime warning message (stderr, or debugger console) when it executed that connect()?

                EDIT Ah, from https://doc.qt.io/qt-5/qobject.html#connect:

                The function returns a QMetaObject::Connection that represents a handle to a connection if it successfully connects the signal to the slot. The connection handle will be invalid if it cannot create the connection, for example, if QObject is unable to verify the existence of either signal or method, or if their signatures aren't compatible. You can check if the handle is valid by casting it to a bool.

                So the connect() return result should have told you it was invalid, and it's your responsibility to check, certainly if you're using the macros.

                This has inspired me to raise question https://forum.qt.io/topic/118029/connect-new-style-syntax-return-result ....

                ademmlerA Offline
                ademmlerA Offline
                ademmler
                wrote on last edited by
                #7

                @JonB I did not got a runtime error.

                Honestly I am really get confused by "old" and new" syntax and different styles of slots/signals ...
                I have read this: https://wiki.qt.io/New_Signal_Slot_Syntax but still its a miracle to me.

                Would you tell me how to get informations like about the calling action (name, title, data) in the slot I call?

                JonBJ 1 Reply Last reply
                0
                • ademmlerA ademmler

                  @JonB I did not got a runtime error.

                  Honestly I am really get confused by "old" and new" syntax and different styles of slots/signals ...
                  I have read this: https://wiki.qt.io/New_Signal_Slot_Syntax but still its a miracle to me.

                  Would you tell me how to get informations like about the calling action (name, title, data) in the slot I call?

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

                  @ademmler
                  I edited my post above, when I came across that the connect() will have returned a "false" result at runtime which is your job to test, rather than issuing an error message.

                  I don't know why you are confused, I find that link easy to understand. Look at @Bonnie's two different ways, and compare to your original "mixed" way. Simple rule: do not ever use SIGNAL() or SLOT() macros! It won't compile till you have it right in your code then.

                  Would you tell me how to get informations like about the calling action (name, title, data) in the slot I call?

                  If you mean you need to know the actual QAction, or some extra parameters from it, in the slot, for whatever purpose, you will want to use a C++ lambda for your slot, so that you can pass extra parameters to your method. In that link they show an example:

                  connect(
                      sender, &Sender::valueChanged,
                      [=]( const QString &newValue ) { receiver->updateValue( "senderValue", newValue ); }
                  );
                  

                  Maybe also look at https://forum.qt.io/topic/96163/lambda-that-uses-signal-argument-to-connect-to-a-slot. Also an example in https://doc.qt.io/qt-5/signalsandslots.html#signals-and-slots-with-default-arguments

                  I know it looks a bit hairy, but this is what a C++ lambda looks like. You'll have to read up or look at other examples till you get the hang of it.

                  ademmlerA 1 Reply Last reply
                  0
                  • JonBJ JonB

                    @ademmler
                    I edited my post above, when I came across that the connect() will have returned a "false" result at runtime which is your job to test, rather than issuing an error message.

                    I don't know why you are confused, I find that link easy to understand. Look at @Bonnie's two different ways, and compare to your original "mixed" way. Simple rule: do not ever use SIGNAL() or SLOT() macros! It won't compile till you have it right in your code then.

                    Would you tell me how to get informations like about the calling action (name, title, data) in the slot I call?

                    If you mean you need to know the actual QAction, or some extra parameters from it, in the slot, for whatever purpose, you will want to use a C++ lambda for your slot, so that you can pass extra parameters to your method. In that link they show an example:

                    connect(
                        sender, &Sender::valueChanged,
                        [=]( const QString &newValue ) { receiver->updateValue( "senderValue", newValue ); }
                    );
                    

                    Maybe also look at https://forum.qt.io/topic/96163/lambda-that-uses-signal-argument-to-connect-to-a-slot. Also an example in https://doc.qt.io/qt-5/signalsandslots.html#signals-and-slots-with-default-arguments

                    I know it looks a bit hairy, but this is what a C++ lambda looks like. You'll have to read up or look at other examples till you get the hang of it.

                    ademmlerA Offline
                    ademmlerA Offline
                    ademmler
                    wrote on last edited by
                    #9

                    @JonB

                    thx for your help again. I will have a look at it.

                    in the meantime I found this solution:

                    QObject* obj = sender();
                    QAction *action = qobject_cast<QAction *>(obj);
                    QString data = action->data().toString();
                    qDebug() <<"Action data: " << data;

                    JonBJ 1 Reply Last reply
                    0
                    • ademmlerA ademmler

                      @JonB

                      thx for your help again. I will have a look at it.

                      in the meantime I found this solution:

                      QObject* obj = sender();
                      QAction *action = qobject_cast<QAction *>(obj);
                      QString data = action->data().toString();
                      qDebug() <<"Action data: " << data;

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

                      @ademmler
                      I know! But using sender() was really the only way to do it without using lambdas. I know it looks easier, but it's "naughty" :) I'm sure there will be references to this over the web. And actually it (quite possibly) will not work if the connection is using lambda. (And if you're not the only programmer you don't know how other people are doing their connect()s to your slot.)

                      As you please, but getting into the habit of using the lambda approach is better than sender(). Also you can do quite different things (pass different parameters, which you could not otherwise access) via lambda which you cannot via sender(). "Trust Me" ;-)

                      ademmlerA 1 Reply Last reply
                      0
                      • JonBJ JonB

                        @ademmler
                        I know! But using sender() was really the only way to do it without using lambdas. I know it looks easier, but it's "naughty" :) I'm sure there will be references to this over the web. And actually it (quite possibly) will not work if the connection is using lambda. (And if you're not the only programmer you don't know how other people are doing their connect()s to your slot.)

                        As you please, but getting into the habit of using the lambda approach is better than sender(). Also you can do quite different things (pass different parameters, which you could not otherwise access) via lambda which you cannot via sender(). "Trust Me" ;-)

                        ademmlerA Offline
                        ademmlerA Offline
                        ademmler
                        wrote on last edited by
                        #11

                        @JonB I trust you and try this out - thx

                        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