文本查找器
使用QUiLoader 动态加载 .ui 文件。
TextFinder 示例展示了如何使用QUiLoader 类动态加载和设置.ui
文件,该类是 Qt UI Tools类动态加载和设置 文件。
该程序允许用户查找文本内容中的某个特定单词。用户界面的视觉元素和布局是在运行时从程序资源中加载的。
![]() | ![]() |
设置资源文件
本例所需的资源包括
textfinder.ui
- 在程序中创建的用户界面文件 Qt Widgets Designerinput.txt
- 一个文本文件,其中包含一些要在用户界面中显示的文本。QTextEdit
textfinder.ui
包含文本查找器所需的所有 对象。 用于用户输入, 用于显示 的内容, 用于显示文本 "关键词", 用于 按钮。请注意,所有部件都分配了合理的 's。代码中使用这些标识来识别它们。QWidget QLineEdit QTextEdit input.txt
QLabel 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.qrc
文本查找器类定义
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 将被返回。
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::readAll() 函数,使用QTextStream 将数据读入QString 。我们明确地将编码设置为UTF-8,因为QTextStream 默认使用当前系统的本地语言。最后,加载的文本将被返回。
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() 按对象名称查找创建的QWidgets。
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
标志用于指示是否在ui_textEdit
内容中找到searchString
。如果没有找到,则使用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 文件。
另请参阅 计算器生成器。
© 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.