Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt
  • Unsolved
Collapse
qtws26_logo

The Qt Event of the Year: Qt World Summit 2026

Save Your Spot >
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. How can i log all executions of QAction?
Qt 6.12 LTS is out! See what's new in the release blog

How can i log all executions of QAction?

Scheduled Pinned Locked Moved Solved General and Desktop
11 Posts 4 Posters 1.8k 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.
  • S Offline
    S Offline
    stefanwoe
    wrote on last edited by
    #1

    In our application we want to log all QAction executions to a log file. All Commands are called using QAction objects, and using that we would be able to reconstruct what a user did.
    I originally wanted to extend QAction with a own class and just overload the triggered method, but this method is not virtual as most others of QAction.

    I then tried to add signals following this approach here
    https://stackoverflow.com/questions/70064468/list-all-signals-emitted-from-qt-application/70066122#70066122

    But i am unable to get the calling QAction Element.
    Is there a way to do this without adding code to each command we implemented?

    1 Reply Last reply
    0
    • D Offline
      D Offline
      DerReisende
      wrote on last edited by
      #2

      Having had only a quick look at QAction source why don‘t you overrride the event() function and do the logging before emitting the appropriate signals?

      S 1 Reply Last reply
      3
      • D DerReisende

        Having had only a quick look at QAction source why don‘t you overrride the event() function and do the logging before emitting the appropriate signals?

        S Offline
        S Offline
        stefanwoe
        wrote on last edited by
        #3

        @DerReisende I tried that, but i dont find a matching event type:
        I find 3 events related to actions:
        QEvent::ActionAdded
        QEvent::ActionChanged
        QEvent::ActionRemoved
        (https://doc.qt.io/qt-6/qevent.html)

        QEvent::ActionChanged will be send when executing but also when building the events or on a a language change etc. I dont find a way to distinguish this.

        1 Reply Last reply
        0
        • D Offline
          D Offline
          DerReisende
          wrote on last edited by
          #4

          I meant void QAction::activate(ActionEvent event):

          void QAction::activate(ActionEvent event)
          1113	{
          1114	    Q_D(QAction);
          1115	    if (event == Trigger) {
          1116	        // Ignore even explicit triggers when explicitly disabled
          1117	        if ((d->explicitEnabled && !d->explicitEnabledValue) || (d->group && !d->group->isEnabled()))
          1118	            return;
          1119	        QPointer<QObject> guard = this;
          1120	        if (d->checkable) {
          1121	            // the checked action of an exclusive group may not be unchecked
          1122	            if (d->checked && (d->group
          1123	                               && d->group->exclusionPolicy() == QActionGroup::ExclusionPolicy::Exclusive
          1124	                               && d->group->checkedAction() == this)) {
          1125	                if (!guard.isNull())
          1126	                    emit triggered(true);
          1127	                return;
          1128	            }
          1129	            setChecked(!d->checked);
          1130	        }
          1131	        if (!guard.isNull())
          1132	            emit triggered(d->checked);
          1133	    } else if (event == Hover) {
          1134	        emit hovered();
          1135	    }
          1136	}
          

          This is from Qt6 source file and maybe you should be able to properly put logging content in your override.

          S 1 Reply Last reply
          0
          • S Offline
            S Offline
            stefanwoe
            wrote on last edited by stefanwoe
            #5

            I found a rather simple solution inspired by @DerReisende.
            It just uses a signal / slot. So all i had to do besides this, was
            replace "new QAction" by "new MyAction" all over my program.

            This seems to work fine:

            class MyAction : public QAction
            {
                Q_OBJECT
                using QAction::QAction;
            
                bool event(QEvent *e);
            
            public slots:
                void onTriggered(bool);
            };
            
            bool MyAction ::event(QEvent *e)
            {
                if(e->type() == QEvent::ActionChanged)
                {
                    static const QMetaMethod triggeredSignal = QMetaMethod::fromSignal(&CMDIAction::triggered);
            
                    if(! isSignalConnected(triggeredSignal))
                       connect(this, SIGNAL(triggered(bool)), this, SLOT(onTriggered(bool)));
                }
                return QAction::event(e);
            }
            
            void MyAction ::onTriggered(bool)
            {
                gLogStream << " Action Triggered: " << text() ;
            }
            
            M 1 Reply Last reply
            0
            • D DerReisende

              I meant void QAction::activate(ActionEvent event):

              void QAction::activate(ActionEvent event)
              1113	{
              1114	    Q_D(QAction);
              1115	    if (event == Trigger) {
              1116	        // Ignore even explicit triggers when explicitly disabled
              1117	        if ((d->explicitEnabled && !d->explicitEnabledValue) || (d->group && !d->group->isEnabled()))
              1118	            return;
              1119	        QPointer<QObject> guard = this;
              1120	        if (d->checkable) {
              1121	            // the checked action of an exclusive group may not be unchecked
              1122	            if (d->checked && (d->group
              1123	                               && d->group->exclusionPolicy() == QActionGroup::ExclusionPolicy::Exclusive
              1124	                               && d->group->checkedAction() == this)) {
              1125	                if (!guard.isNull())
              1126	                    emit triggered(true);
              1127	                return;
              1128	            }
              1129	            setChecked(!d->checked);
              1130	        }
              1131	        if (!guard.isNull())
              1132	            emit triggered(d->checked);
              1133	    } else if (event == Hover) {
              1134	        emit hovered();
              1135	    }
              1136	}
              

              This is from Qt6 source file and maybe you should be able to properly put logging content in your override.

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

              @DerReisende
              As noted above, you cant override QAction::activate its not virtual.

              1 Reply Last reply
              0
              • S stefanwoe

                I found a rather simple solution inspired by @DerReisende.
                It just uses a signal / slot. So all i had to do besides this, was
                replace "new QAction" by "new MyAction" all over my program.

                This seems to work fine:

                class MyAction : public QAction
                {
                    Q_OBJECT
                    using QAction::QAction;
                
                    bool event(QEvent *e);
                
                public slots:
                    void onTriggered(bool);
                };
                
                bool MyAction ::event(QEvent *e)
                {
                    if(e->type() == QEvent::ActionChanged)
                    {
                        static const QMetaMethod triggeredSignal = QMetaMethod::fromSignal(&CMDIAction::triggered);
                
                        if(! isSignalConnected(triggeredSignal))
                           connect(this, SIGNAL(triggered(bool)), this, SLOT(onTriggered(bool)));
                    }
                    return QAction::event(e);
                }
                
                void MyAction ::onTriggered(bool)
                {
                    gLogStream << " Action Triggered: " << text() ;
                }
                
                M Offline
                M Offline
                mchinand
                wrote on last edited by mchinand
                #7

                @stefanwoe said in How can i log all executions of QAction?:

                connect(this, SIGNAL(triggered(bool)), this, SLOT(onTriggered(bool)));

                Couldn't you put this connect statement (and switch to the new(ish) connect format) in the constructor of MyAction?

                S 1 Reply Last reply
                0
                • M mchinand

                  @stefanwoe said in How can i log all executions of QAction?:

                  connect(this, SIGNAL(triggered(bool)), this, SLOT(onTriggered(bool)));

                  Couldn't you put this connect statement (and switch to the new(ish) connect format) in the constructor of MyAction?

                  S Offline
                  S Offline
                  stefanwoe
                  wrote on last edited by
                  #8

                  @mchinand N0, i tried, but i failed on this.

                  jsulmJ 1 Reply Last reply
                  0
                  • S stefanwoe

                    @mchinand N0, i tried, but i failed on this.

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

                    @stefanwoe said in How can i log all executions of QAction?:

                    but i failed on this

                    Why? What happened and how exactly did you try?

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

                    S 1 Reply Last reply
                    0
                    • jsulmJ jsulm

                      @stefanwoe said in How can i log all executions of QAction?:

                      but i failed on this

                      Why? What happened and how exactly did you try?

                      S Offline
                      S Offline
                      stefanwoe
                      wrote on last edited by
                      #10

                      @jsulm Nothing i tried compiled, but i may have done it wrong Thats not important for me. The solution seems to work. Thats important.

                      1 Reply Last reply
                      0
                      • S Offline
                        S Offline
                        stefanwoe
                        wrote on last edited by stefanwoe
                        #11

                        Ah, it works that way:

                        connect(this, &QAction::triggered, this, &MyAction::onTriggered);
                        

                        If do that in the constructor ill have to overload all 3 different ctors - but yes that would probably work to.

                        1 Reply Last reply
                        1

                        • Login

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