Qt
C++用の包括的なクロスプラットフォーム開発フレームワーク。豊富なUIコンポーネント、ネットワーク、データベース、グラフィックス機能を統合。QMLによる宣言的UI開発とC++の高性能を両立。商用・オープンソース両ライセンス提供。
GitHub概要
スター2,747
ウォッチ118
フォーク1,088
作成日:2013年5月6日
言語:C++
ライセンス:-
トピックス
c-plus-plusqtqt5
スター履歴
データ取得日時: 2025/7/15 22:54
フレームワーク
Qt
概要
Qtは、C++で書かれたクロスプラットフォーム・アプリケーション・フレームワークです。高性能なネイティブアプリケーションを、Windows、macOS、Linux、Android、iOS、組み込みシステムで統一されたコードベースから開発できます。
詳細
Qt(キュート)は、1995年から続く成熟したクロスプラットフォーム開発フレームワークです。2025年現在、世界70以上の業界で約100万人の開発者に使用され、AMD、欧州宇宙機関、ウォルト・ディズニー・アニメーション・スタジオ、シーメンス、パナソニックなどの大手企業で採用されています。
最新版のQt 6.9が2025年4月2日にリリースされ、継続的な開発と機能強化が行われています。Qtの最大の特徴は「Write Once, Deploy Everywhere」のコンセプトで、単一のコードベースから複数のプラットフォーム向けアプリケーションを効率的に開発できることです。
Mercedes BenzのMBUXユーザー体験、Adobe Photoshop Elements、Google Earth、TeamViewerなど、様々な著名アプリケーションでQtが使用されており、特にデスクトップアプリケーション、組み込みシステム、産業用アプリケーション分野で強固な地位を確立しています。
メリット・デメリット
メリット
- 成熟したエコシステム: 30年近い歴史と豊富な機能
- 真のクロスプラットフォーム: Windows、macOS、Linux、Android、iOS、組み込み対応
- ネイティブ性能: ネイティブUIとハイパフォーマンス
- 豊富なライブラリ: GUI、ネットワーク、データベース、マルチメディアなど包括的
- Qt Designer: ビジュアルUIデザインツール
- 幅広い業界採用: 大手企業での実績豊富
- 強力なドキュメント: 詳細なドキュメントとサンプル
- 企業サポート: The Qt Companyによる商用サポート
デメリット
- 学習コストの高さ: C++の知識とQt特有のシステム理解が必要
- ライセンス複雑性: LGPL/GPLとコマーシャルライセンスの選択
- バイナリサイズ: 必要ライブラリによりアプリサイズが大きくなる場合
- モバイル制約: iOS/Androidでの一部制限
- リリースサイクル: メジャーアップデートでAPI変更の可能性
主要リンク
書き方の例
基本的なQtアプリケーション
// main.cpp
#include <QApplication>
#include <QMainWindow>
#include <QPushButton>
#include <QVBoxLayout>
#include <QWidget>
#include <QLabel>
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr)
: QMainWindow(parent)
{
auto *centralWidget = new QWidget(this);
setCentralWidget(centralWidget);
auto *layout = new QVBoxLayout(centralWidget);
auto *label = new QLabel("Hello, Qt!", this);
auto *button = new QPushButton("クリックしてください", this);
layout->addWidget(label);
layout->addWidget(button);
connect(button, &QPushButton::clicked, this, &MainWindow::onButtonClicked);
setWindowTitle("Qt アプリケーション");
resize(300, 200);
}
private slots:
void onButtonClicked()
{
static int count = 0;
auto *label = findChild<QLabel*>();
if (label) {
label->setText(QString("クリック回数: %1").arg(++count));
}
}
};
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
MainWindow window;
window.show();
return app.exec();
}
#include "main.moc"
シグナルとスロット
// counter.h
#include <QObject>
#include <QTimer>
class Counter : public QObject
{
Q_OBJECT
public:
explicit Counter(QObject *parent = nullptr);
public slots:
void start();
void stop();
void reset();
private slots:
void updateCount();
signals:
void countChanged(int count);
void finished();
private:
QTimer *m_timer;
int m_count;
int m_maxCount;
};
// counter.cpp
#include "counter.h"
Counter::Counter(QObject *parent)
: QObject(parent), m_count(0), m_maxCount(10)
{
m_timer = new QTimer(this);
connect(m_timer, &QTimer::timeout, this, &Counter::updateCount);
}
void Counter::start()
{
m_timer->start(1000); // 1秒間隔
}
void Counter::stop()
{
m_timer->stop();
}
void Counter::reset()
{
m_count = 0;
emit countChanged(m_count);
}
void Counter::updateCount()
{
++m_count;
emit countChanged(m_count);
if (m_count >= m_maxCount) {
m_timer->stop();
emit finished();
}
}
QMLとC++の統合
// main.cpp
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include "datamodel.h"
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
// C++オブジェクトをQMLに公開
DataModel dataModel;
engine.rootContext()->setContextProperty("dataModel", &dataModel);
// QMLファイルを読み込み
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
if (engine.rootObjects().isEmpty())
return -1;
return app.exec();
}
// main.qml
import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Layouts 1.15
ApplicationWindow {
visible: true
width: 400
height: 300
title: "Qt QML アプリケーション"
ColumnLayout {
anchors.centerIn: parent
spacing: 20
Text {
text: "データ: " + dataModel.currentValue
font.pixelSize: 18
Layout.alignment: Qt.AlignHCenter
}
Button {
text: "データを更新"
Layout.alignment: Qt.AlignHCenter
onClicked: dataModel.updateValue()
}
Slider {
from: 0
to: 100
value: dataModel.sliderValue
Layout.fillWidth: true
onValueChanged: dataModel.sliderValue = value
}
Text {
text: "スライダー値: " + Math.round(dataModel.sliderValue)
Layout.alignment: Qt.AlignHCenter
}
}
}
データベース操作
// database.cpp
#include <QSqlDatabase>
#include <QSqlQuery>
#include <QSqlError>
#include <QDebug>
class DatabaseManager
{
public:
bool initializeDatabase()
{
QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
db.setDatabaseName("example.db");
if (!db.open()) {
qDebug() << "データベース接続エラー:" << db.lastError().text();
return false;
}
// テーブル作成
QSqlQuery query;
query.exec("CREATE TABLE IF NOT EXISTS users ("
"id INTEGER PRIMARY KEY AUTOINCREMENT, "
"name TEXT NOT NULL, "
"email TEXT UNIQUE NOT NULL)");
return true;
}
bool addUser(const QString &name, const QString &email)
{
QSqlQuery query;
query.prepare("INSERT INTO users (name, email) VALUES (?, ?)");
query.addBindValue(name);
query.addBindValue(email);
if (!query.exec()) {
qDebug() << "ユーザー追加エラー:" << query.lastError().text();
return false;
}
return true;
}
QStringList getAllUsers()
{
QStringList users;
QSqlQuery query("SELECT name, email FROM users");
while (query.next()) {
QString name = query.value(0).toString();
QString email = query.value(1).toString();
users << QString("%1 <%2>").arg(name, email);
}
return users;
}
};
ネットワーク通信
// networkclient.h
#include <QObject>
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QJsonDocument>
#include <QJsonObject>
class NetworkClient : public QObject
{
Q_OBJECT
public:
explicit NetworkClient(QObject *parent = nullptr);
void fetchData(const QString &url);
void postData(const QString &url, const QJsonObject &data);
signals:
void dataReceived(const QJsonObject &data);
void errorOccurred(const QString &error);
private slots:
void onReplyFinished();
private:
QNetworkAccessManager *m_manager;
};
// networkclient.cpp
#include "networkclient.h"
#include <QJsonDocument>
#include <QDebug>
NetworkClient::NetworkClient(QObject *parent)
: QObject(parent)
{
m_manager = new QNetworkAccessManager(this);
}
void NetworkClient::fetchData(const QString &url)
{
QNetworkRequest request(QUrl(url));
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
QNetworkReply *reply = m_manager->get(request);
connect(reply, &QNetworkReply::finished, this, &NetworkClient::onReplyFinished);
}
void NetworkClient::postData(const QString &url, const QJsonObject &data)
{
QNetworkRequest request(QUrl(url));
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
QJsonDocument doc(data);
QNetworkReply *reply = m_manager->post(request, doc.toJson());
connect(reply, &QNetworkReply::finished, this, &NetworkClient::onReplyFinished);
}
void NetworkClient::onReplyFinished()
{
QNetworkReply *reply = qobject_cast<QNetworkReply*>(sender());
if (!reply) return;
if (reply->error() == QNetworkReply::NoError) {
QByteArray data = reply->readAll();
QJsonDocument doc = QJsonDocument::fromJson(data);
emit dataReceived(doc.object());
} else {
emit errorOccurred(reply->errorString());
}
reply->deleteLater();
}
CMakeLists.txt設定
cmake_minimum_required(VERSION 3.16)
project(MyQtApp LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
# Qt6を検索
find_package(Qt6 REQUIRED COMPONENTS Core Widgets Gui Sql Network Qml Quick)
# 実行ファイルを作成
qt_add_executable(MyQtApp
main.cpp
mainwindow.cpp
mainwindow.h
counter.cpp
counter.h
datamodel.cpp
datamodel.h
networkclient.cpp
networkclient.h
)
# QMLモジュールを追加
qt_add_qml_module(MyQtApp
URI MyApp
VERSION 1.0
QML_FILES
main.qml
)
# Qtライブラリをリンク
target_link_libraries(MyQtApp PRIVATE
Qt6::Core
Qt6::Widgets
Qt6::Gui
Qt6::Sql
Qt6::Network
Qt6::Qml
Qt6::Quick
)
# プラットフォーム固有の設定
set_target_properties(MyQtApp PROPERTIES
WIN32_EXECUTABLE TRUE
MACOSX_BUNDLE TRUE
)
プロジェクト作成と実行
# Qt Creatorでプロジェクト作成(推奨)
# Qt Creator -> File -> New Project -> Application
# または、CMakeでプロジェクト作成
mkdir my-qt-app && cd my-qt-app
# CMakeLists.txtとソースファイルを作成後
mkdir build && cd build
cmake ..
cmake --build .
# 実行
./MyQtApp # Linux/macOS
# または
MyQtApp.exe # Windows
# qmakeを使用する場合
qmake -project
qmake
make # Linux/macOS
# または
nmake # Windows