今回は,
マウスイベント遷移
前回取り上げたシグナル遷移はステートマシンフレームワークのリファレンスで,
マウスイベント遷移の説明のためにEventWidgetウィジェットを作りました。このウィジェットは,
リスト1 eventwidget.
1: #ifndef EVENTWIDGET_H
2: #define EVENTWIDGET_H
3:
4: #include <QWidget>
5:
6: class EventWidgetPrivate;
7:
8: class EventWidget : public QWidget
9: {
10: Q_OBJECT
11: Q_DECLARE_PRIVATE( EventWidget )
12: Q_PROPERTY( QString text READ text WRITE setText )
13:
14: public:
15: explicit EventWidget( QWidget* parent = 0 );
16: ~EventWidget();
17: QString text() const;
18: QSize sizeHint() const;
19:
20: public slots:
21: void setText( const QString& text );
22:
23: protected:
24: void paintEvent( QPaintEvent* event );
25:
26: private:
27: EventWidgetPrivate* d_ptr;
28: };
29:
30: #endif
EventWidgetのヘッダです。今までも見て来たように,
リスト2 eventwidget.
1: #include <QStateMachine>
2: #include <QPainter>
3: #include <QPaintEvent>
4: #include <QEventTransition>
5:
6: #include "eventwidget.h"
7:
8: class EventWidgetPrivate
9: {
10: public:
11: EventWidgetPrivate() {}
12:
13: QString text;
14: };
15:
16: EventWidget::EventWidget( QWidget* parent )
17: : QWidget( parent ), d_ptr( new EventWidgetPrivate )
18: {
19: QPalette palette = this->palette();
20: palette.setColor( QPalette::Window, Qt::gray );
21: palette.setColor( QPalette::Normal, QPalette::WindowText, Qt::green );
22: palette.setColor( QPalette::Disabled, QPalette::WindowText, Qt::red );
23: setPalette( palette );
24: setAutoFillBackground( true );
25:
背景色を灰色にするには,
有効化と無効化の各状態でのテキストの色は,
26: setSizePolicy( QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding );
27:
28: QStateMachine* stateMachine = new QStateMachine( this );
29:
30: QState* idleState = new QState;
31: idleState->setObjectName( "idle" );
32: idleState->assignProperty( this, "text", "Idle" );
33:
34: QState* pressedState = new QState;
35: pressedState->setObjectName( "pressed" );
36: pressedState->assignProperty( this, "text", "Pressed" );
37:
通常状態とボタンが押されている状態を用意しています。
38: QEventTransition* pressTransition = new QEventTransition( this, QEvent::MouseButtonPress, idleState );
39: pressTransition->setTargetState( pressedState );
40:
41: QEventTransition* dblClickTransition = new QEventTransition( this, QEvent::MouseButtonDblClick, idleState );
42: dblClickTransition->setTargetState( pressedState );
43:
44: QEventTransition* releaseTransition = new QEventTransition( this, QEvent::MouseButtonRelease, pressedState );
45: releaseTransition->setTargetState( idleState );
46:
本連載の第4回
#include <QMouseEventTransition>
...
EventWidget::EventWidget( QWidget* parent )
: QWidget( parent ), d_ptr( new EventWidgetPrivate )
{
...
QMouseEventTransition* pressTransition = new QMouseEventTransition( this, QEvent::MouseButtonPress, Qt::LeftButton, idleState );
pressTransition->setTargetState( pressedState );
QMouseEventTransition* dblClickTransition = new QMouseEventTransition( this, QEvent::MouseButtonDblClick, Qt::LeftButton, idleState );
dblClickTransition->setTargetState( pressedState );
QMouseEventTransition* releaseTransition = new QMouseEventTransition( this, QEvent::MouseButtonRelease, Qt::LeftButton, pressedState );
releaseTransition->setTargetState( idleState );
QEventTransitionの代わりにそのサブクラスのQMouseEventTransitionを使うと上記のように書けて,
47: stateMachine->addState( idleState );
48: stateMachine->addState( pressedState );
49:
50: stateMachine->setInitialState( idleState );
51:
52: stateMachine->start();
53: }
54:
ステートマシンの動かし方は今まで通りです。
68: {
69: Q_D( EventWidget );
70:
71: if ( d->text == text )
72: return;
73:
74: d->text = text;
75: update();
76: updateGeometry();
77: }
78:
textプロパティのゲッターとセッターで,
79: QSize EventWidget::sizeHint() const
80: {
81: Q_D( const EventWidget );
82:
83: return fontMetrics().boundingRect( d->text ).size();
84: }
85:
テキストが表示される最小限の大きさをsizeHint()で返すようにして,
86: void EventWidget::paintEvent( QPaintEvent* event )
87: {
88: Q_D( EventWidget );
89: Q_UNUSED( event );
90:
91: QPainter painter( this );
92: painter.drawText( rect(), Qt::AlignCenter, d->text );
93: }
前述したようにパレットで背景色と状態に合わせた色を設定しているので,
リスト3 main.
1: #include <QApplication>
2: #include <QLayout>
3:
4: #include "eventwidget.h"
5:
6: class Harness : public QWidget
7: {
8: Q_OBJECT
9:
10: public:
11: Harness();
12: };
13:
14: Harness::Harness()
15: : QWidget( 0 )
16: {
17: EventWidget* firstWidget = new EventWidget;
18: EventWidget* secondWidget = new EventWidget;
19: secondWidget->setEnabled( false );
20:
21: QVBoxLayout* topLayout = new QVBoxLayout;
22: topLayout->addWidget( firstWidget );
23: topLayout->addWidget( secondWidget );
24:
25: setLayout( topLayout );
26: }
27:
28: int main( int argc, char** argv )
29: {
30: QApplication app( argc, argv );
31:
32: Harness harness;
33: harness.show();
34:
35: return app.exec();
36: }
37:
38: #include "main.moc"
有効化と無効化の両状態のEventWidgetを表示して動作を確認するコードです。図2のように無効化されていてもマウスイベント遷移が起きます。
これはウィジェットのイベントへの振舞いを考えると,
QMouseEventTransition( QObject* object, QEvent::Type type, Qt::MouseButtonbutton, QState* sourceState = 0 )
QObjectである必要はであるでしょう。しかし,