このページでは

テキストファインダー

QUiLoader を使って .ui ファイルを動的にロードする。

TextFinderの例では、ライブラリの一部であるQUiLoader クラスを使用して、.ui ファイルを動的にロードしてセットアップする方法を示しています。 Qt UI Toolsライブラリの一部です。

このプログラムでは、ユーザーがテキストの内容から特定の単語を検索することができます。ユーザー・インターフェースの視覚的要素とレイアウトは、プログラム・リソースから実行時にロードされます。

テキストファインダーの検索ボタンと入力テキストファインダー ハイライト結果

リソース・ファイルのセットアップ

この例で必要なリソースは以下の通りです:

  • textfinder.ui - で作成されたユーザー・インターフェース・ファイル Qt Widgets Designer
  • input.txt - で表示されるテキストを含むテキストファイル。QTextEdit

textfinder.ui には、テキスト・ファインダーに必要なQWidget オブジェクトがすべて含まれています。QLineEdit はユーザー入力に使われ、QTextEditinput.txt の内容を表示するのに使われ、QLabel は「キーワード」というテキストを表示するのに使われ、QPushButtonFind ボタンに使われる。すべてのウィジェットには、objectName'が割り当てられています。これらは、ウィジェットを識別するためにコードで使用されます。

下のスクリーンショットは Qt Widgets Designer.

TestFinder UIのスクリーンショット

この例では、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 クラスはメインのユーザー・インターフェースを含んでいます。QPushButtonQTextEditQLineEdit の各要素へのポインタを宣言しています。ユーザー・インターフェースの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つのメソッド、loadUiFileloadTextFile にあります。

loadUiFile 関数は、あらかじめ Qt Widgets Designer.まず、textfinder.ui ファイルを探し、リソース・システムから開きます。そして、QUiLoader インスタンスが作成され、QUiLoader::load()関数が呼び出される。第1引数はオープンされたファイル、第2引数は親として設定されるべきウィジェットのポインタである。作成されたQWidget が返される。

静的QWidget*loadUiFile(QWidget*parent) { QFilefile(u":/forms/textfinder.ui"_s);if(!file.open(QIODevice::ReadOnly))        qFatal("Cannot open resource file");

   リターンQUiLoader().load(&file,parent); }

同様に、loadTextFile 関数は、リソースからinput.txt を探し、開きます。そして、QTextStream::readAll() 関数を使ってファイルの内容を返します。

静的QStringloadTextFile() { QFileinputFile(u":/forms/input.txt"_s);if(!inputFile.open(QIODevice::ReadOnly))        qFatal("Cannot open resource file");

   リターンQTextStream(&inputFile).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_findButtonclicked() シグナルに接続されるスロットである。searchStringui_lineEdit から抽出され、documentui_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();

searchStringui_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 を使用するのもそのひとつです。その他のアプローチについては、「アプリケーションでデザイナーUIファイルを使用する」を参照してください。

サンプルプロジェクト @ code.qt.io

電卓ビルダーも参照してください

© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.