テキストファインダー
QUiLoader を使って .ui ファイルを動的にロードする。
TextFinder の例では、Qt UI Toolsライブラリの一部であるQUiLoader クラスを使って、.ui
ファイルを動的に読み込んでセットアップする方法を示しています。
このプログラムでは、ユーザーがテキストの内容から特定の単語を検索することができます。ユーザーインターフェースの視覚的な要素とレイアウトは、プログラムのリソースから実行時にロードされます。
リソース・ファイルのセットアップ
この例に必要なリソースは以下の通りです:
textfinder.ui
-Qt Widgets Designerで作成されたユーザーインターフェイスファイル。input.txt
- に表示されるテキストを含むテキストファイル。QTextEdit
textfinder.ui
には、テキスト・ファインダーに必要な オブジェクトがすべて含まれています。 はユーザー入力に、 は の内容を表示するために、 は "Keyword" というテキストを表示するために、 は ボタンに使われます。すべてのウィジェットには、 'が割り当てられています。これらはコード内でウィジェットを識別するために使用されます。QWidget QLineEdit QTextEdit input.txt
QLabel QPushButton Find objectName
下のスクリーンショットは、Qt Widgets Designerで取得したプレビューです。
この例では、textfinder.qrc
ファイルをインクルードすることで、両方のリソースをアプリケーションの実行ファイルに保存しています。また、ファイルシステムから実行時に読み込むこともできますし、外部のバイナリリソース.rcc
ファイルから読み込むこともできます。リソースファイルの詳細については、Qt Resource Systemを参照してください。
textfinder.qrc
ファイルには、リソースとして含めるべきすべてのファイルがリストされています:
<!DOCTYPE RCC><RCC version="1.0"> <qresource> <file>forms/textfinder.ui</file> <file>forms/input.txt</file> </qresource> </RCC>
実行時にフォームを生成するために、サンプルはQt Ui Toolsライブラリとリンクされます。これはtextfinder.pro
ファイルで行われます:
QT += widgets uitools HEADERS = textfinder.h SOURCES = textfinder.cpp main.cpp RESOURCES = textfinder.qrc
TextFinder クラス定義
TextFinder
クラスはメイン・ユーザー・インターフェースを含んでいます。QPushButton 、QTextEdit 、QLineEdit の各要素へのポインタを宣言しています。ユーザー・インターフェースのQLabel は、コードからアクセスする必要がないので、ここでは宣言しません。
class TextFinder : public QWidget { Q_OBJECT public: explicit TextFinder(QWidget *parent = nullptr); private slots: void on_findButton_clicked(); private: QPushButton *ui_findButton; QTextEdit *ui_textEdit; QLineEdit *ui_lineEdit; };
スロットon_findButton_clicked()
は、uic
で要求されるAutomatic Connection の命名規則に従って命名されたスロットです。
リソースのロード
QFile 、実行時にプログラム・リソースからデータをロードします。このためのコードは、textfinder.cpp
の上にある2つのメソッド、loadUiFile
とloadTextFile
にあります。
loadUiFile
関数は、Qt Widgets Designer で作成したユーザー・インターフェース・ファイルをロードします。まず、textfinder.ui
ファイルの内容がリソース・システムからロードされます。次に、QUiLoader インスタンスが作成され、QUiLoader::load() 関数が呼び出されます。第1引数にはオープン・ファイル、第2引数には親として設定するウィジェットのポインタが指定されます。作成されたQWidget が返される。
static QWidget *loadUiFile(QWidget *parent) { QFile file(u":/forms/textfinder.ui"_s); file.open(QIODevice::ReadOnly); QUiLoader loader; return loader.load(&file, parent); }
同様に、loadTextFile
関数はinput.txt
をリソースからロードする。データはQTextStream を使ってQTextStream::readAll() 関数でQString に読み込まれる。QTextStream 、デフォルトでは現在のシステムロケールを使用するため、明示的にエンコーディングをUTF-8に設定しています。最後に、読み込まれたテキストが返されます。
static QString loadTextFile() { QFile inputFile(u":/forms/input.txt"_s); inputFile.open(QIODevice::ReadOnly); QTextStream in(&inputFile); return in.readAll(); }
TextFinder クラスの実装
TextFinder
クラスのコンストラクタは、子ウィジェットを直接インスタンス化しません。代わりにloadUiFile()
関数を呼び出し、QObject::findChild() を使って、作成されたQWidgetをオブジェクト名で探します。
TextFinder::TextFinder(QWidget *parent) : QWidget(parent) { QWidget *formWidget = loadUiFile(this); ui_findButton = findChild<QPushButton*>("findButton"); ui_textEdit = findChild<QTextEdit*>("textEdit"); ui_lineEdit = findChild<QLineEdit*>("lineEdit");
次に、QMetaObject::connectSlotsByName() を使用して、on_findButton_clicked()
スロットを自動的に呼び出せるようにします。
QMetaObject::connectSlotsByName(this);
loadTextFile
関数を呼び出して、QTextEdit に表示するテキストを取得します。
ui_textEdit->setText(loadTextFile());
これで、formWidget
の動的にロードされるユーザーインターフェイスが適切にセットアップされました。次に、QVBoxLayout
を使ってformWidget
を埋め込みます。
auto *layout = new QVBoxLayout(this); layout->addWidget(formWidget);
コンストラクタの最後に、ウィンドウのタイトルを設定します。
setWindowTitle(tr("Text Finder"));
}
on_findButton_clicked()
関数はui_findButton
のclicked()
シグナルに接続されるスロットです。searchString
はui_lineEdit
から抽出され、document
はui_textEdit
から抽出される。空のsearchString
があれば、QMessageBox が使用され、ユーザーに単語の入力を要求する。そうでない場合は、ui_textEdit
の単語を走査し、searchString
のすべての出現箇所を強調表示します。2 つの QTextCursor オブジェクトが使用されます:1つはline
の単語を走査するため、もう1つは編集ブロックを追跡するためです。
void TextFinder::on_findButton_clicked() { QString searchString = ui_lineEdit->text(); QTextDocument *document = ui_textEdit->document(); bool found = false; // undo previous change (if any) document->undo(); if (searchString.isEmpty()) { QMessageBox::information(this, tr("Empty Search Field"), tr("The search field is empty. " "Please enter a word and click Find.")); } else { QTextCursor highlightCursor(document); QTextCursor cursor(document); cursor.beginEditBlock(); QTextCharFormat plainFormat(highlightCursor.charFormat()); QTextCharFormat colorFormat = plainFormat; colorFormat.setForeground(Qt::red); while (!highlightCursor.isNull() && !highlightCursor.atEnd()) { highlightCursor = document->find(searchString, highlightCursor, QTextDocument::FindWholeWords); if (!highlightCursor.isNull()) { found = true; highlightCursor.movePosition(QTextCursor::WordRight, QTextCursor::KeepAnchor); highlightCursor.mergeCharFormat(colorFormat); } } cursor.endEditBlock();
searchString
がui_textEdit
のコンテンツ内で見つかったかどうかを示すために、found
フラグが使用されます。 見つからなかった場合は、QMessageBox が使用されてユーザーに通知されます。
if (found == false) { QMessageBox::information(this, tr("Word Not Found"), tr("Sorry, the word cannot be found.")); } } }
main()
関数
main()
関数はTextFinder
をインスタンス化して表示します。
int main(int argc, char *argv[]) { QApplication app(argc, argv); TextFinder textFinder; textFinder.show(); return app.exec(); }
アプリケーションにフォームを含めるには様々なアプローチがあります。QUILoaderの使用はその1つに過ぎません。利用可能な他のアプローチの詳細については、「アプリケーションでデザイナーUIファイルを使用する」を参照してください。
Calculator Builderも参照して ください。
©2024 The Qt Company Ltd. 本書に含まれるドキュメントの著作権は各所有者に帰属します。 本書で提供されるドキュメントは、Free Software Foundation が発行したGNU Free Documentation License version 1.3に基づいてライセンスされています。 Qtおよびそれぞれのロゴは、フィンランドおよびその他の国におけるThe Qt Company Ltd.の 商標です。その他すべての商標は、それぞれの所有者に帰属します。