Extending QAction by emitting additional Signals/de

From Qt Wiki
Jump to navigation Jump to search


Deutsch | English

Wie man eine Klasse von QAction ableitet, sodass sie Checked/Unchecked-Signale sendet

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 angeklickt hat.

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


Und hier folgt nun die Implementierung der Klasse:

#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

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

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()) );