PushButton Based On Action: Difference between revisions

From Qt Wiki
Jump to navigation Jump to search
No edit summary
No edit summary
Line 1: Line 1:
[[Category:HowTo]]<br />[[Category:snippets]]
[[Category:HowTo]]
[[Category:snippets]]


= Creating a QPushButton component configured by a QAction =
= Creating a QPushButton component configured by a QAction =
Line 5: Line 6:
QPushButton does not allow itself to be configured by a QAction. In the case when you need to share a QAction among different components like menus, buttons, and so on, you can simply extend the QPushButton class with code similar to the following:
QPushButton does not allow itself to be configured by a QAction. In the case when you need to share a QAction among different components like menus, buttons, and so on, you can simply extend the QPushButton class with code similar to the following:


<code>#ifndef ACTIONBUTTON_H<br />#define ACTIONBUTTON_H
<code>#ifndef ACTIONBUTTON_H
#define ACTIONBUTTON_H


#include &lt;QPushButton&amp;gt;<br />#include &lt;QAction&amp;gt;
#include <QPushButton>
#include <QAction>


/*!<br /> '''An extension of a QPushButton that supports QAction.<br />''' This class represents a QPushButton extension that can be<br /> * connected to an action and that configures itself depending<br /> * on the status of the action.<br /> * When the action changes its state, the button reflects<br /> * such changes, and when the button is clicked the action<br /> * is triggered.<br /> '''/<br />class ActionButton : public QPushButton<br />{<br /> Q_OBJECT
/*!
<br />private:
'''An extension of a QPushButton that supports QAction.
<br /> /'''!<br /> * The action associated to this button.<br /> '''/<br /> QAction''' actionOwner;
''' This class represents a QPushButton extension that can be
* connected to an action and that configures itself depending
* on the status of the action.
* When the action changes its state, the button reflects
* such changes, and when the button is clicked the action
* is triggered.
*/
class ActionButton : public QPushButton
{
Q_OBJECT


public:<br /> /*!<br /> * Default constructor.<br /> * parent the widget parent of this button<br /> */<br /> explicit ActionButton(QWidget '''parent = 0);
private:
<br /> /'''!<br /> * Sets the action owner of this button, that is the action<br /> * associated to the button. The button is configured immediatly<br /> * depending on the action status and the button and the action<br /> * are connected together so that when the action is changed the button<br /> * is updated and when the button is clicked the action is triggered.<br /> * action the action to associate to this button<br /> '''/<br /> void setAction( QAction''' action );
 
/*!
* The action associated to this button.
*/
QAction''' actionOwner;
 
public:
/*!
* Default constructor.
* parent the widget parent of this button
*/
explicit ActionButton(QWidget '''parent = 0);
 
