このサイトは、只今WEB業界で活躍中のデザイナー、プログラマーの方々の情報を集めたweb統合情報サイトです。

Archives Details

Macで、Qt5 開発 QPushButton、QSliderなどウィジェット作成

C++

2020.12.13

この記事は最終更新日から1年以上が経過しています。

どもです。今回もまたまたQtを扱っていこうかなと、言う事で、

だいぶん前から積み本となっているこちらの書籍を参考に、ウィジェットを作成していきたいと思います。

created by Rinker
¥4,180 (2024/04/16 11:32:56時点 Amazon調べ-詳細)

ですが、こちらの書籍見て分かるように、「Qt4」に書かれた書籍でして、初版発売は2007年と実に13年前の書籍と言うこともあって、現状のバージョンQt5で動かそうとしても、そのままでは動かなかったりしますので、手を加えながら作成していきたいと思います。

開発環境
  • Mac OS 10.14.5
  • Homebrew 2.6.0
  • Apple clang version 11.0.0
  • Qt 5.15.2

QPushButtonの表示

まずは、以下の様にボタンの表示から。

QPushButtonを用いて表示させます。

main.cpp

#include <QtWidgets/QApplication>
#include <QPushButton>

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

シンプルにmain.cppの1ファイルのみのプログラムです。

作成したら、以下のコマンドでビルド。

$ qmake -project 
$ qmake ●●●●●.pro 
$ make 

「pushbutton」の名前でディレクトリを作成していた場合、以下の様に起動ファイルが生成されるので実行。

$ ./pushbutton.app/Contents/MacOS/pushbutton
SIGNAL(シグナル)とSLOT(スロット)

ここで抑えるべき所は「シグナルとスロット」ですかね。

Qtのウィジェットでは、ユーザーが操作を行ったり、状態が変化すると「シグナル」を送信する様に設計されている様です。

上記では、clicked()と言うシグナルを送信します。

シグナル」は「スロット」に結び付けられることができ、上記では「シグナル」に対して、「スロット」のquit()関数に結びついているので、ボタンをクリックすることによって、ウィジェットを閉じる事ができます。

前回の記事のMacで、Qt5をbrew installしてサクッと起動する。でも書いたのですが、Qt5では、QApplicationは以下の include記述で、

#include <QtWidgets/QApplication>

〇〇〇.proファイルの末尾に以下の追記が必要です。

QT+=widgets

QSliderなど含んだウィジェットのレイアウト

続いては、spinとsliderが連動しているウィジェットです。

main.cpp

#include <QtWidgets/QApplication>
#include <QHBoxLayout>
#include <QSlider>
#include <QSpinBox>

int main(int argc, char *argv[]) {
    QApplication app(argc, argv);

    QWidget *window = new QWidget;
    window->setWindowTitle("Enter Your Age");

    QSpinBox *spinBox = new QSpinBox;
    QSlider *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)));

    QHBoxLayout *layout = new QHBoxLayout;
    layout->addWidget(spinBox);
    layout->addWidget(slider);
    window->setLayout(layout);

    window->show();
    return app.exec();
}

ここでの注目しておく所は、 まず、QSpinBoxとQSliderのオブジェクトを生成し、それぞれsetRange関数を用いて、0〜130まで値を扱える様に設定しています。

その後、QObject::connectを用いてspinBoxとsliderを連動する様に設定しています。

spinBoxの値が変更されれば、sliderの方にも値がセットされ、sliderの値が変更されれば、sliderの方にも値がセットされます。

お互いのシグナルに対してスロットで受け取り、setValue関数で代入されています。

そうすることによって、連動させる事が可能となっております。

また、最後、QHBoxLayoutで横並びのレイアウトを実装しているのですが、QLayoutは以下の様なレイアウトマネージャが用意されています。

 

  • QHBoxLayout: ウィジェットを左から右に配置。
  • QVBoxLayout: ウィジェットを上から下に配置。
  • QGridLayout: ウィジェットを格子状に配置。

 

