search
LoginSignup
1

posted at

Qt でGUI - ウィジェットを作る -

ユーザーの操作に対応するボタンの設置

GUIを作るからにはマウスのクリックなどのユーザーの操作と結びついて, 何かしらのプログラムが実行されるようにしなければ意味がない. 今回はGUI上にボタンを設置して, ユーザーがそのボタンをクリックしたらウィンドウを抜けるというプログラムを作ってみる.
以下の本を参考にしています. インストールされているのがQt6 なのでinclude の場所が少し違うだけで基本的にはQt4 と同じ記述です.
Qt4 プログラミング入門

シグナルとスロット

Qt での言葉の定義として, シグナルとスロットがある

  • シグナル : ユーザー操作によるオブジェクトの状態変化.
  • スロット : シグナルが送信されたときに行われる関数.

言葉だけを見てもわかりにくいが, 具体例を見てみると簡単なこと.
GUI 上にボタン (オブジェクト) があるとする.
ボタンに対してマウスでクリックという操作が行われると, ボタンというオブジェクトは「押されていない状態から押された」というように状態が変化する. このようなユーザー操作によるオブジェクトの状態変化をQt内部ではclicked() というシグナル関数が発生する.
このclicked 関数(シグナル関数)にプロラグムを終了させるquit 関数(スロット関数)を接続しておくと,
シグナル関数が発生したときにquit 関数が実行されて, アプリケーションが終了する.

シグナルとスロットの接続

quit.cpp といしてファイルを作る.

quit.cpp
#include <QtWidgets/QApplication>
#include <QtWidgets/QPushButton>

int main(int argc, char *argv[]) {
  QApplication app(argc, argv);
  auto *button = new QPushButton("Quit");
  QObject::connect(button, SIGNAL(clicked()), &app, SLOT(quit()));
  button->show();
  return app.exec();
}

ボタンの設置には, QtWidgets/QPushButton オブジェクトを使う.

QPushButton *button = new QPushButton("Quit");

引数でボタンに表示される文字列を指定できる.
オブジェクトで生成されるシグナル関数とスロット関数は

QObject::connect(button, SIGNAL(clicked()), &app, SLOT(quit()));

のようにQObject クラスのconnect 関数で接続する.
後はビルドする.

$ qmake -project

生成されたquit.pro の最終行に QT+=widgets を追加して,

$ qmake quit.pro
$ make
$ ./quit.app/Contents/MacOS/quit

とすれば, 以下のようにボタンができる.
ボタン上でクリックすれば, アプリケーションが終了する.
スクリーンショット 2023-01-11 16.43.00.png

2つ以上のウィジェットの配置

1つのウィンドウに2 つ以上のウィジェットを並べる際には,

Qwidget()

で親オブジェクトを作って, その中に子ウィジェットを配置する.
以下ではwindows という親オブジェクトを作って,その中にQspinBox とQslider を配置していく.
また, QspinBox の値とQSlider が同期するようにそれぞれシグナル関数とスロット関数を接続している.

widget.cpp
#include <QtWidgets/QApplication>
#include <QtWidgets/QHBoxLayout>
#include <QtWidgets/QSlider>
#include <QtWidgets/QSpinBox>

int main(int argc, char *argv[]){
  QApplication app(argc, argv);
  auto *window = new QWidget();
  window-> setWindowTitle("Enter your Age");

  auto *spinbox = new QSpinBox();
  auto *slider = new QSlider(Qt::Horizontal);
  spinbox->setRange(0, 130);
  slider->setRange(0, 130);

  QObject::connect(spinbox, SIGNAL(valueChanged(int)),slider,SLOT(setValue(int)));
  QObject::connect(slider, SIGNAL(valueChanged(int)),spinbox,SLOT(setValue(int)));
  spinbox->setValue(29);

  auto *layout = new QHBoxLayout();
  layout->addWidget(spinbox);
  layout->addWidget(slider);
  window->setLayout(layout);
  window->show();
  return app.exec();
}

ウィジェットの配置については,

auto *layout = new QHBoxLayout();

の部分でまずはウィジェットを左から右に配置するレイアウトを指定している.
もちろん他のレイアウトもあり, 主には以下があるらしい.

  • QVBoxLayout : 上から下に
  • QGridLayout : 格子状に
  • QHBoxLayout : 左から右に

ウィジェットの格納は,

layout->addWidget();

の部分で行われており, 今回は左からボックス, スライダーというようになるはず.
このように設定したレイアウトを

window->setlayput(layout);

としてセットして無事に終了.

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
1