/*!
* Sets the action owner of this button, that is the action
* associated to the button. The button is configured immediatly
* depending on the action status and the button and the action
* are connected together so that when the action is changed the button
* is updated and when the button is clicked the action is triggered.
* action the action to associate to this button
*/
void setAction( QAction''' action );


signals:
signals:


public slots:<br /> /*!<br /> * A slot to update the button status depending on a change<br /> * on the action status. This slot is invoked each time the action<br /> * &quot;changed&amp;quot; signal is emitted.<br /> */<br /> void updateButtonStatusFromAction();
public slots:
/*!
* A slot to update the button status depending on a change
* on the action status. This slot is invoked each time the action
* "changed" signal is emitted.
*/
void updateButtonStatusFromAction();


};
};


#endif // ACTIONBUTTON_H<br /></code>
#endif // ACTIONBUTTON_H
</code>


The idea is to extend QPushButton and to provide a ''setAction'' method that will immediately configure the button itself with the action data. After that, the button will connect to the action, so that when the button is clicked the action is triggered and vice-versa: when the action is changed the button is re-configured.
The idea is to extend QPushButton and to provide a ''setAction'' method that will immediately configure the button itself with the action data. After that, the button will connect to the action, so that when the button is clicked the action is triggered and vice-versa: when the action is changed the button is re-configured.
Line 28: Line 68:
The following is the implementation:
The following is the implementation:


<code>#include &quot;actionbutton.h&amp;quot;
<code>#include "actionbutton.h"


ActionButton::ActionButton(QWidget *parent) :<br /> QPushButton(parent)<br />{<br /> actionOwner = NULL;<br />}
ActionButton::ActionButton(QWidget *parent) :
QPushButton(parent)
{
actionOwner = NULL;
}


void ActionButton::setAction(QAction *action)<br />{
void ActionButton::setAction(QAction *action)
{


// if I've got already an action associated to the button<br /> // remove all connections
// if I've got already an action associated to the button
// remove all connections


if( actionOwner [[Image:= NULL &amp;&amp; actionOwner |= NULL &amp;&amp; actionOwner ]]= action ){<br /> disconnect( actionOwner,<br /> SIGNAL (changed()),<br /> this,<br /> SLOT (updateButtonStatusFromAction()) );
if( actionOwner [[Image:= NULL &amp;&amp; actionOwner |= NULL &amp;&amp; actionOwner ]]= action ){
disconnect( actionOwner,
SIGNAL (changed()),
this,
SLOT (updateButtonStatusFromAction()) );


disconnect( this,<br /> SIGNAL (clicked()),<br /> actionOwner,<br /> SLOT (trigger()) );<br /> }
disconnect( this,
SIGNAL (clicked()),
actionOwner,
SLOT (trigger()) );
}


// store the action<br /> actionOwner = action;
// store the action
actionOwner = action;


// configure the button<br /> updateButtonStatusFromAction();
// configure the button
updateButtonStatusFromAction();


// connect the action and the button<br /> // so that when the action is changed the<br /> // button is changed too!<br /> connect( action,<br /> SIGNAL (changed()),<br /> this,<br /> SLOT (updateButtonStatusFromAction()));
// connect the action and the button
// so that when the action is changed the
// button is changed too!
connect( action,
SIGNAL (changed()),
this,
SLOT (updateButtonStatusFromAction()));


// connect the button to the slot that forwards the<br /> // signal to the action<br /> connect( this,<br /> SIGNAL (clicked()),<br /> actionOwner,<br /> SLOT (trigger()) );<br />}
// connect the button to the slot that forwards the
// signal to the action
connect( this,
SIGNAL (clicked()),
actionOwner,
SLOT (trigger()) );
}


void ActionButton::updateButtonStatusFromAction()<br />{<br /> setText( actionOwner-&gt;text() );<br /> setStatusTip( actionOwner-&gt;statusTip() );<br /> setToolTip( actionOwner-&gt;toolTip() );<br /> setIcon( actionOwner-&gt;icon() );<br /> setEnabled( actionOwner-&gt;isEnabled() );<br /> setCheckable( actionOwner-&gt;isCheckable() );<br /> setChecked( actionOwner-&gt;isChecked());
void ActionButton::updateButtonStatusFromAction()
{
setText( actionOwner->text() );
setStatusTip( actionOwner->statusTip() );
setToolTip( actionOwner->toolTip() );
setIcon( actionOwner->icon() );
setEnabled( actionOwner->isEnabled() );
setCheckable( actionOwner->isCheckable() );
setChecked( actionOwner->isChecked());


}
}


</code>
</code>

Revision as of 10:03, 25 February 2015


Creating a QPushButton component configured by a QAction

QPushButton does not allow itself to be configured by a QAction. In the case when you need to share a QAction among different components like menus, buttons, and so on, you can simply extend the QPushButton class with code similar to the following:

#ifndef ACTIONBUTTON_H
#define ACTIONBUTTON_H

#include <QPushButton>
#include <QAction>

/*!
 '''An extension of a QPushButton that supports QAction.
''' This class represents a QPushButton extension that can be
 * connected to an action and that configures itself depending
 * on the status of the action.
 * When the action changes its state, the button reflects
 * such changes, and when the button is clicked the action
 * is triggered.
 */
class ActionButton : public QPushButton
{
 Q_OBJECT

private:

 /*!
 * The action associated to this button.
 */
 QAction''' actionOwner;

public:
 /*!
 * Default constructor.
 * parent the widget parent of this button
 */
 explicit ActionButton(QWidget '''parent = 0);

 /*!
 * Sets the action owner of this button, that is the action
 * associated to the button. The button is configured immediatly
 * depending on the action status and the button and the action
 * are connected together so that when the action is changed the button
 * is updated and when the button is clicked the action is triggered.
 * action the action to associate to this button
 */
 void setAction( QAction''' action );

signals:

public slots:
 /*!
 * A slot to update the button status depending on a change
 * on the action status. This slot is invoked each time the action
 * "changed" signal is emitted.
 */
 void updateButtonStatusFromAction();

};

#endif // ACTIONBUTTON_H

The idea is to extend QPushButton and to provide a setAction method that will immediately configure the button itself with the action data. After that, the button will connect to the action, so that when the button is clicked the action is triggered and vice-versa: when the action is changed the button is re-configured.

The following is the implementation:

#include "actionbutton.h"

ActionButton::ActionButton(QWidget *parent) :
 QPushButton(parent)
{
 actionOwner = NULL;
}

void ActionButton::setAction(QAction *action)
{

// if I've got already an action associated to the button
 // remove all connections

if( actionOwner [[Image:= NULL &amp;&amp; actionOwner |= NULL &amp;&amp; actionOwner ]]= action ){
 disconnect( actionOwner,
 SIGNAL (changed()),
 this,
 SLOT (updateButtonStatusFromAction()) );

disconnect( this,
 SIGNAL (clicked()),
 actionOwner,
 SLOT (trigger()) );
 }

// store the action
 actionOwner = action;

// configure the button
 updateButtonStatusFromAction();

// connect the action and the button
 // so that when the action is changed the
 // button is changed too!
 connect( action,
 SIGNAL (changed()),
 this,
 SLOT (updateButtonStatusFromAction()));

// connect the button to the slot that forwards the
 // signal to the action
 connect( this,
 SIGNAL (clicked()),
 actionOwner,
 SLOT (trigger()) );
}

void ActionButton::updateButtonStatusFromAction()
{
 setText( actionOwner->text() );
 setStatusTip( actionOwner->statusTip() );
 setToolTip( actionOwner->toolTip() );
 setIcon( actionOwner->icon() );
 setEnabled( actionOwner->isEnabled() );
 setCheckable( actionOwner->isCheckable() );
 setChecked( actionOwner->isChecked());

}