検索フォームなど含んだウィジェット

と言う事で、最後のウィジェットは、以下の様な検索フォームを想定したウィジェットです。

今まで、「main.cpp」ファイルのみで生成して来たのですが、ここでは他にも流用できる様に独立したコンポーネントとして作成していく形となります。

なので、「finddialog.h」「finddialog.cpp」に、ウィジェットのクラスを作成していきます。

 

finddialog.h

#ifndef FINDDIALOG_H
#define FINDDIALOG_H

#include <QtWidgets/QDialog>

class QCheckBox;
class QLabel;
class QLineEdit;
class QPushButton;

class FindDialog : public QDialog
{
    Q_OBJECT

    public:
        FindDialog(QWidget *parent = 0);

    signals:
        void findNext(const QString &str, Qt::CaseSensitivity cs);
        void findPrevious(const QString &str, Qt::CaseSensitivity cs);

    private slots:
        void findClicked();
        void enableFindButton(const QString &text);

    private:
        QLabel *label;
        QLineEdit *lineEdit;
        QCheckBox *caseCheckBox;
        QCheckBox *backwardCheckBox;
        QPushButton *findButton;
        QPushButton *closeButton;
};

#endif

#ifndef FINDDIALOG_H、#define FINDDIALOG_H で、複数回のインクルードを防いでます。

FindDialogクラスを作成。signalsで2つのシグナルを宣言。Searchbackwardオプションありで、findPreviousシグナル、そうでなければfindNextシグナル送信する設定です。

private箇所に、2つのスロットを宣言。スロット実装の際にダイアログの子ウィジェットの多くアクセスする為、ウィジェットのポインタも宣言しています。

続いて、「finddialog.cpp」ファイルで実装。

finddialog.cpp

#include <QtGui>
#include <QtWidgets>

#include "finddialog.h"

FindDialog::FindDialog(QWidget *parent): QDialog(parent)
{
    label = new QLabel(tr("Find &what:"));
    lineEdit = new QLineEdit;
    label->setBuddy(lineEdit);

    caseCheckBox = new QCheckBox(tr("Match &case"));
    backwardCheckBox = new QCheckBox(tr("Search &backward"));

    findButton = new QPushButton(tr("&Find"));
    findButton->setDefault(true);
    findButton->setEnabled(false);

    closeButton = new QPushButton(tr("Close"));

    connect(lineEdit, SIGNAL(textChanged(const QString &)), this, SLOT(enableFindButton(const QString &)));
    connect(findButton, SIGNAL(clicked()), this, SLOT(findClicked()));
    connect(closeButton, SIGNAL(clicked()), this, SLOT(close()));

    QHBoxLayout *topLeftLayout = new QHBoxLayout;
    topLeftLayout->addWidget(label);
    topLeftLayout->addWidget(lineEdit);

    QVBoxLayout *leftLayout = new QVBoxLayout;
    leftLayout->addLayout(topLeftLayout);
    leftLayout->addWidget(caseCheckBox);
    leftLayout->addWidget(backwardCheckBox);

    QVBoxLayout *rightLayout = new QVBoxLayout;
    rightLayout->addWidget(findButton);
    rightLayout->addWidget(closeButton);
    rightLayout->addStretch();

    QHBoxLayout *mainLayout = new QHBoxLayout;
    mainLayout->addLayout(leftLayout);
    mainLayout->addLayout(rightLayout);
    setLayout(mainLayout);

    setWindowTitle(tr("Find"));
    setFixedHeight(sizeHint().height());
}

void FindDialog::findClicked()
{
    QString text = lineEdit->text();
    Qt::CaseSensitivity cs = caseCheckBox->isChecked() ? Qt::CaseSensitive : Qt::CaseInsensitive;

    if (backwardCheckBox->isChecked()) {
        emit findPrevious(text, cs);
    } else {
        emit findNext(text, cs);
    }
}

void FindDialog::enableFindButton(const QString &text) {
    findButton->setEnabled(!text.isEmpty());
}

