Qt 6 QML 和訳文書 P20 ~ P48
Qt 6 Introduction
Qt Quick
Qt QuickというのはQt6内で利用されるユーザーインターフェーステクノロジーのための包括的な専門用語です。Qt4で紹介されて、今はQt6で拡張されています。Qt Quick自体はいくつかのテクノロジーの集合です。
QML: ユーザーインターフェースのためのマークアップ言語です。
JavaScript: 動的なスクリプト言語です。
Qt C++-高度に他のシステムに移植可能、画質の高められたC++ライブラリです。
HTMLと同様に、QMLはマークアップ言語です。Qt Quickでは型(タイプス)と呼ばれるタグで構成されます。タグは中括弧{}で囲まれているものです。:Item{}.
開発者にとって迅速に、より可読性のあるユーザーインターフェースの作成のために0からデザインされました。
ユーザーインターフェースはJavaScriptによってさらに質が向上します。Qt QuickはQt C++を使って独自のネイティブ機能で簡単に拡張することができます。
要するに、宣言型言語のUIはいわゆるフロントエンドと呼ばれ、ネイティブの部分がバックエンドと呼ばれます。これにより、アプリケーションのコンピューティング集約型およびネイティブ操作をユーザーインターフェイス部分から分離できます。
典型的なプロジェクトでは、フロントエンドはQML/JavaScriptで開発されます。
システムとの仲介を行い、そしてヘビーリフティングをする、バックエンドコードはQt C++を使って開発されます。これはよりデザインに方針を決め、開発者と、関数手続き型指向の開発者の間では自然な分担です。通常、バックエンドはQt単体テストフレームワークであるQt Testを使用してテストされ、フロントエンド開発者が使用できるようにエクスポートされます。
Digesting a User Interface
Qt Quickを使って簡単なユーザーインターフェースを作りましょう。QML言語のいくつかの側面のショーケースです。最後に、回転する刃のついた紙風車になります。
「main.qmlという名前の空のドキュメントで始めます。全てのQMLファイルは.qmlという接尾辞がつきます。HTMLのようなマークアップランゲージのように、QMLドキュメントは一つあるいは、唯一のルート型を持つ必要があります。このサンプルのためには、これはImage型で、イメージの幾何領域(ジオメトリ)の背景に基づき、widthとheightを持ちます。QMLはルート型のための型の選択を制限していませんので、私たちはルートとして背景のイメージへソースプロパティをセットするImage型をつかいます。」
import QtQuick
Image {
id: root
source: "images/background.png"
}
TIP
ヒント:
それぞれの型はプロパティを持ちます。例えば、イメージ型がwidthとheightのプロパティを持ちます。それぞれはピクセルのカウント数を持ちます。他のプロパティもあります。例えばsourceというプロパティです。イメージ型のサイズは自動的にimageのサイズによりますので、widthとheightをセットする必要はありません。
最も標準的な型はQtQuickモジュール内に置かれており、.qmlファイルの最初でimportステートメントにより利用可能になります。idは特別であり、かつ、任意のプロパティです。idはドキュメント内のどこでも、関連した型を参照するために使うことができる識別子を持ちます。
重要:IDプロパティは実行中は設定することができませんし、一旦セットすると変更することはできません。ルート型のIDとしてrootを使用することは、より大きなQMLドキュメントで最上位の型を参照することを予測可能にするためにこの本で使用されている規則です。foreground要素は、ユーザーインターフェース内ではポールとピンホイールを表現しており、別々のイメージとして含まれます。
私たちは、背景の中央に水平にポールを置きたいのですが、下部に向かって垂直にオフセットします。背景の真ん中にpinwheelを置きます。この初心者用エグザンプルはimage型だけを使いますが、進むにつれて、多くの型で構成される、より洗練されたユーザーインターフェースを作ることになります。
Image {
id: root
...
Image {
id: pole
anchors.horizontalCenter: parent.horizontalCenter
anchors.bottom: parent.bottom
source: "images/pole.png"
}
Image {
id: wheel
anchors.centerIn: parent
source: "images/pinwheel.png"
}
...
}
中央にピンホイールを置くために、anchorと呼ばれる複雑なプロパティを使います。アンカーを使うことはparentと兄弟間オブジェクトの間で幾何領域的な関係を指定するようになります。例えば、私を他の型の中央におきます。(anchors.centerIn: parent)左、右、上、下、中央、塗りつぶし、垂直に中央、水平に中央の関係が両端にあります。当然、anchorの二つか、それよりも多くのアンカーが共に使われる時、それぞれを補間するべきです。例えば、ある型の左側を他の型の上へ結びつけることは意味がありません。pinwheelのためには、アンカーを行うことは一つの単純なアンカーを必要とするだけです。
TIP
例えば、中心の外へ少しだけ型を押しのけるような、ちょっとした修正をしたいかもしれません。これはanchors.horizontalCenterOffset、あるいはanchors.verticalCenterOffsetでできます。同様の修正プロパティは他のアンカー全てに対してできます。アンカープロパティのための完全なリストには、ドキュメンテーションを参照してください。
TIP
ルート型の子の型としてイメージを置くことは宣言型言語の重要なコンセプトを例証します。レイヤーとグルーピングの順番でユーザーインターフェースの可視的な外観を記述します。最上部の層(背景画像)が最初に描かれて、子の層は含んでいる型のローカル座標システムで、その上に描かれます。
展示品となるサンプルコードをちょっとだけ面白くするために、インタラクティブにしてみましょう。ユーザーがシーンのどこかでマウスを押すときに、ホイールを回転させることです。MouseArea型を使い、ルート型の全体の領域でそれをカバーします。
Image {
id: root
...
MouseArea {
anchors.fill: parent
onClicked: wheel.rotation += 90
}
...
}
マウスエリアはユーザーがカバーしている領域内でクリックを行うときシグナルを発生させます。あなたはonClicked関数をオーバーライドすることでこのシグナルに接続することができます。シグナルがつながると、シグナルが発行されるときはいつでも対応している関数がよばれるということです。この場合、マウスエリア内でクリックがあると、idがwheelである型(例えば、pinwheelイメージ)は、90度ごとに回転します。
TIP
このテクニックはタイトルケースのon+シグナル名である命名規則で全てのシグナルで働きます。また、全てのプロパティはそれらの値が変化するときシグナルを発行します。これらのシグナルは、名前付けの規則が
`on${property}Changed`
例えば、もしwidthプロパティが変化するのであれば、onWidthChanged: print(width)でそれを観察することができます。
【翻訳者の補足:Title caseは、文章やフレーズ内の単語の最初の文字を大文字にするテキストの書式設定方法です。タイトルケースは、書類、見出し、本のタイトル、論文のタイトルなど、特定の文章の一部を強調するために使用されることがあります。
Title caseの基本的なルールは以下の通りです。
最初の単語は常に大文字にする。
名詞、代名詞、動詞、形容詞、副詞などの主要な語はすべて大文字にする。
記号や前置詞("and"、"the"、"in"など)は通常、小文字にする。
一部の特定の単語("a"、"an"、"the"、"and"など)は、文の最初や重要な位置に現れる場合でも、小文字にすることがあります。
以下は、タイトルケースの例です。
"The Quick Brown Fox Jumps Over the Lazy Dog"
"Harry Potter and the Chamber of Secrets"
"A Brief History of Time"
タイトルケースの使用方法は、スタイルガイドや個々の出版物によって異なる場合があります。特定の文書やプロジェクトでタイトルケースが要求されている場合は、そのガイドラインに従う必要があります。】
ホイールは今ユーザーがクリックすときはいつでも回転しますが、回転は一定時間中流れるような動きよりはむしろ、一回のジャンプで起きるものです。アニメーションを使って滑らかな動きを実現できます。アニメーションは一定期間を越えてどれだけプロパティの変化が発生するかを定義します。これを有効にするには、Behaviorと呼ばれるアニメーション型のプロパティを使います。Behaviorはそのプロパティに適用される全ての変化のために定義されたプロパティのためのアニメーションを指定します。言い換えれば、プロパティが変わるごとに、アニメーションが走ります。これはQMLでアニメーションを行う数ある方法のうちの一つにしかすぎません。
Image {
id: root
Image {
id: wheel
Behavior on rotation {
NumberAnimation {
duration: 250
}
}
}
}
今、ホイールの回転プロパティが変化するごとに、NumberAnimationを使って250ミリセカンドの存続時間でアニメ―とします。だからそれぞれの90度には250ミリセカンドかかり、ほどよいスムーズな回転を生み出します。
TIP
実際には風車はぼやけてみえることはありません。これは回転を示しているだけです。(あなたがそれで実験したい場合には、ぼやけた回転は、assetsフォルダ内にあります。Qt Quickプログラミングがどう動くのかという基本への手短な洞察を提供するだけではなく、風車の見栄えは前よりいいですし、本当にそれらしく振舞います。
Quick Start
この章はQt6での開発をご紹介します。Qt SDKをインストールする方法、そしてQt Creator IDEを利用してhello worldアプリケーションを実行するだけではなく、どのように作るのか、ということについてお伝えします。
Installing Qt 6 SDK
Qt SDKはデスクトップあるいは、組み込み型アプリケーションを組み立てる必要があるツールを含んでいます。Qtカンパニーのホームページから最新版を手に入れることができます。オフラインとオンラインインストーラーがあります。著者は個人的にオンライン版を好みます。インストールと、多数のQtのリリースを更新してくれるからです。始めるにはお勧めの方法です。SDK自体、SDKを最新版へ更新するようにできるメンテナンスツールを持っています。Qt SDKはイントールが簡単でQt Creatorという迅速な開発のための、IDEをもちます。IDEは全ての読み手にとってお勧めであり、Qtコーディングのための高度に生産性の高い環境です。多くの開発者はコマンドラインからQtを使いますが、あなたの選択次第でコードエディタを使うのも自由です。SDKをインストールすると、初期オプションを選択し、少なくともQt6.2が利用可能であることを確認するべきです。これで準備は完了です。
Update Qt
Qt SDKは${install_dir}の元に置かれた自身のメンテナンスツールも一緒に持っています。これはQt SDKのコンポーネントを更新するものです。
Build from Source
ソースからQtをビルドするには、Qt Wiki(https://wiki.qt.io/Building_Qt_6_from_Git)のガイド通りにできます。
Hello World
インストールをテストするために、小さいhello worldアプリケーションを作りましょう。どうか、Qt Creatorを開き、Qt Quick UI Projectを作ってください。(File ‣ New File or Project ‣ Other Project ‣ Qt Quick UI Prototype)そして、プロジェクト名をHelloWorldにします。
TIP
「QtCreator IDEでは様々な型のアプリケーションを作ることができます。他に何も言われなければ、私たちは常にQt Quick UI prototypeプロジェクトを使います。運用アプリケーションでは、CMake ベースのプロジェクトを好むことがよくありますが、高速プロトタイプ作成にはこの型の方が適しています。」
TIP
「典型的なQt Quickアプリケーションは初期のQMLコードをロードするQmlEngineと呼ばれるランタイムから作成されます。開発者はネイティブコードを仲介するためにランタイムでC++の型を登録できます。これらのC++の型はプラグインとバンドルすることもできますし、importステートメントを使って動的にロードすることもできます。
qmlツールは直接使用される事前に作られたランタイムツールです。初心者のために、私たちはQt6のQML側のみに焦点を絞ってネイティブサイドの開発をカバーしません。こういうわけで私たちはprototypeプロジェクトから始めます。Qt Creatorはあなたに対していくつかのファイルを作ります。HelloWorld.qmlprojectファイルはプロジェクトファイルで、関連するプロジェクトの構成が格納されているものです。このファイルはQt Creatorによって管理されています、だからあなた自身でそれを編集しないでください。別のファイルには、HelloWorld.qmlがあり、これが私たちのアプリケーションのコードです。それを開いて、あなたが読む前にアプリケーションが何をするのか理解してみましょう。」
// HelloWorld.qml
import QtQuick
import QtQuick.Window
Window {
width: 640
height: 480
visible: true
title: qsTr("Hello World")
}
HelloWorld.qmlプログラムはQML言語で書かれています。私たちはQML言語を次の章でより深く討論します。QMLはユーザーインターフェースを階層要素のツリーとして記述します。この場合、640×480ピクセルのウィンドウ、windowタイトルは"Hello World"です。アプリケーションを自分自身で走らせるために、左側にあるRunツールを押して、メニューからBuild>Runを選択してください。バックグラウンドでは、QtCreatorがqmlを走らせ、あなたのQMLドキュメントを最初の引数として渡します。qmlアプリケーションはドキュメントを解析し、そしてユーザーインターフェースを発射します。次のようなものが表示されます。
Qt 6 works![
Qt6は動いています。
That means we’re ready to continue.
私たちは続行する準備が整っているということです。
TIP
TIP
システムインテグレーターの場合は、Qt SDKをインストールして、最新の安定したQtリリースと、特定のデバイスターゲットのソースからコンパイルされたQtバージョンを入手する必要があります。
もしコマンドラインからQt6をビルドしたいのならば、最初にコードレポジトリのコピーを手に入れて、それをビルドする必要があります。gitからQtをビルドする方法の最新の説明のためにはQtのウィキを訪問してください。(コーヒー2杯を飲んだあたりで)コンパイルがうまくいくと、Qt6はqtbaseフォルダ内で利用可能です。飲み物はなんでもいいけれども、最高の結果のためにはコーヒーをおすすめします。もしあなたがコンパイルをテストしたいのであれば、今Qt6についてくるデフォルトランタイムのエグザンプルを、実行することができます。
$qtbase/bin/qml
Application Types
Console Application
コンソールアプリケーションはグラフィカルユーザーインターフェースを提供しません。そして大抵はシステムサービスの一部として呼ばれるか、あるはコマンドラインから呼ばれます。Qt6はとても効率的にクロスプラットフォームのコンソールアプリケーションを作る手助けをする一連の準備で作成されたコンポーネントと共にあります。
例えば、ネットワーキングファイルのAPI, ストリングハンドリング、そして効率的なコマンドラインパーサーです。QtはC ++の上位にある高レベルのAPIであるため、プログラミング速度と実行速度の組み合わせが得られます。Qtを単なるUIツールキットであると考えないでください。提供できるものはまだまだたくさんあります!
String Handling
ストリング処理
最初の例はあなたが2つの定数ストリングをどのように加えるのかを実証します。明らかに、これはあまり役に立つアプリケーションではないが、ネイティブのC++アプリケーションが、イベントループなしでどのようであるかという考えを与えます。
// module or class includes
#include <QtCore>
// text stream is text-codec aware
QTextStream cout(stdout, QIODevice::WriteOnly);
int main(int argc, char** argv)
{
// avoid compiler warnings
Q_UNUSED(argc)
Q_UNUSED(argv)
QString s1("Paris");
QString s2("London");
// string concatenation
QString s = s1 + " " + s2 + "!";
cout << s << Qt::endl;
}
Container Classes
コンテナクラス
この例はリスト、そしてリストイテレーションをアプリケーションに加えます。Qtは使いやすい大量のコンテナクラスがあり、他のQtのクラスと同じAPIパラダイムを持ちます。
QString s1("Hello");
QString s2("Qt");
QList<QString> list;
// stream into containers
list << s1 << s2;
// Java and STL like iterators
QListIterator<QString> iter(list);
while(iter.hasNext()) {
cout << iter.next();
if(iter.hasNext()) {
cout << " ";
}
}
cout << "!" << Qt::endl;
より進んだリスト関数があります。リスト内のストリングを一つのストリングに連結できます。これは行を基本としたテキスト入力を手続きするようなときにはとてもお手軽です。split()関数を使えば逆もまた可能になります。
QString s1("Hello");
QString s2("Qt");
// convenient container classes
QStringList list;
list << s1 << s2;
// join strings
QString s = list.join(" ") + "!";
cout << s << Qt::endl;
次のスニペットでは、私たちはローカルディレクトリからCSVファイルを読込み、それぞれの行からセルを抜き出すために行をループします。これを行うことで、CSVファイルからコードのca.20行内のテーブルデータを取得します。ファイルの読込はバイトストリームを私たちに与え、これを有効なユニコードテキストに変換することができ、私たちはテキストストリームを使って、より低いレベルのストリームとしてファイル内に渡す必要があります。CSVファイルを書くために、write modeでファイルを開く必要があり、そしてテキストストリームに行をパイプします。
QList<QStringList> data;
// file operations
QFile file("sample.csv");
if(file.open(QIODevice::ReadOnly)) {
QTextStream stream(&file);
// loop forever macro
forever {
QString line = stream.readLine();
// test for null string 'String()'
if(line.isNull()) {
break;
}// test for empty string 'QString("")'
if(line.isEmpty()) {
continue;
}
QStringList row;
// for each loop to iterate over containers
foreach(const QString& cell, line.split(",")) {
row.append(cell.trimmed());
}
data.append(row);
}
}
// No cleanup necessary.
C++ Widget Application
コンソールベースのアプリケーションはとてもお手頃ですが、あなたはGUIを持つ必要があるときもあります。加えて、GUIを基本としたアプリケーションはバックエンドでファイルを読込、書き込みする必要がありますし、ネットワーク上でコミュニケーションを取り、あるいはコンテナ内のデータを保存する必要があります。ウィジェットベースのアプリケーション用のこの最初のスニペットでは、ウィンドウを作成して表示するために必要なことをほとんど行いません。Qtでは、親なしのウィジェットはウィンドウです。私たちはそのウィジェットがポインタがスコープの外に出る時に消去することを確かにするためスコープドポインタを使います。アプリケーションオブジェクトはQtのランタイムをカプセル化し、exec()をコールすることでイベントループをスタートさせます。そこから、アプリケーションはユーザー入力(マウスやキーボードのような)によって引き起こされたイベントにのみ、あるいはネットワーキングやfile IOのような他のイベント提供者によって引きおこされるイベントにのみ反応します。アプリケーションはイベントループが脱出するときにのみ脱出します。これはアプリケーション上でquit()がコールされることにより、あるいはウィンドウをクローズすることによって行われます。あなたがコードを走らせるとき、240×120ピクセルのサイズでウィンドウを見るでしょう。それだけです。
include <QtGui>
int main(int argc, char** argv)
{
QApplication app(argc, argv);
QScopedPointer<QWidget> widget(new CustomWidget());
widget->resize(240, 120);
widget->show();
return app.exec();
}
Custom Widgets
あなたがユーザーインターフェース上で活動するとき、カスタムメイドのウィジェットを作る必要があるかもしれません。典型的には、ウィジェットはペインティングを呼ぶことで塗りつぶされるウィンドウの領域です。加えて、ウィジェットはキーボード入力とマウス入力の動かし方の内部の知識を持っており、そして外部のトリガーへの反応の仕方の知識も持っています。Qt内でこれを行うには、QWidgetを継承して、イベントハンドリングとペイントのためのいくつかの関数を上書きする必要があります。
#pragma once
include <QtWidgets>
class CustomWidget : public QWidget
{
Q_OBJECT
public:
explicit CustomWidget(QWidget *parent = 0);
void paintEvent(QPaintEvent *event);
void mousePressEvent(QMouseEvent *event);
void mouseMoveEvent(QMouseEvent *event);
private:
QPoint m_lastPos;
};
実装では、ウィジェット上に小さな境界線を描き、最後のマウスポジション上に小さな矩形を描きます。これは低レベルのカスタムウィジェットに対してとても典型的です。マウスとキーボードイベントはウィジェットの内部の状態を変化させ、ペインティングの更新を引き起こします。私たちはこのコードについてあまりにも多くの詳細に立ち入りませんが、可能性があることを知るのはいいことです。Qtは既に整えられたデスクトップウィジェットの大きなセットを持っています。だからあなたはこれを行わなくてもよい可能性があります。
include "customwidget.h"
CustomWidget::CustomWidget(QWidget *parent) :
QWidget(parent)
{
}
void CustomWidget::paintEvent(QPaintEvent *)
{
QPainter painter(this);
QRect r1 = rect().adjusted(10,10,-10,-10);
painter.setPen(QColor("#33B5E5"));
painter.drawRect(r1);
QRect r2(QPoint(0,0),QSize(40,40));
if(m_lastPos.isNull()) {
r2.moveCenter(r1.center());
} else {
r2.moveCenter(m_lastPos);
}
painter.fillRect(r2, QColor("#FFBB33"));
}
void CustomWidget::mousePressEvent(QMouseEvent *event)
{
m_lastPos = event->pos();
update();
}
void CustomWidget::mouseMoveEvent(QMouseEvent *event)
{
m_lastPos = event->pos();
update();
}
Desktop Widgets
Qtの開発者は異なるオペレーティングシステム内のネイティブの外観で、デスクトップウィジェットの設定を提供し、既にあなたのためにこれの全てを行いました。その時、あなたの仕事は、あるウィジェットコンテナ内の異なるこれらのウィジェットをより大きなパネルへ整理することです。Qt内のウィジェットは他のウィジェットのためのコンテナにもなります。これは親子関係を通して達成されます。これは私たちが作り、例えば、ボタン、チェックボックス、ラジオボタン、リスト、そしてグリッド、他のウィジェットの子のような既存のウィジェットを作る必要があるという意味です。これを達成する方法は下記に表示されます。こちらはいわゆるウィジェットコンテナのヘッダファイルです。
CustomWidget::CustomWidget(QWidget *parent) :
QWidget(parent)
{
QVBoxLayout *layout = new QVBoxLayout(this);
m_widget = new QListWidget(this);
layout->addWidget(m_widget);
m_edit = new QLineEdit(this);
layout->addWidget(m_edit);
m_button = new QPushButton("Quit", this);
layout->addWidget(m_button);
setLayout(layout);
QStringList cities;
cities << "Paris" << "London" << "Munich";
foreach(const QString& city, cities) {
m_widget->addItem(city);
}
connect(m_widget, SIGNAL(itemClicked(QListWidgetItem*)), th
connect(m_edit, SIGNAL(editingFinished()), this, SLOT(updat
connect(m_button, SIGNAL(clicked()), qApp, SLOT(quit()));
}
void CustomWidget::itemClicked(QListWidgetItem *item)
{
Q_ASSERT(item);
m_edit->setText(item->text());
}
void CustomWidget::updateItem()
{
QListWidgetItem* item = m_widget->currentItem();
if(item) {
item->setText(m_edit->text());
}
}
Drawing Shapes
いくつかの問題がより浮き彫りになってきます。もし問題がじおめてぃかるな部ジェクトのように遠くに見えるのだれば、Qtのグラフィックスビューが良い候補です。グラフィックビューは単純な幾何図形をシーン内に整理します。ユーザーはこれらのシェイプと相互にかかわることができ、あるいはアルゴリズムを使って位置づけられます。グラフィックスビューを一般化するためには、あなたはグラフィックスビューとグラフィックスシーンを必要とします。シーンはビューに取り付けられ、グラフィックスアイテムで一般化されます。こちらは小さいエグザンプルです。ビューとシーンの宣言の最初のヘッダファイルです。
class CustomWidgetV2 : public QWidget
{
Q_OBJECT
public:
explicit CustomWidgetV2(QWidget *parent = 0);
private:
QGraphicsView *m_view;
QGraphicsScene *m_scene;
};
「実装では、シーンは最初にビューに取り付けられます。ビューはウィジェットであり、コンテナウィジェット内でアレンジされます。最後には、シーンに小さな矩形範囲を加え、そしてそれからビューへ表示されます。」
include "customwidgetv2.h"
CustomWidget::CustomWidget(QWidget *parent) :
QWidget(parent)
{
m_view = new QGraphicsView(this);
m_scene = new QGraphicsScene(this);
m_view->setScene(m_scene);
QVBoxLayout *layout = new QVBoxLayout(this);
layout->setMargin(0);
layout->addWidget(m_view);
setLayout(layout);
QGraphicsItem* rect1 = m_scene->addRect(0,0, 40, 40, Qt::No
rect1->setFlags(QGraphicsItem::ItemIsFocusable|QGraphicsIte
}
Adapting Data
「今までで私たちはほとんどの基本のデータ型をカバーしましたし、ウィジェットとグラフィックスビューの使い方をカバーしました。あなたのアプリケーションでは、より多くの構造化されたデータを必要とすることがよくあるでしょうし、そのデータはいつまでも格納し続ける必要があるでしょう。最後に、そのデータは表示される必要もあります。このため、Qtはモデルを使います。単純なモデルはストリングリストモデルで、ストリング型で満たされ、リストビューに取り付けられます。」
m_view = new QListView(this);
m_model = new QStringListModel(this);
view->setModel(m_model);
QList<QString> cities;
cities << "Munich" << "Paris" << "London";
m_model->setStringList(cities);
「データを格納し、取り出すための、他の人気な方法はSQLです。Qtは組み込まれたSQLiteを持っていて、他のデータベースエンジンのためのサポートも持っています。(例えばMySQLとPostgreSQLです。)最初、あなたはスキーマを使ってデータベースを作る必要があります。このように。」
CREATE TABLE city (name TEXT, country TEXT);
INSERT INTO city VALUES ("Munich", "Germany");
INSERT INTO city VALUES ("Paris", "France");
INSERT INTO city VALUES ("London", "United Kingdom");
To use SQL, we need to add the SQL module to our .pro file
「SQLを使うため、私たちは.proファイルにSQLモジュールを加える必要があります。」
QT += sql
「そしてそれからC++を使ってデータベースをオープンできます。最初に、私たちは新しいデータベースオブジェクトを、指定したデータベースエンジンのために取得する必要があります。このデータベースオブジェクトで、データベースを開きます。SQLiteに対しては、データベースファイルのパスを指定するだけで十分です。Qtはいくつかの高レベルのデータベースモデルを提供し、そのうちの一つがテーブルモデルです。テーブルモデルはテーブルの識別子と、データを選択するための選択的なwhere句を利用します。結果としてのモデルは以前の他のモデルとしてリストビューへ取り付けられます。」
QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
db.setDatabaseName("cities.db");
if(!db.open()) {
qFatal("unable to open database");
}
m_model = QSqlTableModel(this);
m_model->setTable("city");
m_model->setHeaderData(0, Qt::Horizontal, "City");
m_model->setHeaderData(1, Qt::Horizontal, "Country");
view->setModel(m_model);
m_model->select();
For a higher level model operations, Qt provides a sorting file proxy model that allows you sort, filter, and transform models.
「より高度な段階の命令のために、Qtはソート、フィルター、モデルの変換ができるプロキシもソーティングファイルプロキシモデルを提供します。」
QSortFilterProxyModel* proxy = new QSortFilterProxyModel(this);
proxy->setSourceModel(m_model);
view->setModel(proxy);
view->setSortingEnabled(true);
Filtering is done based on the column that is to be filters, and a string as filter argument.
「フィルタリングはフィルターであるカラムを基本として行われ、フィルター引数としてストリング型を基本とします。」
proxy->setFilterKeyColumn(0);
proxy->setFilterCaseSensitivity(Qt::CaseInsensitive);
proxy->setFilterFixedString(QString)
The filter proxy model is much more powerful than demonstrated here. For now, it is enough to remember it exists.
「フィルタープロキシモデルはここで証明するよりもずっとパワフルです。これからのためにも、それが存在するということを覚えるだけで十分です。」
!!! note
This has been an overview of the different kind of classic appl
これは古典的なアプリの異なる種類の概観でした。
Coming next: Qt Quick to the rescue.
次は、緊急救援のQt Quickです。
Qt Quick Application
現代のソフトウェア開発には固着した競合があります。ユーザーインターフェースはバックエンドサービスよりもずっと速く動いています。伝統的な技術では、バックエンドと同じペースでいわゆるフロントエンドを開発します。顧客はプロジェクトの間にユーザーインターフェースを変化させたい時、あるいは、プロジェクトの間にユーザーインターフェースのアイデアを発展させたい時、これが競合する結果になります。アジャイルプロジェクトは、アジャイルメソッドを必要とします。Qt Quickは、ユーザーインターフェイス(フロントエンド)がHTMLのように宣言され、バックエンドがネイティブC ++コードである宣言型環境を提供します。これにより、両方の長所を活かすことができます。
This is a simple Qt Quick UI below
import QtQuick
Rectangle {
width: 240; height: 240
Rectangle {
width: 40; height: 40
anchors.centerIn: parent
color: '#FFBB33'
}
}
「QMLという宣言型言語、①そしてそれは実行するランタイムを必要とします。Qtはqmlと呼ばれる標準のランタイムを提供します。カスタムランタイムも書くことができます。このため、私たちはクイックビューを必要とし、主なQMLドキュメントをC++からのソースとして設定します。それからユーザーインターフェースを表示します。」
①ランタイムとは何か?
chat GPT
ランタイム(Runtime)とは、プログラムが実行される環境や実行時における動作のことを指します。具体的には、プログラムが実行される際に必要なランタイム環境やランタイムエンジンが提供する機能やサービスを指すことがあります。
一般的に、プログラミング言語にはそれぞれ対応するランタイムが存在します。例えば、JavaプログラムはJavaランタイム環境(JRE)またはJava仮想マシン(JVM)上で実行されますし、JavaScriptプログラムはウェブブラウザのJavaScriptランタイムで実行されます。
ランタイムには、メモリ管理、変数のライフサイクル管理、例外処理、スレッド管理、ファイル入出力などの機能が含まれる場合があります。また、実行時に動的なコード生成や実行が可能な場合もあります。
一般に、開発者がプログラムを作成する際には、プログラミング言語と対応するランタイム環境が必要となります。このランタイム環境が提供する機能や制約によって、プログラムの挙動やパフォーマンスが左右されることになります。
したがって、「ランタイム」という用語は、プログラムが実際に動作するための環境や実行時の動作に焦点を当てた概念を表す言葉として使用されます。
import QtQuick
Rectangle {
width: 240; height: 120
ListView {
width: 180; height: 120
anchors.centerIn: parent
model: cityModel
delegate: Text { text: model.city }
}
}
cityModelを有効にするため、私たちはほとんど私たちの以前のモデルを再利用することができ、ルートコンテキストにコンテキストプロパティを加えることができます。ルートコンテキストはメインドキュメント内の他のルート要素です。
m_model = QSqlTableModel(this);
... // some magic code
QHash<int, QByteArray> roles;
roles[Qt::UserRole+1] = "city";
roles[Qt::UserRole+2] = "country";
m_model->setRoleNames(roles);
engine.rootContext()->setContextProperty("cityModel", m_model);
Summary
まとめ
私たちはQt SDKのインストール方法と、最初のアプリケーションの作り方を見てきました。それからQtの概観をあなたに示すために異なるアプリケーションタイプを通して道案内をし、アプリケーション開発のためにQtが提供する機能をお見せしました。私はQtがとてもリッチなユーザーインターフェースツールキットであるという良い印象を得ることを望みますし、アプリケーション開発者が望むものすべて、そしてそれ以上のものを提供するものであることを望んでいます。なお、Qtは指定したライブラリへあなたを拘束しません、あなたは常に他のライブラリを使うことができ、あるいはQtをあなた自身が拡張することさえできます。異なるアプリケーションモデル:コンソール、古典的なデスクトップユーザーインターフェース、そしてタッチ型ユーザーインターフェースのようなものをサポートすることでもなおリッチなのです。