Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. Can QtQuick app create and display MessageDialog from C++ static member function?
Forum Updated to NodeBB v4.3 + New Features

Can QtQuick app create and display MessageDialog from C++ static member function?

Scheduled Pinned Locked Moved Solved QML and Qt Quick
5 Posts 3 Posters 468 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.
  • Tom assoT Offline
    Tom assoT Offline
    Tom asso
    wrote on last edited by Tom asso
    #1

    I want my C++ static member function to simply display an informational message in a dialog. Does QtQuick provide a convenience function to do this? I see how to do this with a C++ signal connected to QML slot, but in my case the C++ is a static member so cannot emit a signal.

    Thanks!

    GrecKoG 1 Reply Last reply
    0
    • Tom assoT Tom asso

      I want my C++ static member function to simply display an informational message in a dialog. Does QtQuick provide a convenience function to do this? I see how to do this with a C++ signal connected to QML slot, but in my case the C++ is a static member so cannot emit a signal.

      Thanks!

      GrecKoG Offline
      GrecKoG Offline
      GrecKo
      Qt Champions 2018
      wrote on last edited by
      #2

      @Tom-asso add a static QObject member to emit the signal. Or add a function in your root QML window and invoke it from c++

      Tom assoT 1 Reply Last reply
      3
      • GrecKoG GrecKo

        @Tom-asso add a static QObject member to emit the signal. Or add a function in your root QML window and invoke it from c++

        Tom assoT Offline
        Tom assoT Offline
        Tom asso
        wrote on last edited by Tom asso
        #3

        @GrecKo - thanks!
        I might be over-thinking this, but it's still not clear to me how this would work. I.e. I want my static C++ member function to raise an informational message dialog (with just on 'OK' button). Seems like a common use case? Are there examples that you can point to? In particular, what would the QObject::connect() call look like, if the signal is being emitted by a static member object, assuming my QML ApplicationWindow defines function showInfoDialog()?

        class Emitter : public QObject {
        signal:
          sendMsg(QString msg);
        };
        
        class Backend {
           static Emitter emitter;
        }
        

        Now how to connect the signal emitted by static member emitter with QML? What are the first two arguments to connect()?

        main.cpp:

        Backend backend;
        
        QObject::connect(&backend.emitter, SIGNAL(sendMsg(QString msg)),
        		 rootObject, SLOT(showInfoDialog(QString msg)));
        

        The above compiles, but connect() fails at runtime:

        QObject::connect: No such signal Emitter::showMessage(QString &msg)
        

        This seems odd because the runtime "knows" that showMessage(QString &msg) is associated with the Emitter class, yet somehow doesn't recognize it as a signal. What am I doing wrong???

        Thanks!

        B 1 Reply Last reply
        0
        • Tom assoT Tom asso

          @GrecKo - thanks!
          I might be over-thinking this, but it's still not clear to me how this would work. I.e. I want my static C++ member function to raise an informational message dialog (with just on 'OK' button). Seems like a common use case? Are there examples that you can point to? In particular, what would the QObject::connect() call look like, if the signal is being emitted by a static member object, assuming my QML ApplicationWindow defines function showInfoDialog()?

          class Emitter : public QObject {
          signal:
            sendMsg(QString msg);
          };
          
          class Backend {
             static Emitter emitter;
          }
          

          Now how to connect the signal emitted by static member emitter with QML? What are the first two arguments to connect()?

          main.cpp:

          Backend backend;
          
          QObject::connect(&backend.emitter, SIGNAL(sendMsg(QString msg)),
          		 rootObject, SLOT(showInfoDialog(QString msg)));
          

          The above compiles, but connect() fails at runtime:

          QObject::connect: No such signal Emitter::showMessage(QString &msg)
          

          This seems odd because the runtime "knows" that showMessage(QString &msg) is associated with the Emitter class, yet somehow doesn't recognize it as a signal. What am I doing wrong???

          Thanks!

          B Offline
          B Offline
          Bob64
          wrote on last edited by
          #4

          @Tom-asso I think the issue you are having is that Backend does not expose a signal to allow you to connect, right?

          You could add a static function to your Backend class which would make the connection. That would then have access to the emitter. To keep it clean, you could pass a std::function as the target, which you initialise with a lambda.

          class Backend
          {
          public:
              static void connectInfoMsg(std::function<void(QString)> onInfoMsg)
              {
                  QObject::connect(&emitter, &Emitter::sendMsg, onInfoMsg);
              }
              ...
          };
          

          In your main.cpp:

          Backend::connectInfoMsg(
              [&](QString msg){ rootObject->showInfoDialog(msg);
          }
          

          Despite what you say, I am not sure how common this actually is as a use case. I don't recall ever having done anything like this. I would be more likely to expose an object to QML using a context property (old-fashioned way) or qmlRegisterSingletonInstance (modern way) that would emit signals when messages are available. Then hook up connections to dialogs on the QML side.

          I think you are possibly making things awkward for yourself with a design that relies on a static function.

          Tom assoT 1 Reply Last reply
          1
          • B Bob64

            @Tom-asso I think the issue you are having is that Backend does not expose a signal to allow you to connect, right?

            You could add a static function to your Backend class which would make the connection. That would then have access to the emitter. To keep it clean, you could pass a std::function as the target, which you initialise with a lambda.

            class Backend
            {
            public:
                static void connectInfoMsg(std::function<void(QString)> onInfoMsg)
                {
                    QObject::connect(&emitter, &Emitter::sendMsg, onInfoMsg);
                }
                ...
            };
            

            In your main.cpp:

            Backend::connectInfoMsg(
                [&](QString msg){ rootObject->showInfoDialog(msg);
            }
            

            Despite what you say, I am not sure how common this actually is as a use case. I don't recall ever having done anything like this. I would be more likely to expose an object to QML using a context property (old-fashioned way) or qmlRegisterSingletonInstance (modern way) that would emit signals when messages are available. Then hook up connections to dialogs on the QML side.

            I think you are possibly making things awkward for yourself with a design that relies on a static function.

            Tom assoT Offline
            Tom assoT Offline
            Tom asso
            wrote on last edited by Tom asso
            #5

            @Bob64 - Thanks, Bob.
            Emitter actually emits a signal sendMsg(). The reason that connect() failed is because I need to specify data passed as QVariant (not QMessage) when data is exchanged between C++ and QML. So the following compiles and connects properly:

            Emitter.h:

            class Emitter : public QObject {
            signal:
              sendMsg(QVariant msg);
            };
            

            main.cpp:

            QObject::connect(&backend.emitter, SIGNAL(sendMsg(QVariant)),
            		 rootObject, SLOT(showInfoDialog(QVariant)));
            

            My application includes a lot of legacy 'C' code, and passes Backend static function pointers to that C code. Now that I have it working it seems ok.
            Thanks!

            1 Reply Last reply
            0
            • Tom assoT Tom asso has marked this topic as solved on

            • Login

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