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.
Erweitern von QAction durch zusätzliche Signale
Einführung
QAction kann so konfiguriert werden, dass es checkable ist. Dies bedeutet, es kann einen binären Zustand, nämlich angewählt (checked) und nicht angewählt annehmen. Dies wird bspw. bei einem Pushbutton angezeigt, der runtergedrückt bleibt, nachdem man ihn einmal geklickt hat und erst wieder in den Ausgangszustand zurückkehrt, nachdem man ihn noch ein weiteres mal anklickt.
Das Problem mit QAction ist, dass es nur ein Signal sendet, wenn sich sein checked-Zustand geändert hat und in diesem Signal mit einem boolschen Attribut mitteilt, ob der Zustand nun checked ist oder nicht. Das bedeutet, wenn man eine Slot-Methode schreibt, die auf dieses Signal reagiert, muss man in diesem Slot erst gucken, wie der Zustand der QAction jetzt ist und dann kann man erst, basierend auf dieser Fallentscheidung, die gewünschte Funktion ausführen.
Es oft praktischer, wenn man 2 getrennte Signale hätte: Eins für "der Zustand ist jetzt checked" und eins für "er ist jetzt nicht checked". Weil QAction solche Signale nicht hat, bauen wir uns hier eine von QAction abgeleitete Klasse, die QAction um eben diese Signale erweitert.
Quelltext
Der Quelltext ist wirklich einfach. Dies ist die Header-Datei:
#ifndef CHECKABLEACTION_H
#define CHECKABLEACTION_H
#include <QAction>
#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 );
};
#endif // CHECKABLEACTION_H
Implementierung:
#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();
}
}
Beispiel zur Verwendung
Die neue Klasse wird genauso benutzt, wie eine QAction, bloß dass uns jetzt die 2 neuen Signale actionChecked() und actionUnchecked() zur Verfügung stehen.
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())
);