Qt wiki will be updated on October 12th 2023 starting at 11:30 AM (EEST) and the maintenance will last around 2-3 hours. During the maintenance the site will be unavailable.

Extending QAction by emitting additional Signals: Difference between revisions

From Qt Wiki
Jump to navigation Jump to search
No edit summary
 
No edit summary
Line 1: Line 1:
<div class="wiki-content qtcdk">
=Extending QAction to provide a checked/unchecked signals=
=Extending QAction to provide a checked/unchecked signals=


Line 6: Line 8:


The source code is really simple.<br /> Here there is the header file:
The source code is really simple.<br /> Here there is the header file:
<div class="cpp-qt geshi">
# <div class="de1"><span class="co2"><nowiki>#ifndef CHECKABLEACTION_H</nowiki></span></div>
# <div class="de1"><span class="co2">#define CHECKABLEACTION_H</span></div>
# <div class="de1"> </div>
# <div class="de1"><span class="co2">#include &lt;QAction&gt;</span></div>
# <div class="de2"><span class="co2">#include &lt;QDebug&gt;</span></div>
# <div class="de1"> </div>
# <div class="de1"><span class="coMULTI">/*!</span></div>
# <div class="de1"><span class="coMULTI">  * This class represents an action that will emit</span></div>
# <div class="de1"><span class="coMULTI">  * distinct signals depending on the check of the</span></div>
# <div class="de2"><span class="coMULTI">  * action itself.</span></div>
# <div class="de1"><span class="coMULTI">  */</span></div>
# <div class="de1"><span class="kw2">class</span> CheckableAction <span class="sy0">:</span> <span class="kw2">public</span> [http://doc.qt.io/QAction.html <span class="kw5">QAction</span>]</div>
# <div class="de1"><span class="br0">{</span></div>
# <div class="de1">    <span class="kw2">Q_OBJECT</span></div>
# <div class="de2"><span class="kw2">public</span><span class="sy0">:</span></div>
# <div class="de1">    <span class="kw2">explicit</span> CheckableAction<span class="br0">(</span>[http://doc.qt.io/QObject.html <span class="kw5">QObject</span>] <span class="sy0">*</span>parent <span class="sy0">=</span> <span class="nu0">0</span><span class="br0">)</span><span class="sy0">;</span></div>
# <div class="de1"> </div>
# <div class="de1"><span class="kw2">signals</span><span class="sy0">:</span></div>
# <div class="de1"> </div>
# <div class="de2">    <span class="coMULTI">/*!</span></div>
# <div class="de1"><span class="coMULTI">      * This signal is emitted each time the action is</span></div>
# <div class="de1"><span class="coMULTI">      * checked.</span></div>
# <div class="de1"><span class="coMULTI">      */</span></div>
# <div class="de1">    <span class="kw4">void</span> actionChecked<span class="br0">(</span><span class="br0">)</span><span class="sy0">;</span></div>
# <div class="de2"> </div>
# <div class="de1">    <span class="coMULTI">/*!</span></div>
# <div class="de1"><span class="coMULTI">      * This signal is emitted each time the action is</span></div>
# <div class="de1"><span class="coMULTI">      * unchecked.</span></div>
# <div class="de1"><span class="coMULTI">      */</span></div>
# <div class="de2">    <span class="kw4">void</span> actionUnchecked<span class="br0">(</span><span class="br0">)</span><span class="sy0">;</span></div>
# <div class="de1"> </div>
# <div class="de1"> </div>
# <div class="de1"> </div>
# <div class="de1"><span class="kw2">public</span> <span class="kw2">slots</span><span class="sy0">:</span></div>
# <div class="de2"> </div>
# <div class="de1"> </div>
# <div class="de1"><span class="kw2">private</span> <span class="kw2">slots</span><span class="sy0">:</span></div>
# <div class="de1"> </div>
# <div class="de1">    <span class="coMULTI">/*!</span></div>
# <div class="de2"><span class="coMULTI">      * This slot is used to forward (i.e., emit) a triggered</span></div>
# <div class="de1"><span class="coMULTI">      * event depending on the status of the action (i.e., if it</span></div>
# <div class="de1"><span class="coMULTI">      * has been checked or not).</span></div>
# <div class="de1"><span class="coMULTI">      * \param checked true if the action has been checked, false</span></div>
# <div class="de1"><span class="coMULTI">      * otherwise</span></div>
# <div class="de2"><span class="coMULTI">      */</span></div>
# <div class="de1">    <span class="kw4">void</span> slotForwardCheckSignal<span class="br0">(</span> <span class="kw4">bool</span> checked <span class="br0">)</span><span class="sy0">;</span></div>
# <div class="de1"> </div>
# <div class="de1"><span class="br0">}</span><span class="sy0">;</span></div>
# <div class="de1"> </div>
# <div class="de2"><span class="co2">#endif // CHECKABLEACTION_H</span></div>
</div>


