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. QMetaObject::invokeMethod and SLOT macro: No such method

QMetaObject::invokeMethod and SLOT macro: No such method

Scheduled Pinned Locked Moved Solved General and Desktop
signals&slotsqmetaobjectinvokemethodslot
13 Posts 4 Posters 2.5k 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.
  • C Offline
    C Offline
    candy76041820
    wrote on 5 Aug 2022, 02:41 last edited by candy76041820 8 May 2022, 12:57
    #1

    Qt5:

    class C: public QObject{
        Q_OBJECT
    public slots:
      void F(void);
    };
    
    C c;
    QMetaObject::invokeMethod(&c, "F");//OK
    QMetaObject::invokeMethod(&c, SLOT(F()));//QMetaObject::invokeMethod: No such method C::1F()()
    

    Are QMetaObject::invokeMethod and SLOT macro incompatible?

    WORKAROUND (for this particular scenario):
    To be precise, what I need is invocation of slots connect()ed to signals of another class (we don't want to emit another object's signal even if they are public, do we?), but all I have would be the SLOT string. So a springboard should suffice:

    class Signaller: public QObject{
        Q_OBJECT
    signals:
        void S(void);
    }s;
    class Forwarder: public QObject{
        Q_OBJECT
    public slots:
        void F(void){
            emit this->FS();
        }
    signals:
        void FS(void);
    };
    
    class C; C c;//As defined above
    const char *slot_str;//Its value comes from SLOT(F())
    Forwarder *fwd=new Forwarder();
    fwd->setParent(&c);
    connect(&s, &Signaller::S, fwd, &Forwarder::F);
    connect(fwd, SIGNAL(FS()), &c, slot_str);
    

    Now fwd->F() will do the trick.

    1 Reply Last reply
    0
    • J Offline
      J Offline
      JKSH
      Moderators
      wrote on 5 Aug 2022, 03:02 last edited by
      #2

      Hi, and welcome!

      @candy76041820 said in QMetaObject::invokeMethod and SLOT macro: No such method:

      Are QMetaObject::invokeMethod and SLOT macro incompatible?

      The SLOT() macro is for the old version of QObject::connect(). It is not for QMetaObject::invokeMethod().

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

      1 Reply Last reply
      0
      • C Offline
        C Offline
        candy76041820
        wrote on 5 Aug 2022, 03:05 last edited by
        #3

        So this means I have to make a workaround if the string SLOT returned is the only piece of information I have?

        J 1 Reply Last reply 5 Aug 2022, 04:54
        0
        • C candy76041820
          5 Aug 2022, 03:05

          So this means I have to make a workaround if the string SLOT returned is the only piece of information I have?

          J Offline
          J Offline
          JKSH
          Moderators
          wrote on 5 Aug 2022, 04:54 last edited by
          #4

          @candy76041820 said in QMetaObject::invokeMethod and SLOT macro: No such method:

          So this means I have to make a workaround if the string SLOT returned is the only piece of information I have?

          Sounds like it.

          How do you get the string returned by SLOT()?

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

          C 1 Reply Last reply 5 Aug 2022, 09:29
          0
          • J JKSH
            5 Aug 2022, 04:54

            @candy76041820 said in QMetaObject::invokeMethod and SLOT macro: No such method:

            So this means I have to make a workaround if the string SLOT returned is the only piece of information I have?

            Sounds like it.

            How do you get the string returned by SLOT()?

            C Offline
            C Offline
            candy76041820
            wrote on 5 Aug 2022, 09:29 last edited by
            #5

            @JKSH Isn't it just a plain const char *? Or will it invalidate after subsequent calls?

            1 Reply Last reply
            0
            • S Offline
              S Offline
              SGaist
              Lifetime Qt Champion
              wrote on 5 Aug 2022, 09:39 last edited by
              #6

              Hi,

              What the macro generates is however it's not literally what you pass in that is returned hence the error you got.

              Interested in AI ? www.idiap.ch
              Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

              C 1 Reply Last reply 5 Aug 2022, 09:59
              0
              • S SGaist
                5 Aug 2022, 09:39

                Hi,

                What the macro generates is however it's not literally what you pass in that is returned hence the error you got.

                C Offline
                C Offline
                candy76041820
                wrote on 5 Aug 2022, 09:59 last edited by
                #7

                @SGaist Just thinking that maybe I'll parse the string and take the function name.

                M 1 Reply Last reply 5 Aug 2022, 10:40
                0
                • C candy76041820
                  5 Aug 2022, 09:59

                  @SGaist Just thinking that maybe I'll parse the string and take the function name.

                  M Offline
                  M Offline
                  mpergand
                  wrote on 5 Aug 2022, 10:40 last edited by mpergand 8 May 2022, 10:40
                  #8

                  @candy76041820

                  Here examples of some macros of mine:

                  #define InvokeLater(slot)  QMetaObject::invokeMethod(this, #slot,Qt::QueuedConnection)
                  
                  #define InvokeLaterWithArg(slot,argType,arg)  QMetaObject::invokeMethod(this, #slot,Qt::QueuedConnection,Q_ARG(argType,arg))
                  
                  C 1 Reply Last reply 5 Aug 2022, 13:19
                  0
                  • M mpergand
                    5 Aug 2022, 10:40

                    @candy76041820

                    Here examples of some macros of mine:

                    #define InvokeLater(slot)  QMetaObject::invokeMethod(this, #slot,Qt::QueuedConnection)
                    
                    #define InvokeLaterWithArg(slot,argType,arg)  QMetaObject::invokeMethod(this, #slot,Qt::QueuedConnection,Q_ARG(argType,arg))
                    
                    C Offline
                    C Offline
                    candy76041820
                    wrote on 5 Aug 2022, 13:19 last edited by
                    #9

                    @mpergand Problem is that invokeMethod doesn't recognize what SLOT says.

                    J 1 Reply Last reply 5 Aug 2022, 13:51
                    0
                    • C candy76041820
                      5 Aug 2022, 13:19

                      @mpergand Problem is that invokeMethod doesn't recognize what SLOT says.

                      J Offline
                      J Offline
                      JKSH
                      Moderators
                      wrote on 5 Aug 2022, 13:51 last edited by
                      #10

                      @candy76041820 said in QMetaObject::invokeMethod and SLOT macro: No such method:

                      Problem is that invokeMethod doesn't recognize what SLOT says.

                      I'm still trying to understand why this is a problem.

                      Can you please explain your use-case? How come the SLOT() string is the only piece of information that you have?

                      Isn't it just a plain const char *?

                      Yes, it's a const char*, but it's in the wrong format for invokeMethod().

                      Anyway, my question was: How do you obtain your slot function name?

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

                      C 1 Reply Last reply 5 Aug 2022, 23:15
                      0
                      • J JKSH
                        5 Aug 2022, 13:51

                        @candy76041820 said in QMetaObject::invokeMethod and SLOT macro: No such method:

                        Problem is that invokeMethod doesn't recognize what SLOT says.

                        I'm still trying to understand why this is a problem.

                        Can you please explain your use-case? How come the SLOT() string is the only piece of information that you have?

                        Isn't it just a plain const char *?

                        Yes, it's a const char*, but it's in the wrong format for invokeMethod().

                        Anyway, my question was: How do you obtain your slot function name?

                        C Offline
                        C Offline
                        candy76041820
                        wrote on 5 Aug 2022, 23:15 last edited by candy76041820 8 May 2022, 23:24
                        #11

                        @JKSH Well, the scenario:

                        namespace Helper{
                            class QFileDialogSaveCanceller: public QObject{
                                Q_OBJECT
                            public slots:
                                void Cancel(void){
                                    emit this->Cancelled(QString());
                                }
                            signals:
                                void Cancelled(const QString &empty);
                            }
                            void InvokeQFileDialogSave(QWidget *window, const char *slot/*void(const QString &)*/, .../*filters, default name & extension, etc*/){
                                QFileDialog *dlg=new QFileDialog();//Can't use the static getSaveFileName(), since I want the default extension auto-added
                                QFileDialogSaveCanceller *canceller=new QFileDialogSaveCanceller;
                                canceller->setParent(dlg);
                                connect(canceller, SIGNAL(Cancelled(const QString &)), window, slot); 
                                connect(dlg, &QDialog::rejected, canceller, &QFileDialogSaveCanceller::Cancel);
                                /*connect(dlg, &QDialog::rejected, [window](void)->void{
                                    QMetaObject::invokeMethod(window, slot, Q_ARG(QString()));//No such method
                                });*/
                                dlg->open(window, slot);
                            }
                        }
                        
                        class MainWindow: public QMainWindow{};
                        MainWindow mw;
                        Helper::InvokeQFileDialogSave(&mw, SLOT(FileSelected(const QString &)), ...);
                        

                        I'm just too lazy to template-ize the helper function, neither do I wanna write another "MainWindow::Cancelled(void)" slot to do the forwarding. Tried invokeMethod but no luck, thus this post.

                        J 1 Reply Last reply 6 Aug 2022, 15:30
                        0
                        • C candy76041820
                          5 Aug 2022, 23:15

                          @JKSH Well, the scenario:

                          namespace Helper{
                              class QFileDialogSaveCanceller: public QObject{
                                  Q_OBJECT
                              public slots:
                                  void Cancel(void){
                                      emit this->Cancelled(QString());
                                  }
                              signals:
                                  void Cancelled(const QString &empty);
                              }
                              void InvokeQFileDialogSave(QWidget *window, const char *slot/*void(const QString &)*/, .../*filters, default name & extension, etc*/){
                                  QFileDialog *dlg=new QFileDialog();//Can't use the static getSaveFileName(), since I want the default extension auto-added
                                  QFileDialogSaveCanceller *canceller=new QFileDialogSaveCanceller;
                                  canceller->setParent(dlg);
                                  connect(canceller, SIGNAL(Cancelled(const QString &)), window, slot); 
                                  connect(dlg, &QDialog::rejected, canceller, &QFileDialogSaveCanceller::Cancel);
                                  /*connect(dlg, &QDialog::rejected, [window](void)->void{
                                      QMetaObject::invokeMethod(window, slot, Q_ARG(QString()));//No such method
                                  });*/
                                  dlg->open(window, slot);
                              }
                          }
                          
                          class MainWindow: public QMainWindow{};
                          MainWindow mw;
                          Helper::InvokeQFileDialogSave(&mw, SLOT(FileSelected(const QString &)), ...);
                          

                          I'm just too lazy to template-ize the helper function, neither do I wanna write another "MainWindow::Cancelled(void)" slot to do the forwarding. Tried invokeMethod but no luck, thus this post.

                          J Offline
                          J Offline
                          JKSH
                          Moderators
                          wrote on 6 Aug 2022, 15:30 last edited by JKSH 8 Jun 2022, 15:31
                          #12

                          @candy76041820 said in QMetaObject::invokeMethod and SLOT macro: No such method:

                          I'm just too lazy to template-ize the helper function, neither do I wanna write another "MainWindow::Cancelled(void)" slot to do the forwarding. Tried invokeMethod but no luck, thus this post.

                          That's an interesting setup.

                          You could use function pointers instead of strings:

                          using MySlot = void(QWidget::*)(const QString&);
                          
                          void InvokeQFileDialogSave(QWidget *window, MySlot slot) {
                              auto dlg = new QFileDialog;
                              auto canceller = new QFileDialogSaveCanceller;
                              
                              connect(canceller, &QFileDialogSaveCanceller::Cancelled,
                                      window, slot); 
                          
                              connect(dlg, &QDialog::rejected, [window, slot] {
                                  (window->*slot)( QString() );
                              });
                          
                              // ...
                          }
                          
                          

                          Or, you could use string manipulation to find the slot name.

                          //Can't use the static getSaveFileName(), since I want the default extension auto-added
                          

                          The selectedFilter parameter of getSaveFileName() lets you set the default extension

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

                          C 1 Reply Last reply 7 Aug 2022, 02:43
                          1
                          • J JKSH
                            6 Aug 2022, 15:30

                            @candy76041820 said in QMetaObject::invokeMethod and SLOT macro: No such method:

                            I'm just too lazy to template-ize the helper function, neither do I wanna write another "MainWindow::Cancelled(void)" slot to do the forwarding. Tried invokeMethod but no luck, thus this post.

                            That's an interesting setup.

                            You could use function pointers instead of strings:

                            using MySlot = void(QWidget::*)(const QString&);
                            
                            void InvokeQFileDialogSave(QWidget *window, MySlot slot) {
                                auto dlg = new QFileDialog;
                                auto canceller = new QFileDialogSaveCanceller;
                                
                                connect(canceller, &QFileDialogSaveCanceller::Cancelled,
                                        window, slot); 
                            
                                connect(dlg, &QDialog::rejected, [window, slot] {
                                    (window->*slot)( QString() );
                                });
                            
                                // ...
                            }
                            
                            

                            Or, you could use string manipulation to find the slot name.

                            //Can't use the static getSaveFileName(), since I want the default extension auto-added
                            

                            The selectedFilter parameter of getSaveFileName() lets you set the default extension

                            C Offline
                            C Offline
                            candy76041820
                            wrote on 7 Aug 2022, 02:43 last edited by candy76041820 8 Aug 2022, 01:46
                            #13

                            @JKSH Not applicable because I have other event sink classes.
                            Also, I use the SLOT string because (for the sake of keeping this post clear, I didn't demonstrate that) I have file-open scenarios too: void OnSingleSelect(const QString &file) and void OnMultiSelect(const QStringList &files). They don't share signatures, so either I need to template-ize (which doesn't work well w/ signals&slots), or to repeat and tweak the helper function.
                            Wait: will selectedFilter trigger setDefaultSuffix along with selectNameFilter? Didn't find evidence in the source tree.
                            Also again: Linux Qt 5.6.1, selectedFilter doesn't setDefaultSuffix. Call chain according to https://code.qt.io/cgit/qt/qtbase.git/plain/src/widgets/dialogs/qfiledialog.cpp :
                            QFileDialog::getSaveFileName -> QFileDialog::getSaveFileUrl -> QFileDialog::selectNameFilter -> QFileDialogPrivate::_q_useNameFilter, which doesn't seem to be doing the work (at least, in my case) after the user clicked OK.

                            1 Reply Last reply
                            0

                            1/13

                            5 Aug 2022, 02:41

                            • Login

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