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. invokeMethod in other thread
Qt 6.11 is out! See what's new in the release blog

invokeMethod in other thread

Scheduled Pinned Locked Moved Unsolved General and Desktop
22 Posts 5 Posters 25.3k Views 2 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.
  • McLionM Offline
    McLionM Offline
    McLion
    wrote on last edited by McLion
    #1

    Hi

    I'm using this to init needed stuff in a worker thread - which works as supposed:

    emit InitLoLaSocket(ip4addr, port, location, name, MAC, loglevel);

    However, this is executed a lot later, whenever the event queue is coming to it.
    I now want to have it execute immediately, and thought that this is the solution:

    QMetaObject::invokeMethod(LoLaWorker, "InitLoLaUDPsocket", Qt::DirectConnection, ip4addr, port, location, name, MAC, loglevel);

    However, this returns expected primary-expression before ',' token and I simply can not see what I'm doing wrong.
    Any idea?
    Thanks, McL

    1 Reply Last reply
    0
    • m.sueM Offline
      m.sueM Offline
      m.sue
      wrote on last edited by
      #2

      Hi,
      in invokeMethod you need to use the Q_ARG functions to marshall the parameters e.g. like this to send a string:

      QString string;
      QMetaObject::invokeMethod(object,"slot",Q_ARG(QString,string));
      

      -Michael.

      1 Reply Last reply
      1
      • McLionM Offline
        McLionM Offline
        McLion
        wrote on last edited by
        #3

        Hi Michael,

        Thanks. Corrected to this:
        QMetaObject::invokeMethod(lolaworker, "InitLoLaUDPsocket", Qt::DirectConnection, Q_ARG(QString, ip4addr), Q_ARG(quint16, port), Q_ARG(QString, location), Q_ARG(QString, name), Q_ARG(QString, MAC), Q_ARG(QString, loglevel));

        Any idea if nothing at all happens now?

        m.sueM 1 Reply Last reply
        0
        • VRoninV Offline
          VRoninV Offline
          VRonin
          wrote on last edited by
          #4

          why don't you just call lolaworker->InitLoLaUDPsocket instead of using invokeMethod?

          "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
          ~Napoleon Bonaparte

          On a crusade to banish setIndexWidget() from the holy land of Qt

          1 Reply Last reply
          0
          • McLionM Offline
            McLionM Offline
            McLion
            wrote on last edited by
            #5

            @VRonin

            Because this builds correctly, but generates a signal 11 crash.

            jsulmJ 1 Reply Last reply
            0
            • McLionM McLion

              @VRonin

              Because this builds correctly, but generates a signal 11 crash.

              jsulmJ Offline
              jsulmJ Offline
              jsulm
              Lifetime Qt Champion
              wrote on last edited by
              #6

              @McLion Are you sure this invokeMethod() call is executed?

              https://forum.qt.io/topic/113070/qt-code-of-conduct

              1 Reply Last reply
              0
              • McLionM McLion

                Hi Michael,

                Thanks. Corrected to this:
                QMetaObject::invokeMethod(lolaworker, "InitLoLaUDPsocket", Qt::DirectConnection, Q_ARG(QString, ip4addr), Q_ARG(quint16, port), Q_ARG(QString, location), Q_ARG(QString, name), Q_ARG(QString, MAC), Q_ARG(QString, loglevel));

                Any idea if nothing at all happens now?

                m.sueM Offline
                m.sueM Offline
                m.sue
                wrote on last edited by m.sue
                #7

                @McLion said in invokeMethod in other thread:

                Any idea if nothing at all happens now?

                There can happen many things:

                • you did not add Q_OBJECT to the class declaration
                • InitLoLaUDPsocket is not in the slots section of the class
                • a typo in the slot name e.g. the original slot was InitLoLaSocket
                • you did not use the correct signature of the parameter e.g. forgot * or & or used a wrong type
                • LoLaWorker has an invalid address
                • maybe more...

                You can always debug into invokeMethod to get a hint about what it is that does not work.
                -Michael.

                1 Reply Last reply
                0
                • McLionM Offline
                  McLionM Offline
                  McLion
                  wrote on last edited by
                  #8

                  @jsulm
                  Yes.

                  @m-sue

                  • class LoLaWorker : public QObject
                    {
                    Q_OBJECT

                  • public slots:
                    void InitLoLaThread();
                    void InitLoLaUDPsocket(QString qsIP4addr, quint16 uiPort, QString qsLocation, QString qsName, QString qsMAC, QString qsLogLevel);

                  • InitLoLaSocket is the signal of the emitting class whereas InitLoLaUDPsocket is the slot of the target class running in another thread.

                  • still thinking about the others ...

                  1 Reply Last reply
                  0
                  • m.sueM Offline
                    m.sueM Offline
                    m.sue
                    wrote on last edited by
                    #9

                    As said, I would debug into invokeMethod and make sure the function InitLoLaUDPsocket with the given list of parameters gets found in the list (or hash(?)) of slots and signals of LoLaWorker.

                    McLionM 1 Reply Last reply
                    0
                    • m.sueM m.sue

                      As said, I would debug into invokeMethod and make sure the function InitLoLaUDPsocket with the given list of parameters gets found in the list (or hash(?)) of slots and signals of LoLaWorker.

                      McLionM Offline
                      McLionM Offline
                      McLion
                      wrote on last edited by
                      #10

                      @m.sue said in invokeMethod in other thread:

                      As said, I would debug into invokeMethod and make sure the function InitLoLaUDPsocket with the given list of parameters gets found in the list (or hash(?)) of slots and signals of LoLaWorker.

                      I don't have a debugger on my eLinux Target.

                      1 Reply Last reply
                      0
                      • VRoninV Offline
                        VRoninV Offline
                        VRonin
                        wrote on last edited by
                        #11

                        invokemethod with direct connection is basically the same as a direct call to the method so I'd investigate why it generates a crash

                        "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                        ~Napoleon Bonaparte

                        On a crusade to banish setIndexWidget() from the holy land of Qt

                        1 Reply Last reply
                        1
                        • McLionM Offline
                          McLionM Offline
                          McLion
                          wrote on last edited by
                          #12

                          The invokeMethod now calls it the same as the direct call - To be honest, I have no clue why the call works today - maybe the full rebuild did the trick ... and overnight ... ;-)
                          However, it still crashes.
                          Isn't calling this in a different thread the issue? Or I have some other issue - some code segments follow. I'm creating everything in the constructor of the mainwindow:

                          // start a new thread and put the LoLaWorker to it
                            bLoLaIsInitiated = false;
                            QThread* lolathread = new QThread;
                            LoLaWorker* lolaworker = new LoLaWorker();
                            lolaworker->moveToThread(lolathread);
                            connect(lolathread, SIGNAL(started()), lolaworker, SLOT(InitLoLaThread()));
                            lolathread->start();
                          ... some more connects here
                          

                          I have #include "LoLaWorkerThread.h" and LoLaWorker *lolaworker; public in header of mainwindow and I am calling

                          QMetaObject::invokeMethod(lolaworker, "InitLoLaUDPsocket", Qt::DirectConnection, 
                                                    Q_ARG(QString, ip4addr),
                                                    Q_ARG(quint16, port),
                                                    Q_ARG(QString, location),
                                                    Q_ARG(QString, name),
                                                    Q_ARG(QString, MAC),
                                                    Q_ARG(QString, loglevel));
                          

                          When emitting the signal everything works - just not immediate, which is what I need.

                          I suspect I'm doing something wrong. Any ideas?
                          Thanks
                          McL

                          kshegunovK 1 Reply Last reply
                          0
                          • McLionM McLion

                            The invokeMethod now calls it the same as the direct call - To be honest, I have no clue why the call works today - maybe the full rebuild did the trick ... and overnight ... ;-)
                            However, it still crashes.
                            Isn't calling this in a different thread the issue? Or I have some other issue - some code segments follow. I'm creating everything in the constructor of the mainwindow:

                            // start a new thread and put the LoLaWorker to it
                              bLoLaIsInitiated = false;
                              QThread* lolathread = new QThread;
                              LoLaWorker* lolaworker = new LoLaWorker();
                              lolaworker->moveToThread(lolathread);
                              connect(lolathread, SIGNAL(started()), lolaworker, SLOT(InitLoLaThread()));
                              lolathread->start();
                            ... some more connects here
                            

                            I have #include "LoLaWorkerThread.h" and LoLaWorker *lolaworker; public in header of mainwindow and I am calling

                            QMetaObject::invokeMethod(lolaworker, "InitLoLaUDPsocket", Qt::DirectConnection, 
                                                      Q_ARG(QString, ip4addr),
                                                      Q_ARG(quint16, port),
                                                      Q_ARG(QString, location),
                                                      Q_ARG(QString, name),
                                                      Q_ARG(QString, MAC),
                                                      Q_ARG(QString, loglevel));
                            

                            When emitting the signal everything works - just not immediate, which is what I need.

                            I suspect I'm doing something wrong. Any ideas?
                            Thanks
                            McL

                            kshegunovK Offline
                            kshegunovK Offline
                            kshegunov
                            Moderators
                            wrote on last edited by
                            #13

                            @McLion said in invokeMethod in other thread:

                            QMetaObject::invokeMethod(lolaworker, "InitLoLaUDPsocket", Qt::DirectConnection, ...
                            

                            This is a race condition if you're calling this from a thread different than lolathread .

                            If you want something to be called first in a thread post the event to the object immediately after moving it to the thread (i.e. it becomes the first event) and don't use direct connection across threads if you don't provide manual access serialization.

                                // ...
                                lolaworker->moveToThread(lolathread);
                                // What's wrong with this?
                                QMetaObject::invokeMethod(lolaworker, "InitLoLaUDPsocket", Qt::QueuedConnection, ... );
                                // And ... start the event processing
                                lolathread->start();
                            

                            Read and abide by the Qt Code of Conduct

                            McLionM 1 Reply Last reply
                            2
                            • kshegunovK kshegunov

                              @McLion said in invokeMethod in other thread:

                              QMetaObject::invokeMethod(lolaworker, "InitLoLaUDPsocket", Qt::DirectConnection, ...
                              

                              This is a race condition if you're calling this from a thread different than lolathread .

                              If you want something to be called first in a thread post the event to the object immediately after moving it to the thread (i.e. it becomes the first event) and don't use direct connection across threads if you don't provide manual access serialization.

                                  // ...
                                  lolaworker->moveToThread(lolathread);
                                  // What's wrong with this?
                                  QMetaObject::invokeMethod(lolaworker, "InitLoLaUDPsocket", Qt::QueuedConnection, ... );
                                  // And ... start the event processing
                                  lolathread->start();
                              
                              McLionM Offline
                              McLionM Offline
                              McLion
                              wrote on last edited by McLion
                              #14

                              @kshegunov
                              Sorry for the delay ... was called off to work on some other software.

                              OK, I moved the moveToThread and the start from the constructor to the function where the initialization takes place (when, at runtime, I got the parameters needed), as suggested to try.

                              This gives me a crash at runtime (signal 11 - sigsegv - invalid memory reference).

                              1 Reply Last reply
                              0
                              • VRoninV Offline
                                VRoninV Offline
                                VRonin
                                wrote on last edited by
                                #15

                                that's segmentation fault... did you try debugging your code?

                                "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                                ~Napoleon Bonaparte

                                On a crusade to banish setIndexWidget() from the holy land of Qt

                                McLionM 1 Reply Last reply
                                0
                                • VRoninV VRonin

                                  that's segmentation fault... did you try debugging your code?

                                  McLionM Offline
                                  McLionM Offline
                                  McLion
                                  wrote on last edited by
                                  #16

                                  @VRonin
                                  Working on Windows, compiling on/for Linux as well, running on eLinux device with no debugger.

                                  1 Reply Last reply
                                  0
                                  • VRoninV Offline
                                    VRoninV Offline
                                    VRonin
                                    wrote on last edited by
                                    #17

                                    Can you compile for windows just for debug? or run a linux virtual machine to debug it?

                                    I'm sorry to be this useless but that error is quite generic. Main things to investigate:

                                    • Are you accessing an object through a pointer before creating it (calling new)?
                                    • Are you accessing an object through a pointer after it was deleted?
                                    • Are you trying to access a null pointer?

                                    "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                                    ~Napoleon Bonaparte

                                    On a crusade to banish setIndexWidget() from the holy land of Qt

                                    McLionM 1 Reply Last reply
                                    0
                                    • VRoninV VRonin

                                      Can you compile for windows just for debug? or run a linux virtual machine to debug it?

                                      I'm sorry to be this useless but that error is quite generic. Main things to investigate:

                                      • Are you accessing an object through a pointer before creating it (calling new)?
                                      • Are you accessing an object through a pointer after it was deleted?
                                      • Are you trying to access a null pointer?
                                      McLionM Offline
                                      McLionM Offline
                                      McLion
                                      wrote on last edited by McLion
                                      #18

                                      @VRonin
                                      Thanks for trying to help!

                                      As far as I can tell everything is ok.

                                      in constructor of qtgui mainwindow:

                                      QThread* lolathread = new QThread;
                                      LoLaWorker* lolaworker = new LoLaWorker();
                                      connect(lolathread, SIGNAL(started()), lolaworker, SLOT(InitLoLaThread()));
                                      connect(this, SIGNAL(TerminateLoLa()), lolaworker, SLOT(TerminateLoLaUDPsocket()));
                                      .. and some more conects
                                      

                                      later, in function LoLaInit:

                                      lolaworker->moveToThread(lolathread);
                                      QMetaObject::invokeMethod(lolaworker, "InitLoLaUDPsocket", Qt::QueuedConnection, Q_ARG(QString, ip4addr), Q_ARG(quint16, port), Q_ARG(QString, location), Q_ARG(QString, name), Q_ARG(QString, MAC), Q_ARG(QString, loglevel));
                                      lolathread->start();
                                      

                                      Anyhow, if moveToThread and start the thread are in the constructor and later emit a signal only, everything works, despite the fact that it is not immediate.

                                      I start to believe that what I want is not possible.
                                      I just want to have it to execute this function immediately (switching threads or whatever is needed) and following it up where it has left later (there is a queue of commands that now are worked off first, unfortunately).

                                      1 Reply Last reply
                                      0
                                      • VRoninV Offline
                                        VRoninV Offline
                                        VRonin
                                        wrote on last edited by
                                        #19

                                        I just want to have it to execute this function immediately

                                        Then just call the function from the main thread. invokeMethod with direct connection will execute it in the calling thread anyway so I still stuggle to understand why you are doing what you are doing

                                        "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                                        ~Napoleon Bonaparte

                                        On a crusade to banish setIndexWidget() from the holy land of Qt

                                        McLionM 1 Reply Last reply
                                        0
                                        • VRoninV VRonin

                                          I just want to have it to execute this function immediately

                                          Then just call the function from the main thread. invokeMethod with direct connection will execute it in the calling thread anyway so I still stuggle to understand why you are doing what you are doing

                                          McLionM Offline
                                          McLionM Offline
                                          McLion
                                          wrote on last edited by
                                          #20

                                          @VRonin said in invokeMethod in other thread:

                                          Then just call the function from the main thread. invokeMethod with direct connection will execute it in the calling thread anyway so I still stuggle to understand why you are doing what you are doing

                                          I tried to do this - to no avail. It may well be that it's me that is doing something wrong.

                                          The debug console actually shows that it seems to really directly call the functions in the other thread. However, it also ends up in a strange behavior on the debug console - dbg strings already written out are written out again - and then I again get a seg fault crash.

                                          There are 3 threads: gui-main, serial and lola. I want the following to happen

                                          • serial gets parameters for lola-init and emit to gui-main (master cmd-interpreter)
                                          • gui-main initializes lola (works with emit, but not immediately)
                                          • lola tells gui-main success or not (works with emit, but not immediately)

                                          When I replace the 2 emit with direct calls, I get the crash.
                                          Maybe I'm doing something wrong .. or if what I want is not possible I'll think about a different approach/solution.
                                          Thanks anyway.

                                          kshegunovK 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