Qt6とC++でシグナルとスロット

C++ コンピュータ
C++

ウィンドウにボタンをレイアウトし、ボタンを押すことでボタンの文字が変化するサンプルプログラムを作成しました。

ソースコード

ファイル名:datasource.h

#ifndef DATASOURCE_H
#define DATASOURCE_H

#include <QObject>
#include <QString>

class DataSource : public QObject {
    Q_OBJECT
    Q_PROPERTY(QString data READ data WRITE setData NOTIFY dataChanged)

public:
    explicit DataSource(const QString& initialData, QObject* parent = nullptr);

    QString data() const;
    void setData(const QString& newData);

signals:
    void dataChanged(const QString& newData);

private:
    QString m_data;
};

#endif // DATASOURCE_H

ファイル名:datasource.cpp

#include "datasource.h"

DataSource::DataSource(const QString& initialData, QObject* parent)
    : QObject(parent), m_data(initialData) {
    emit dataChanged(m_data);  // ← これを追加
}

QString DataSource::data() const {
    return m_data;
}

void DataSource::setData(const QString& newData) {
    if (m_data != newData) {
        m_data = newData;
        emit dataChanged(m_data);
    }
}

ファイル名:mywidget.h

#ifndef MYWIDGET_H
#define MYWIDGET_H

#include <QWidget>

class QPushButton;
class DataSource;

class MyWidget : public QWidget {
    Q_OBJECT

public:
    explicit MyWidget(QWidget* parent = nullptr);

private slots:
    void updateButtonText(const QString& newText);
    void changeData();

private:
    DataSource* m_dataSource;
    QPushButton* m_button;
};

#endif // MYWIDGET_H

ファイル名:mywidget.cpp

#include "mywidget.h"
#include "datasource.h"

#include <QPushButton>
#include <QVBoxLayout>

MyWidget::MyWidget(QWidget* parent)
    : QWidget(parent),
    m_dataSource(new DataSource("初期データ", this)),
    m_button(new QPushButton(m_dataSource->data(), this))
{
    auto* layout = new QVBoxLayout(this);
    layout->addWidget(m_button);

    connect(m_dataSource, &DataSource::dataChanged,
            this, &MyWidget::updateButtonText);

    connect(m_button, &QPushButton::clicked,
            this, &MyWidget::changeData);
}

void MyWidget::updateButtonText(const QString& newText) {
    m_button->setText(newText);
}

void MyWidget::changeData() {
    if (m_dataSource->data() == "データ1") {
        m_dataSource->setData("データ2");
    } else {
        m_dataSource->setData("データ1");
    }
}

ファイル名:main.cpp

#include <QApplication>
#include "mywidget.h"

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MyWidget widget;
    widget.show();
    return a.exec();
}

実行イメージ

1.起動時、ボタンのラベルは「初期データ」

2.1回目クリックで「データ1」へ変化

3.2回目クリックで「データ2」へ変化

解説

ボタンのラベル文字列をデータソースとして、ボタンを押すことでデータソースとなる文字列を持つオブジェクト(ビューモデル?)変更する仕掛けになっています。
データバインドしているのでデータソースの文字列の変化に合わせて、ラベルの文字列も変化します。

コメント