Text-Finder

Dynamisches Laden von .ui-Dateien mit QUiLoader.

Das TextFinder Beispiel zeigt, wie man eine .ui Datei dynamisch lädt und einrichtet, indem man die QUiLoader Klasse benutzt, die Teil der Qt UI Tools Bibliothek ist.

Das Programm ermöglicht es dem Benutzer, ein bestimmtes Wort im Inhalt eines Textes nachzuschlagen. Die visuellen Elemente und das Layout der Benutzeroberfläche werden zur Laufzeit aus einer der Programmressourcen geladen.

Einrichten der Ressourcendatei

Die für dieses Beispiel benötigten Ressourcen sind:

  • textfinder.ui - die in Qt Widgets Designer erstellte Benutzeroberflächendatei
  • input.txt - eine Textdatei, die einen Text enthält, der in einem Fenster angezeigt werden soll QTextEdit

textfinder.ui enthält alle notwendigen QWidget Objekte für den Text Finder. Ein QLineEdit wird für die Benutzereingabe verwendet, ein QTextEdit wird verwendet, um den Inhalt von input.txt anzuzeigen, ein QLabel wird verwendet, um den Text "Keyword" anzuzeigen, und ein QPushButton wird für die Schaltfläche Find verwendet. Beachten Sie, dass allen Widgets sinnvolle objectName zugewiesen sind. Diese werden im Code verwendet, um sie zu identifizieren.

Der Screenshot unten zeigt die Vorschau im Qt Widgets Designer.

In diesem Beispiel speichern wir beide Ressourcen in der ausführbaren Datei der Anwendung, indem wir die Datei textfinder.qrc einschließen. Alternativ könnten die Dateien auch zur Laufzeit aus dem Dateisystem oder aus einer externen binären Ressourcendatei .rcc geladen werden. Weitere Informationen über Ressourcendateien finden Sie unter Das Qt Resource System.

Die Datei textfinder.qrc listet alle Dateien auf, die als Ressource eingebunden werden sollen:

<!DOCTYPE RCC><RCC version="1.0">
<qresource>
    <file>forms/textfinder.ui</file>
    <file>forms/input.txt</file>
</qresource>
</RCC>

Um ein Formular zur Laufzeit zu generieren, wird das Beispiel gegen die Qt UI Tools Bibliothek gelinkt. Dies geschieht in der Datei textfinder.pro:

QT += widgets uitools

HEADERS = textfinder.h
SOURCES = textfinder.cpp main.cpp
RESOURCES = textfinder.qrc

TextFinder Klassendefinition

Die Klasse TextFinder enthält die Hauptbenutzerschnittstelle. Sie deklariert Zeiger auf die oben beschriebenen Elemente QPushButton, QTextEdit und QLineEdit. Der QLabel in der Benutzeroberfläche wird hier nicht deklariert, da wir ihn nicht aus dem Code heraus ansprechen müssen.

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;
};

Der Slot on_findButton_clicked() ist ein Slot, der nach der Namenskonvention für automatische Verbindungen benannt ist, die von uic verlangt wird.

Laden der Ressourcen

Wir verwenden QFile, um die Daten aus den Programmressourcen zur Laufzeit zu laden. Der Code dafür befindet sich in zwei Methoden oberhalb von textfinder.cpp: loadUiFile und loadTextFile.

Die Funktion loadUiFile lädt die zuvor im Qt Widgets Designer erstellte Datei der Benutzeroberfläche. Zunächst wird der Inhalt der Datei textfinder.ui aus dem Ressourcensystem geladen. Dann wird eine Instanz von QUiLoader erstellt und die Funktion QUiLoader::load() aufgerufen, wobei das erste Argument die geöffnete Datei und das zweite Argument der Zeiger des Widgets ist, das als Elternteil festgelegt werden soll. Das erstellte QWidget wird zurückgegeben.

static QWidget *loadUiFile(QWidget *parent)
{
    QFile file(u":/forms/textfinder.ui"_s);
    file.open(QIODevice::ReadOnly);

    QUiLoader loader;
    return loader.load(&file, parent);
}

In ähnlicher Weise lädt die Funktion loadTextFile input.txt aus den Ressourcen. Die Daten werden mit QTextStream in ein QString mit der Funktion QTextStream::readAll() eingelesen. Wir setzen die Kodierung explizit auf UTF-8, da QTextStream standardmäßig das aktuelle System-Locale verwendet. Schließlich wird der geladene Text zurückgegeben.

static QString loadTextFile()
{
    QFile inputFile(u":/forms/input.txt"_s);
    inputFile.open(QIODevice::ReadOnly);
    QTextStream in(&inputFile);
    return in.readAll();
}

Implementierung der TextFinder-Klasse

Der Konstruktor der Klasse TextFinder instanziiert keine untergeordneten Widgets direkt. Stattdessen ruft er die Funktion loadUiFile() auf und verwendet dann QObject::findChild(), um die erstellten QWidgets anhand des Objektnamens zu finden.

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");

Anschließend verwenden wir QMetaObject::connectSlotsByName(), um den automatischen Aufruf des on_findButton_clicked() Slots zu ermöglichen.

    QMetaObject::connectSlotsByName(this);

Die Funktion loadTextFile wird aufgerufen, um den Text zu erhalten, der in QTextEdit angezeigt werden soll.

    ui_textEdit->setText(loadTextFile());

Die dynamisch geladene Benutzeroberfläche in formWidget ist nun korrekt eingerichtet. Wir betten nun formWidget durch eine QVBoxLayout ein.

    auto *layout = new QVBoxLayout(this);
    layout->addWidget(formWidget);

Am Ende des Konstruktors setzen wir einen Fenstertitel.

    setWindowTitle(tr("Text Finder"));
}

Die Funktion on_findButton_clicked() ist ein Slot, der mit dem Signal clicked() von ui_findButton verbunden ist. Das searchString wird aus dem ui_lineEdit und das document aus dem ui_textEdit extrahiert. Wenn es ein leeres searchString gibt, wird ein QMessageBox verwendet, das den Benutzer auffordert, ein Wort einzugeben. Andernfalls werden die Wörter in ui_textEdit durchlaufen und alle Vorkommen von searchString hervorgehoben. Es werden zwei QTextCursor-Objekte verwendet: Eines, um die Wörter in line zu durchlaufen, und ein weiteres, um die Bearbeitungsblöcke im Auge zu behalten.

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();

Das found Flag wird verwendet, um anzuzeigen, ob searchString im Inhalt von ui_textEdit gefunden wurde. Wurde es nicht gefunden, wird QMessageBox verwendet, um den Benutzer zu informieren.

        if (found == false) {
            QMessageBox::information(this, tr("Word Not Found"),
                                     tr("Sorry, the word cannot be found."));
        }
    }
}

main() Funktion

Die Funktion main() instanziiert und zeigt TextFinder an.

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);

    TextFinder textFinder;
    textFinder.show();

    return app.exec();
}

Es gibt verschiedene Ansätze, um Formulare in Anwendungen einzubinden. Die Verwendung von QUILoader ist nur einer von ihnen. Weitere Informationen zu den anderen verfügbaren Ansätzen finden Sie unter Verwendung einer Designer UI-Datei in Ihrer Anwendung.

Beispielprojekt @ code.qt.io

Siehe auch Calculator Builder.

© 2025 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.