and here the implementation of the class
and here the implementation of the class
<div class="cpp-qt geshi">
# <div class="de1"><span class="co2"><nowiki>#include "checkableaction.h"</nowiki></span></div>
# <div class="de1"> </div>
# <div class="de1">CheckableAction<span class="sy0">::</span><span class="me2">CheckableAction</span><span class="br0">(</span>[http://doc.qt.io/QObject.html <span class="kw5">QObject</span>] <span class="sy0">*</span>parent<span class="br0">)</span> <span class="sy0">:</span></div>
# <div class="de1">    [http://doc.qt.io/QAction.html <span class="kw5">QAction</span>]<span class="br0">(</span>parent<span class="br0">)</span></div>
# <div class="de2"><span class="br0">{</span></div>
# <div class="de1">    <span class="co1">// auto connect the triggered event to the slot for</span></div>
# <div class="de1">    <span class="co1">// forwarding the check status</span></div>
# <div class="de1">    <span class="kw2">connect</span><span class="br0">(</span> <span class="kw1">this</span><span class="sy0">,</span></div>
# <div class="de1">             SIGNAL<span class="br0">(</span>triggered<span class="br0">(</span><span class="kw4">bool</span><span class="br0">)</span><span class="br0">)</span><span class="sy0">,</span></div>
# <div class="de2">             <span class="kw1">this</span><span class="sy0">,</span></div>
# <div class="de1">             SLOT<span class="br0">(</span>slotForwardCheckSignal<span class="br0">(</span><span class="kw4">bool</span><span class="br0">)</span><span class="br0">)</span> <span class="br0">)</span><span class="sy0">;</span></div>
# <div class="de1"><span class="br0">}</span></div>
# <div class="de1"> </div>
# <div class="de1"><span class="kw4">void</span> CheckableAction<span class="sy0">::</span><span class="me2">slotForwardCheckSignal</span><span class="br0">(</span><span class="kw4">bool</span> checked<span class="br0">)</span></div>
# <div class="de2"><span class="br0">{</span></div>
# <div class="de1">    <span class="kw2">qDebug</span><span class="br0">(</span><span class="br0">)</span> <span class="sy0">&lt;&lt;</span> <span class="st0">"Action checked status "</span> <span class="sy0">&lt;&lt;</span> checked<span class="sy0">;</span></div>
# <div class="de1">    <span class="co1">// check the status of the action</span></div>
# <div class="de1">    <span class="kw1">if</span><span class="br0">(</span> <span class="sy0">!</span> isCheckable<span class="br0">(</span><span class="br0">)</span> <span class="br0">)</span></div>
# <div class="de1">        <span class="co1">// the action cannot be checked, simply emit</span></div>
# <div class="de2">        <span class="co1">// a triggered event</span></div>
# <div class="de1">        triggered<span class="br0">(</span><span class="br0">)</span><span class="sy0">;</span></div>
# <div class="de1">    <span class="kw1">else</span></div>
# <div class="de1">        <span class="kw1">if</span><span class="br0">(</span> isChecked<span class="br0">(</span><span class="br0">)</span> <span class="br0">)</span></div>
# <div class="de1">            <span class="co1">// the action is checked</span></div>
# <div class="de2">            emit actionChecked<span class="br0">(</span><span class="br0">)</span><span class="sy0">;</span></div>
# <div class="de1">        <span class="kw1">else</span></div>
# <div class="de1">            <span class="co1">// the action is unchecked</span></div>
# <div class="de1">            emit actionUnchecked<span class="br0">(</span><span class="br0">)</span><span class="sy0">;</span></div>
# <div class="de1"> </div>
# <div class="de2"><span class="br0">}</span></div>
</div>


