Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt
  • Unsolved
Collapse
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.
  • 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