Difference between revisions of "Extending QAction by emitting additional Signals"

From Qt Wiki
Jump to: navigation, search
 
(5 intermediate revisions by one other user not shown)
Line 1: Line 1:
 
[[Category:HowTo]]
 
[[Category:HowTo]]
[[Category:snippets]]
 
  
'''English''' | [[ActionEmittingCheckedUncheckedSignals_German|Deutsch]]
+
{{DocLink|QAction}}s can be set up to be ''checkable'', that means that it will toggle its status between a checked and unchecked state. This is displayed, for instance, as a {{DocLink|QPushButton}} that remains repressed when clicked a first time. The problem with QAction is that it emits a single signal, <tt>triggered(bool)</tt>, with the actual status of the action (if checked or not). This requires your slot to manually check the boolean flag to perform a specific behavior depending on the checked status. If you want your action to perform two different tasks without having to check the checked status of the action you can subclass the action implementing a couple of signals to emit events depending on the action internal status.
  
= Extending QAction to provide a checked/unchecked signals =
 
 
QAction can be set up to be ''checkable'', that means that it will toggle its status between a checked and unchecked status. This is displayed, for instance, as a qpushbutton that remains pushed when clicked a first time. The problem with QAction is that it emits a single signal, ''triggered(bool)'', with the actual status of the action (if checked or not). This requires your slot to manually check the boolean flag to perform a specific behavior depending on the checked status. If you want your action to perform two different tasks without having to check the checked status of the action you can subclass the action implementing a couple of signals to emit events depending on the action internal status.
 
 
This can become very handy when you have got a set of actions that must be perform a different behavior when checked but must do all the same task when unchecked.
 
This can become very handy when you have got a set of actions that must be perform a different behavior when checked but must do all the same task when unchecked.
  
== Source Code ==
+
==Source Code==
 +
The source code is really simple. Here there is the header file:
  
The source code is really simple.
+
<code>
Here there is the header file:
+
#ifndef CHECKABLEACTION_H
 
 
<code>#ifndef CHECKABLEACTION_H
 
 
#define CHECKABLEACTION_H
 
#define CHECKABLEACTION_H
  
Line 28: Line 23:
 