==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:
<div class="cpp-qt geshi">
# <div class="de1">CheckableAction<span class="sy0">*</span> myAction <span class="sy0">=</span> <span class="kw1">new</span> CheckableAction<span class="br0">(</span> <span class="kw1">this</span> <span class="br0">)</span><span class="sy0">;</span></div>
# <div class="de1">    myAction<span class="sy0">-&gt;</span><span class="me3">setText</span><span class="br0">(</span> tr<span class="br0">(</span><span class="st0">"Action TEXT"</span><span class="br0">)</span> <span class="br0">)</span><span class="sy0">;</span></div>
# <div class="de1">    myAction<span class="sy0">-&gt;</span><span class="me3">setIcon</span><span class="br0">(</span> [http://doc.qt.io/QIcon.html <span class="kw5">QIcon</span>]<span class="br0">(</span><span class="st0">":/actions/img/myaction.png"</span><span class="br0">)</span> <span class="br0">)</span><span class="sy0">;</span></div>
# <div class="de1">    myAction<span class="sy0">-&gt;</span><span class="me3">setStatusTip</span><span class="br0">(</span> tr<span class="br0">(</span><span class="st0">"Check/Uncheck the action"</span><span class="br0">)</span> <span class="br0">)</span><span class="sy0">;</span></div>
# <div class="de2">    myAction<span class="sy0">-&gt;</span><span class="me3">setCheckable</span><span class="br0">(</span> <span class="kw2">true</span> <span class="br0">)</span><span class="sy0">;</span></div>
# <div class="de1">    <span class="kw2">connect</span><span class="br0">(</span> myAction<span class="sy0">,</span></div>
# <div class="de1">             SIGNAL<span class="br0">(</span>actionChecked<span class="br0">(</span><span class="br0">)</span><span class="br0">)</span><span class="sy0">,</span></div>
# <div class="de1">             <span class="kw1">this</span><span class="sy0">,</span></div>
# <div class="de1">             SLOT<span class="br0">(</span> slotActionUncheked<span class="br0">(</span><span class="br0">)</span><span class="br0">)</span> <span class="br0">)</span><span class="sy0">;</span></div>
# <div class="de2">    <span class="kw2">connect</span><span class="br0">(</span> myAction<span class="sy0">,</span></div>
# <div class="de1">             SIGNAL<span class="br0">(</span>actionUnchecked<span class="br0">(</span><span class="br0">)</span><span class="br0">)</span><span class="sy0">,</span></div>
# <div class="de1">             <span class="kw1">this</span><span class="sy0">,</span></div>
# <div class="de1">             SLOT<span class="br0">(</span>slotActionCheked<span class="br0">(</span><span class="br0">)</span><span class="br0">)</span> <span class="br0">)</span><span class="sy0">;</span></div>
</div>


===Categories:===
===Categories:===
Line 17: Line 127:
* [[:Category:HowTo|HowTo]]
* [[:Category:HowTo|HowTo]]
* [[:Category:snippets|snippets]]
* [[:Category:snippets|snippets]]
</div>

Revision as of 09:22, 23 February 2015

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.

Source Code

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

  1. #ifndef CHECKABLEACTION_H
  2. #define CHECKABLEACTION_H
  3.  
  4. #include <QAction>
  5. #include <QDebug>
  6.  
  7. /*!
  8.   * This class represents an action that will emit
  9.   * distinct signals depending on the check of the
  10.   * action itself.
  11.   */
  12. class CheckableAction : public QAction
  13. {
  14.     Q_OBJECT
  15. public:
  16.     explicit CheckableAction(QObject *parent = 0);
  17.  
  18. signals:
  19.  
  20.     /*!
  21.       * This signal is emitted each time the action is
  22.       * checked.
  23.       */
  24.     void actionChecked();
  25.  
  26.     /*!
  27.       * This signal is emitted each time the action is
  28.       * unchecked.
  29.       */
  30.     void actionUnchecked();
  31.  
  32.  
  33.  
  34. public slots:
  35.  
  36.  
  37. private slots:
  38.  
  39.     /*!
  40.       * This slot is used to forward (i.e., emit) a triggered
  41.       * event depending on the status of the action (i.e., if it
  42.       * has been checked or not).
  43.       * \param checked true if the action has been checked, false
  44.       * otherwise
  45.       */
  46.     void slotForwardCheckSignal( bool checked );
  47.  
  48. };
  49.  
  50. #endif // CHECKABLEACTION_H

and here the implementation of the class

  1. #include "checkableaction.h"
  2.  
  3. CheckableAction::CheckableAction(QObject *parent) :
  4.     QAction(parent)
  5. {
  6.     // auto connect the triggered event to the slot for
  7.     // forwarding the check status
  8.     connect( this,
  9.              SIGNAL(triggered(bool)),
  10.              this,
  11.              SLOT(slotForwardCheckSignal(bool)) );
  12. }
  13.  
  14. void CheckableAction::slotForwardCheckSignal(bool checked)
  15. {
  16.     qDebug() << "Action checked status " << checked;
  17.     // check the status of the action
  18.     if( ! isCheckable() )
  19.         // the action cannot be checked, simply emit
  20.         // a triggered event
  21.         triggered();
  22.     else
  23.         if( isChecked() )
  24.             // the action is checked
  25.             emit actionChecked();
  26.         else
  27.             // the action is unchecked
  28.             emit actionUnchecked();
  29.  
  30. }

Usage Example

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

  1. CheckableAction* myAction = new CheckableAction( this );
  2.     myAction->setText( tr("Action TEXT") );
  3.     myAction->setIcon( QIcon(":/actions/img/myaction.png") );
  4.     myAction->setStatusTip( tr("Check/Uncheck the action") );
  5.     myAction->setCheckable( true );
  6.     connect( myAction,
  7.              SIGNAL(actionChecked()),
  8.              this,
  9.              SLOT( slotActionUncheked()) );
  10.     connect( myAction,
  11.              SIGNAL(actionUnchecked()),
  12.              this,
  13.              SLOT(slotActionCheked()) );

Categories: