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. Standard C++ callbacks handling inside Qt application

Standard C++ callbacks handling inside Qt application

Scheduled Pinned Locked Moved Solved General and Desktop
17 Posts 6 Posters 3.8k Views 3 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.
  • DragoonD Offline
    DragoonD Offline
    Dragoon
    wrote on last edited by Dragoon
    #1

    Hi I'm a newbie in Qt and I got stuck into a problem I'm not able to handle, I'm using an external library that implements some feature trough callbacks.
    AFAIK this llibrary uses different threads to manage such callback. As a result I'm not able to manage such calls:

    void MainWindow::connectMAV()
    {
        mavsdk::ConnectionResult conn_result = mavsdk.add_any_connection("localhost:5000");
    
        setWindowTitle("Listening");
    
        mavsdk.subscribe_on_new_system
        (
            [&]()
            {
                setWindowTitle("Connected");
                system = mavsdk.systems()[0];
            }
        );
    }
    

    In the above code the internal lambda function is never called.
    On identical non Qt C++ application the callback is triggered correctly.
    I think the problem is the interaction with the event loop management of Qt.
    There's a workaround?

    Best regards,
    Mike

    bye by[t]e{s}... Mike

    JonBJ S 2 Replies Last reply
    0
    • DragoonD Offline
      DragoonD Offline
      Dragoon
      wrote on last edited by Dragoon
      #14

      it seems that I found the real issue...
      I need to put these lines:

      Q_DECLARE_METATYPE(MissionRawServer::Result)
      Q_DECLARE_METATYPE(MissionRawServer::MissionPlan)
      

      in my class header

      and these:

      qRegisterMetaType<MissionRawServer::Result>();
      qRegisterMetaType<MissionRawServer::MissionPlan>();
      

      prior connect calls.

      Probably since parameters on callback where not QObject derivative they needed to be registered to be connect proof.

      I don't know it this's the correct register procedure and explanation of this issue but now ti seem to be fixed.
      Could someone confirm?

      bye by[t]e{s}... Mike

      jsulmJ 1 Reply Last reply
      2
      • DragoonD Dragoon

        Hi I'm a newbie in Qt and I got stuck into a problem I'm not able to handle, I'm using an external library that implements some feature trough callbacks.
        AFAIK this llibrary uses different threads to manage such callback. As a result I'm not able to manage such calls:

        void MainWindow::connectMAV()
        {
            mavsdk::ConnectionResult conn_result = mavsdk.add_any_connection("localhost:5000");
        
            setWindowTitle("Listening");
        
            mavsdk.subscribe_on_new_system
            (
                [&]()
                {
                    setWindowTitle("Connected");
                    system = mavsdk.systems()[0];
                }
            );
        }
        

        In the above code the internal lambda function is never called.
        On identical non Qt C++ application the callback is triggered correctly.
        I think the problem is the interaction with the event loop management of Qt.
        There's a workaround?

        Best regards,
        Mike

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

        @Dragoon
        I don't see how anyone will know what issue there might be in your code or Qt's with some third-party library.

        Although you say the lambda is never called, if it were and you say it comes from another thread in Qt you would not be allowed to perform setWindowTitle("Connected") from a non-UI thread.

        DragoonD 2 Replies Last reply
        0
        • JonBJ JonB

          @Dragoon
          I don't see how anyone will know what issue there might be in your code or Qt's with some third-party library.

          Although you say the lambda is never called, if it were and you say it comes from another thread in Qt you would not be allowed to perform setWindowTitle("Connected") from a non-UI thread.

          DragoonD Offline
          DragoonD Offline
          Dragoon
          wrote on last edited by
          #3

          @JonB that's the point.

          bye by[t]e{s}... Mike

          JonBJ 1 Reply Last reply
          0
          • DragoonD Dragoon

            @JonB that's the point.

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

            @Dragoon Sorry, which/what exactly is "the point"?

            1 Reply Last reply
            1
            • mranger90M Offline
              mranger90M Offline
              mranger90
              wrote on last edited by
              #5

              I'm not sure how this would work with a lambda. You might try to create a static member function and pass a pointer to that function. With a static function, you are going to need a pointer to mainWindow, since you wont get "this". A lot of libraries that use callbacks allow you to pass a pointer to "this" as a void * argument for just this purpose.
              i.e.
              MainWindow.h

              static void onNewSystem();
              

              MainWindow.cpp

              mavsdk.subscribe_on_new_system(&MainWindow::onNewSystem);
              
              MainWindow::onNewSystem()
              {
                 // assume that a pointer to MainWindow is set somewhere
                 mainWindow->setWindowTitle("Connected.");
              
              DragoonD 1 Reply Last reply
              0
              • DragoonD Dragoon

                Hi I'm a newbie in Qt and I got stuck into a problem I'm not able to handle, I'm using an external library that implements some feature trough callbacks.
                AFAIK this llibrary uses different threads to manage such callback. As a result I'm not able to manage such calls:

                void MainWindow::connectMAV()
                {
                    mavsdk::ConnectionResult conn_result = mavsdk.add_any_connection("localhost:5000");
                
                    setWindowTitle("Listening");
                
                    mavsdk.subscribe_on_new_system
                    (
                        [&]()
                        {
                            setWindowTitle("Connected");
                            system = mavsdk.systems()[0];
                        }
                    );
                }
                

                In the above code the internal lambda function is never called.
                On identical non Qt C++ application the callback is triggered correctly.
                I think the problem is the interaction with the event loop management of Qt.
                There's a workaround?

                Best regards,
                Mike

                S Offline
                S Offline
                SimonSchroeder
                wrote on last edited by
                #6

                @Dragoon said in Standard C++ callbacks handling inside Qt application:

                AFAIK this llibrary uses different threads to manage such callback.

                This might be one more problem. You need to call setWindowTitle() within the main GUI thread. In addition to previous fixes suggested, why don't you just write to the console if your lambda function gets called? Because it might actually be called but not do what you expect.

                The easiest way to have something done in the GUI thread is for your callback to just trigger a signal which is connected to a slot that does the actual work (i.e. call setWindowTitle()).

                DragoonD 1 Reply Last reply
                1
                • S SimonSchroeder

                  @Dragoon said in Standard C++ callbacks handling inside Qt application:

                  AFAIK this llibrary uses different threads to manage such callback.

                  This might be one more problem. You need to call setWindowTitle() within the main GUI thread. In addition to previous fixes suggested, why don't you just write to the console if your lambda function gets called? Because it might actually be called but not do what you expect.

                  The easiest way to have something done in the GUI thread is for your callback to just trigger a signal which is connected to a slot that does the actual work (i.e. call setWindowTitle()).

                  DragoonD Offline
                  DragoonD Offline
                  Dragoon
                  wrote on last edited by
                  #7

                  @SimonSchroeder I'll try this approach...

                  bye by[t]e{s}... Mike

                  DragoonD 1 Reply Last reply
                  0
                  • DragoonD Dragoon

                    @SimonSchroeder I'll try this approach...

                    DragoonD Offline
                    DragoonD Offline
                    Dragoon
                    wrote on last edited by Dragoon
                    #8

                    @SimonSchroeder tried and failed.

                     missionServer->subscribe_incoming_mission(
                       [&](mavsdk::MissionRawServer::Result result, mavsdk::MissionRawServer::MissionPlan plan)
                       {
                          emit incomingMission(result, plan);
                       }
                    );
                    
                    void MainWindow::onIncomingMission(MissionRawServer::Result result, MissionRawServer::MissionPlan plan)
                    {   
                           Q_UNUSED(result);
                           Q_UNUSED(plan);
                            missions++;
                    }
                    

                    Debugging it I can see callback being triggered but incominMission() never being fired.

                    bye by[t]e{s}... Mike

                    1 Reply Last reply
                    0
                    • JonBJ JonB

                      @Dragoon
                      I don't see how anyone will know what issue there might be in your code or Qt's with some third-party library.

                      Although you say the lambda is never called, if it were and you say it comes from another thread in Qt you would not be allowed to perform setWindowTitle("Connected") from a non-UI thread.

                      DragoonD Offline
                      DragoonD Offline
                      Dragoon
                      wrote on last edited by Dragoon
                      #9

                      @JonB the third party library could not be the main issue in this. The problem is the management of C++ 17 standard callbacks.
                      And, BTW, even:

                      missions++;
                      

                      (being mission an int variable) is never executed.

                      bye by[t]e{s}... Mike

                      jsulmJ 1 Reply Last reply
                      0
                      • DragoonD Dragoon

                        @JonB the third party library could not be the main issue in this. The problem is the management of C++ 17 standard callbacks.
                        And, BTW, even:

                        missions++;
                        

                        (being mission an int variable) is never executed.

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

                        @Dragoon Did you make sure you connected incomingMission successfully to onIncomingMission? Did you check the lifetime of the involved objects? If the lambda is called then the signal is for sure emitted. Most probably you did not connect signal/slot.

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

                        DragoonD 1 Reply Last reply
                        0
                        • mranger90M mranger90

                          I'm not sure how this would work with a lambda. You might try to create a static member function and pass a pointer to that function. With a static function, you are going to need a pointer to mainWindow, since you wont get "this". A lot of libraries that use callbacks allow you to pass a pointer to "this" as a void * argument for just this purpose.
                          i.e.
                          MainWindow.h

                          static void onNewSystem();
                          

                          MainWindow.cpp

                          mavsdk.subscribe_on_new_system(&MainWindow::onNewSystem);
                          
                          MainWindow::onNewSystem()
                          {
                             // assume that a pointer to MainWindow is set somewhere
                             mainWindow->setWindowTitle("Connected.");
                          
                          DragoonD Offline
                          DragoonD Offline
                          Dragoon
                          wrote on last edited by
                          #11

                          @mranger90
                          defining 'slots' as static member seem to work.
                          The problem now is to access MainWindow instance...

                          bye by[t]e{s}... Mike

                          jsulmJ 1 Reply Last reply
                          0
                          • DragoonD Dragoon

                            @mranger90
                            defining 'slots' as static member seem to work.
                            The problem now is to access MainWindow instance...

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

                            @Dragoon said in Standard C++ callbacks handling inside Qt application:

                            defining 'slots' as static member seem to work

                            Why static?!
                            Can you show how and what you're actually connecting?

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

                            1 Reply Last reply
                            0
                            • jsulmJ jsulm

                              @Dragoon Did you make sure you connected incomingMission successfully to onIncomingMission? Did you check the lifetime of the involved objects? If the lambda is called then the signal is for sure emitted. Most probably you did not connect signal/slot.

                              DragoonD Offline
                              DragoonD Offline
                              Dragoon
                              wrote on last edited by Dragoon
                              #13

                              @jsulm said in Standard C++ callbacks handling inside Qt application:

                              Most probably you did not connect signal/slot.

                              I'm not SO newbie... ;-)

                              MainWindow::MainWindow(QWidget *parent)
                                  : QMainWindow(parent)
                                  , ui(new Ui::MainWindow)
                                  , configuration(Mavsdk::Configuration::UsageType::Autopilot)
                                  , eventTimer(new QTimer(this))
                              
                              {
                                  ui->setupUi(this);
                              
                                  connect(this, &MainWindow::newSystem, this, &MainWindow::onNewSystem);
                                  connect(this, &MainWindow::incomingMission, this, &MainWindow::onIncomingMission);
                                  connect(eventTimer, &QTimer::timeout, this, &MainWindow::onUpdateEvent);
                              
                                  initMAVSDK();
                                  initMAVConnection();
                              }
                              
                              void MainWindow::initMAVSDK()
                              {
                                  configuration.set_system_id(DEF_ID);
                              
                                  mavsdk.set_configuration(configuration);
                              }
                              
                              void MainWindow::initMAVConnection()
                              {
                                  ConnectionResult conn_result = mavsdk.add_any_connection(DEF_URL.toStdString());  
                              
                                  if(conn_result == mavsdk::ConnectionResult::Success)
                                  {
                                      mavsdk.subscribe_on_new_system(
                                          [&](){
                                              emit newSystem();
                                          }
                                      );
                              
                                      eventTimer->start(DEF_UPDATE_TIMEOUT);
                                  }
                              }
                              

                              bye by[t]e{s}... Mike

                              1 Reply Last reply
                              0
                              • DragoonD Offline
                                DragoonD Offline
                                Dragoon
                                wrote on last edited by Dragoon
                                #14

                                it seems that I found the real issue...
                                I need to put these lines:

                                Q_DECLARE_METATYPE(MissionRawServer::Result)
                                Q_DECLARE_METATYPE(MissionRawServer::MissionPlan)
                                

                                in my class header

                                and these:

                                qRegisterMetaType<MissionRawServer::Result>();
                                qRegisterMetaType<MissionRawServer::MissionPlan>();
                                

                                prior connect calls.

                                Probably since parameters on callback where not QObject derivative they needed to be registered to be connect proof.

                                I don't know it this's the correct register procedure and explanation of this issue but now ti seem to be fixed.
                                Could someone confirm?

                                bye by[t]e{s}... Mike

                                jsulmJ 1 Reply Last reply
                                2
                                • DragoonD Dragoon

                                  it seems that I found the real issue...
                                  I need to put these lines:

                                  Q_DECLARE_METATYPE(MissionRawServer::Result)
                                  Q_DECLARE_METATYPE(MissionRawServer::MissionPlan)
                                  

                                  in my class header

                                  and these:

                                  qRegisterMetaType<MissionRawServer::Result>();
                                  qRegisterMetaType<MissionRawServer::MissionPlan>();
                                  

                                  prior connect calls.

                                  Probably since parameters on callback where not QObject derivative they needed to be registered to be connect proof.

                                  I don't know it this's the correct register procedure and explanation of this issue but now ti seem to be fixed.
                                  Could someone confirm?

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

                                  @Dragoon said in Standard C++ callbacks handling inside Qt application:

                                  I need to put these lines

                                  Ah, yes you're right. If you use your own custom data types as parameters for signals/slots you have to register them.

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

                                  1 Reply Last reply
                                  1
                                  • Kent-DorfmanK Offline
                                    Kent-DorfmanK Offline
                                    Kent-Dorfman
                                    wrote on last edited by
                                    #16

                                    @Dragoon so should this be marked as solved?

                                    The dystopian literature that served as a warning in my youth has become an instruction manual in my elder years.

                                    DragoonD 1 Reply Last reply
                                    0
                                    • Kent-DorfmanK Kent-Dorfman

                                      @Dragoon so should this be marked as solved?

                                      DragoonD Offline
                                      DragoonD Offline
                                      Dragoon
                                      wrote on last edited by
                                      #17

                                      @Kent-Dorfman I do.

                                      bye by[t]e{s}... Mike

                                      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