{
 
{
 
  Q_OBJECT
 
  Q_OBJECT
public:
+
public:
explicit CheckableAction(QObject '''parent = 0);
+
  explicit CheckableAction(QObject *parent = 0);
 
 
signals:
 
 
 
/*!
 
* This signal is emitted each time the action is
 
* checked.
 
*/
 
void actionChecked();
 
 
 
/*!
 
* This signal is emitted each time the action is
 
* unchecked.
 
*/
 
void actionUnchecked();
 
 
 
 
 
  
public slots:
+
signals:
 +
  /*!
 +
  * This signal is emitted each time the action is
 +
  * checked.
 +
  */
 +
  void actionChecked();
  
 +
  /*!
 +
  * This signal is emitted each time the action is
 +
  * unchecked.
 +
  */
 +
  void actionUnchecked();
  
private slots:
+
public slots:
 
 
/*!
 
* This slot is used to forward (i.e., emit) a triggered
 
* event depending on the status of the action (i.e., if it
 
* has been checked or not).
 
* checked true if the action has been checked, false
 
* otherwise
 
*/
 
void slotForwardCheckSignal( bool checked );
 
  
 +
private slots:
 +
  /*!
 +
  * This slot is used to forward (i.e., emit) a triggered
 +
  * event depending on the status of the action (i.e., if it
 +
  * has been checked or not).
 +
  * checked true if the action has been checked, false
 +
  * otherwise
 +
  */
 +
  void slotForwardCheckSignal( bool checked );
 
};
 
};
  
Line 68: Line 57:
 
and here the implementation of the class
 
and here the implementation of the class
  
<code>#include "checkableaction.h"
+
<code>
 +
#include "checkableaction.h"
  
CheckableAction::CheckableAction(QObject '''parent) :
+
CheckableAction::CheckableAction(QObject *parent) :
 
  QAction(parent)
 
  QAction(parent)
{
+
{
// auto connect the triggered event to the slot for
+
 
// forwarding the check status
+
  // auto connect the triggered event to the slot for
connect( this,
+
  // forwarding the check status
SIGNAL (triggered(bool)),
+
  connect( this, SIGNAL(triggered(bool)),
this,
+
          this, SLOT(slotForwardCheckSignal(bool))
SLOT (slotForwardCheckSignal(bool)) );
+
  );
 
}
 
}
  
Line 84: Line 74:
 
{
 
{
 
  qDebug() << "Action checked status " << checked;
 
  qDebug() << "Action checked status " << checked;
 +
 
  // check the status of the action
 
  // check the status of the action
  if( ! isCheckable() )
+
  if( ! isCheckable() ) {
// the action cannot be checked, simply emit
+
  // the action cannot be checked, simply emit
// a triggered event
+
  // a triggered event
triggered();
+
  triggered();
  else
+
  } else
  if( isChecked() )
+
  if( isChecked() ) {
// the action is checked
+
  // the action is checked
emit actionChecked();
+
  emit actionChecked();
  else
+
}
// the action is unchecked
+
  else {
emit actionUnchecked();
+
  // the action is unchecked
 +
  emit actionUnchecked();
 +
}
  
 
}
 
}
 
</code>
 
</code>
  
== Usage Example ==
+
==Usage Example==
 
The action can be used in the way a QAction is, for instance:
 
The action can be used in the way a QAction is, for instance:
  
 
<code>
 
<code>
CheckableAction''' myAction = new CheckableAction( this );
+
CheckableAction *myAction = new CheckableAction( this );
myAction->setText( tr("Action TEXT") );
+
myAction->setText( tr("Action TEXT") );
myAction->setIcon( QIcon(":/actions/img/myaction.png") );
+
myAction->setIcon( QIcon(":/actions/img/myaction.png") );
myAction->setStatusTip( tr("Check/Uncheck the action") );
+
myAction->setStatusTip( tr("Check/Uncheck the action") );
myAction->setCheckable( true );
+
myAction->setCheckable( true );
connect( myAction,
+
 
SIGNAL (actionChecked()),
+
connect( myAction, SIGNAL(actionChecked()),
this,
+
            this, SLOT(slotActionUncheked())
SLOT( slotActionUncheked()) );
+
      );
connect( myAction,
+
 
SIGNAL (actionUnchecked()),
+
connect( myAction, SIGNAL(actionUnchecked()),
this,
+
            this, SLOT(slotActionCheked())
SLOT (slotActionCheked()) );
+
      );
  
 
</code>
 
</code>

Latest revision as of 02:38, 14 November 2020


QActions can be set up to be checkable, that means that it will toggle its status between a checked and unchecked state. This is displayed, for instance, as a QPushButton that remains repressed when clicked a first time. The problem with QAction is that it emits a single signal, triggered(bool), with the actual status of the action (if checked or not). This requires your slot to manually check the boolean flag to perform a specific behavior depending on the checked status. If you want your action to perform two different tasks without having to check the checked status of the action you can subclass the action implementing a couple of signals to emit events depending on the action internal status.

This can become very handy when you have got a set of actions that must be perform a different behavior when checked but must do all the same task when unchecked.

Source Code

The source code is really simple. Here there is the header file:

  1. ifndef CHECKABLEACTION_H
  2. define CHECKABLEACTION_H
  1. include <QAction>
  2. include <QDebug>

/*!

* This class represents an action that will emit
* distinct signals depending on the check of the
* action itself.
*/

class CheckableAction : public QAction {

Q_OBJECT
public:
 explicit CheckableAction(QObject *parent = 0);
signals:
 /*!
  * This signal is emitted each time the action is
  * checked.
  */
 void actionChecked();
 /*!
  * This signal is emitted each time the action is
  * unchecked.
  */
 void actionUnchecked();
public slots:
private slots:
 /*!
  * This slot is used to forward (i.e., emit) a triggered
  * event depending on the status of the action (i.e., if it
  * has been checked or not).
  * checked true if the action has been checked, false
  * otherwise
  */
 void slotForwardCheckSignal( bool checked );

};

  1. endif // CHECKABLEACTION_H

and here the implementation of the class

  1. include "checkableaction.h"

CheckableAction::CheckableAction(QObject *parent) :

QAction(parent)
{
 // auto connect the triggered event to the slot for
 // forwarding the check status
 connect( this, SIGNAL(triggered(bool)),
          this, SLOT(slotForwardCheckSignal(bool))
 );

}

void CheckableAction::slotForwardCheckSignal(bool checked) {

qDebug() << "Action checked status " << checked;
// check the status of the action
if( ! isCheckable() ) {
 // the action cannot be checked, simply emit
 // a triggered event
 triggered();
} else
if( isChecked() ) {
 // the action is checked
 emit actionChecked();
}
else {
 // the action is unchecked
 emit actionUnchecked();
}

}

Usage Example

The action can be used in the way a QAction is, for instance:

CheckableAction *myAction = new CheckableAction( this ); myAction->setText( tr("Action TEXT") ); myAction->setIcon( QIcon(":/actions/img/myaction.png") ); myAction->setStatusTip( tr("Check/Uncheck the action") ); myAction->setCheckable( true );

connect( myAction, SIGNAL(actionChecked()),

            this, SLOT(slotActionUncheked())
      );

connect( myAction, SIGNAL(actionUnchecked()),

            this, SLOT(slotActionCheked())
      );