Qt をはじめよう! 第20回: Qt のイベントの仕組みと描画を学ぼう

👉 Part 1: QMLの基本

👉 Part 2: 簡単なアプリケーション作成デモ

 

 

無料eランニングプラットフォームQt アカデミーも日本語コース用意していますので、ぜひご確認ください!


前回 は QLineEdit の派生クラスと、Qt デザイナフォームクラスを作成しデザイナから使う方法を学びました。
今回は全く新しいウィジェットの作成を通じて Qt のイベントの仕組みを学びましょう。

 

イベント

Qt にはオブジェクト間の通信を 第10回 で学んだ シグナル/スロットという仕組みを使用しますが、システムからの様々な情報の通知やアプリケーション全体への通知などはイベントという仕組みを通じて行われます。

各イベントの情報は [qt QEvent] クラスやその派生クラスとして提供され、イベントの種類は [qt QEvent type] で取得することができます。
以下に使用頻度の高いと思われるイベントの例をあげます。全ての一覧は [qt "QEvent::Type のドキュメント" l=qevent m=#Type-enum] に掲載されています。

グループ 動作 [qt "QEvent::Type" l=qevent m=#Type-enum] イベントの情報を提供するクラス
マウス ボタンが押された QEvent::MouseButtonPress [qt QMouseEvent]
ボタンが離された QEvent::MouseButtonRelease
ポインタの移動の通知 QEvent::MouseMove
ホイールの回転の通知 QEvent::Wheel [qt QWheelEvent]
キーボード キーが押された QEvent::KeyPress [qt QKeyEvent]
キーが離された QEvent::KeyRelease
ウィジェット
(ウィンドウ)
表示された QEvent::Show [qt QShowEvent]
非表示になった QEvent::Hide [qt QHideEvent]
閉じられた QEvent::Close [qt QCloseEvent]
移動した QEvent::Move [qt QMoveEvent]
サイズが変わった QEvent::Resize [qt QResizeEvent]
(再)描画の要求 QEvent::Paint [qt QPaintEvent]
システム、
アプリケーション
表示言語がの変更の通知 QEvent::LanguageChanged QEvent
ロケールの変更の通知 QEvent::LocaleChange
       
       

イベントハンドラ

イベントは [qt QApplication] (GUI が無い場合は [qt QCoreApplication]) によって管理され、適切なオブジェクト(QObject の派生クラス)に対して自動的に通知されます。シグナル/スロットの接続のような明示的な操作は必要ありません。

イベントハンドラは QObject に仮想関数「bool [qt "event" l=qobject m=#event](QEvent*)」として実装されていて、イベントの処理をする際には派生クラスでこのメソッドを再実装します。また、使用頻度の高いイベントについては QWidget で専用のハンドラが用意されています。以下が一例になりますが、詳細は [qt "QWidget::event() のドキュメント" l=qwidget m=#event] を参照してください。

  • void [qt "mousePressEvent" l=qwidget m=#mousePressEvent](QMouseEvent *)
  • void [qt "mouseReleaseEvent" l=qwidget m=#mouseReleaseEvent](QMouseEvent *)
  • void [qt "mouseMoveEvent" l=qwidget m=#mouseMoveEvent](QMouseEvent *)
  • void [qt "wheelEvent" l=qwidget m=#wheelEvent](QWheelEvent *)
  • void [qt "keyPressEvent" l=qwidget m=#keyPressEvent](QKeyEvent *)
  • void [qt "keyReleaseEvent" l=qwidget m=#keyReleaseEvent](QKeyEvent *)
  • void [qt "showEvent" l=qwidget m=#showEvent](QShowEvent *)
  • void [qt "hideEvent" l=qwidget m=#hideEvent](QHideEvent *)
  • void [qt "closeEvent" l=qwidget m=#closeEvent](QCloseEvent *)
  • void [qt "moveEvent" l=qwidget m=#moveEvent](QMoveEvent *)
  • void [qt "resizeEvent" l=qwidget m=#resizeEvent](QResizeEvent *)
  • void [qt "paintEvent" l=qwidget m=#paintEvent](QPaintEvent *)

それでは新しいウィジェットを作成し、イベントに応じた処理を実装してみましょう。

新しいウィジェットの作成

Qt で新たなウィジェットを作成する際には QWidget の派生クラスを作成します。それでは QWidget の派生クラス Widget を作成しましょう。前回作成した promotion プロジェクトを使用し、ウィンドウの一番下にここで作成する Widget ウィジェットを配置します。

* File → New ...
...
** Qt デザイナクラス でない
...
Widget inherits QWidget
...

* Promotion に QWidget を追加し Widget に格上げ

// SS

サイズ情報の設定

Qt のウィジェットでは様々なサイズに関する情報が扱われます。
...
QSize sizeHint() const を実装
QSize minumumSizeHiint() const を実装?

その他 sizePolicy, minimumSize, maximumSize, ...

paintEvent でウィジェットの描画をしよう

Qt でウィジェットに描画する場合、paintEvent を再実装し、その中で描画をする必要があります。
paintEvent は描画が必要な際にイベントシステムから呼ばれます。

作成した Widget で QWidget の paintEvent をオーバーライドし、簡単な描画をしてみましょう。

widget.h

protected:
void paintEvent(QPaintEvent *e);

QWidget::paintEvent に合わせて protected のスコープに宣言をしています。

widget.cpp

#include <QPainter>

...

void Widget::paintEvent(QPaintEvent *e)
{
QPainter p(this);
p.drawRect(
p.drawText(0, 0, "Hello World!");
}

// SS

描画を更新しよう

[qt QWidget update] ([qt QWidget repaint]) [qt QTimer] で angle を変える?

おわりに

次回はマウス/キーです。


Blog Topics:

Comments