trメソッドは、文字列を他の言語用に翻訳する為にマーキングしています。

connect箇所を見ていくと、テキストボックスの内容が変更される度にプライベートなenableFindButtonスロットを呼び出し、ボタンのenabele、disableを監視している形です。

同様に、findButtonを押下で、findClicked()呼び出し、closeButtonを押下でclose()呼び出し終了しています。

FindDialogはQObjectの子孫クラスという事で、connectメソッドの前にQObject::を付ける必要がない。

QHBoxLayout〜からは、QHBoxLayoutやQVBoxLayoutなどのレイアウトマネージャを用いてウィジェットをレイアウト。

findClicked()メソッドは、Search backwardオプションありで、findPrevious()シグナル、そうでなければfindNext()を送信させる処理。

enableFindButton()メソッドは、テキストボックスの内容有り無しで、enabele、disableを変更。

 

main.cpp」で、上記のFindDialogウィジェットを呼び出します。

 

main.cpp

#include <QtWidgets/QApplication>

#include "finddialog.h"

int main(int argc, char *argv[]) {
    QApplication app(argc, argv);
    FindDialog *dialog = new FindDialog;
    dialog->show();
    return app.exec();
}

という事で、Qtのウィジェットを作成してみました。

次は、QtCreatorを扱っていきたいと思います。

Comment

Related Article

【Qt】Mac開発 ソートダイアログ (拡張するダイアログ)を作成

2021.04.01

【Qt】Macの、Qt Creatorで Dialog GUI作成

2020.12.29

【Qt】Macで、Qt Creatorをbrew installしてサクッと起動する。

2020.12.14

Macで、Qt5 開発 QPushButton、QSliderなどウィジェット作成

2020.12.13

Macで、Qt5をbrew installしてサクッと起動する。

2020.12.02

Webassembly用いて、SDL 2.0をブラウザでレンダリング

2020.08.10

MacOS Mojave (10.14.4)の Xcode に、過去のMacOSのSDKをインストール

2019.05.19

CMake インストール 使い方

2016.07.06

CATEGORY LIST

LATEST NEWS

Rust - Actix Web mongo ユーザー登録 JWT認証

Rust

2024.03.24

Rust - Actix Web JWT 認証認可 APIの作成

Rust

2024.02.25

Rust - Actix Web × JSON 静的ファイルをAPIで返却

Rust

2024.01.19

Rust - Actix Web × MongoDB環境をサクッと起動

Rust

2024.01.18

5分で学ぶ RustでWave Function Collapse (波動関数崩壊アルゴリズム)

Rust

2024.01.15

LLaMAモデル GGMLフォーマット(llama.cpp)をRustフレームワーク Leptosを用いて M1MacMiniでサクッと動かす。

Rust

2024.01.11

2024年 狙っているモバイルノートPC

tool

2024.01.07

MacOS XcodeにSDL2を追加

tool

2023.12.26

php 7.4にアップデート

PHP

2023.12.24

5分で覚える Flutter Flameで作る Wave Function Collapse - 波動関数崩壊アルゴリズム

AI・Bot・algorithm

2023.12.20

Flutter - Flameでゲーム作成 (キャラクターの移動)

Flutter

2023.07.23

Flutterで作る ChatGPT Prompt Manager

Flutter

2023.07.12

RANKING

Follow

SPONSOR

現在、掲載募集中です。



Links

About Us

WEBデザイナーの、WEBデザイナーによる、WEBデザイナーの為のサイト。「みんなで書こう!」と仲間を募ってみたが、結局書くのは自分だけとなってしまいました。日々のメモを綴っていきます。

Entry Profile

Graphical FrontEnd Engineer
- Daisuke Takayama

MAD CITY 北九州市で生まれ育つ。20代はバンド活動に明け暮れ、ふと「webデザイナーになりたい。」と思い、デジタルハリウッド福岡校入学。卒業後、数々の賞を受賞、web業界をざわつかせる。
現在、主に、ゲーム制作中心に港区六本木界隈で活動中。

FOLLOW US