文本查找器
使用QUiLoader 动态加载.ui文件。
.ui TextFinder示例演示了如何使用QUiLoader 类(该类属于 Qt UI Tools 库中的一部分的xml-ph-0001@deepl.internal类,动态加载和配置xml-ph-0000@deepl.internal文件。
该程序允许用户在文本内容中查找特定单词。用户界面的视觉元素和布局是在运行时从程序资源中加载的。
![]() | ![]() |
设置资源文件
本示例所需的资源包括:
textfinder.ui- 在 Qt Widgets Designerinput.txt- 一个文本文件,其中包含将在QTextEdit
textfinder.ui 文件中包含“文本查找器”(Text Finder)所需的所有QWidget 对象。其中,QLineEdit 用于用户输入,QTextEdit 用于显示input.txt 中的内容,QLabel 用于显示文本“Keyword”,QPushButton 用于Find 按钮。请注意,所有控件均已分配了合理的objectName 。这些 将在代码中用于识别它们。
下图所示为在 Qt Widgets Designer中获得的预览。

在此示例中,我们通过包含textfinder.qrc 文件,将这两项资源存储在应用程序的可执行文件中。此外,这些文件也可以在运行时从文件系统或外部二进制资源.rcc 文件中加载。有关资源文件的更多信息,请参阅《Qt资源系统》。
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.qrcTextFinder 类定义
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 要求的“自动连接”命名约定命名的插槽。
加载资源
我们使用QFile 在运行时从程序资源中加载数据。相关代码位于textfinder.cpp 类的顶层,分别是loadUiFile 和loadTextFile 这两个方法中。
loadUiFile 函数用于加载先前在 Qt Widgets Designer中创建的用户界面文件。首先,从资源系统中定位并打开textfinder.ui 文件。然后创建一个QUiLoader 实例,并调用QUiLoader::load()函数,其中第一个参数是已打开的文件,第二个参数是应设为父窗口的小部件的指针。最后返回创建的QWidget 。
staticQWidget*loadUiFile(QWidget*parent)
{
QFile file(u":/forms/textfinder.ui"_s);
if(!file.open(QIODevice::ReadOnly))
qFatal("Cannot open resource file");
returnQUiLoader().load(&file,parent);
}同理,loadTextFile 函数会从资源中定位并打开input.txt ,随后通过QTextStream::readAll() 函数返回该文件的内容。
staticQString loadTextFile()
{
QFile inputFile(u":/forms/input.txt"_s);
if(!inputFile.open(QIODevice::ReadOnly))
qFatal("Cannot open resource file");
returnQTextStream(&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_findButton 的clicked() 信号相连的插槽。searchString 是从ui_lineEdit 中提取的,document 则是从ui_textEdit 中提取的。如果searchString 为空,则会使用QMessageBox ,提示用户输入一个单词。 否则,我们将遍历ui_textEdit 中的单词,并高亮显示所有searchString 的出现位置。此处使用了两个QTextCursor对象:一个用于遍历line 中的单词,另一个用于跟踪编辑块。
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();found 标志用于指示searchString 是否在ui_textEdit 的内容中被找到。若未找到,则使用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 只是其中之一。有关其他可用方法的更多信息,请参阅《在应用程序中使用Qt Widgets Designer UI 文件》。
另请参阅 “计算器构建器”。
© 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.

