计算器生成器

在运行时从Qt Widgets Designer 表单创建用户界面。

我们使用计算器表单示例中创建的表单来说明,同样的用户界面可以在执行应用程序时生成,也可以在构建应用程序时定义。

准备工作

计算器表单示例定义了一个无需修改即可使用的用户界面。在本例中,我们使用一个资源文件来包含上例中创建的calculatorform.ui 文件,但也可以将其存储在磁盘上。

要在运行时生成表单,我们需要将示例与QtUiTools 模块库链接。我们使用的项目文件包含所有必要信息:

target_link_libraries(calculatorbuilder PUBLIC
    Qt::Core
    Qt::Gui
    Qt::UiTools
    Qt::Widgets
)

用户界面文件是从资源中加载的:

set(calculatorbuilder_resource_files
    "calculatorform.ui"
)

对于qmake

RESOURCES   = calculatorbuilder.qrc
SOURCES     = main.cpp
QT += widgets uitools

所有其他必要文件的声明与往常一样。

加载计算器表单

我们需要使用libQtUiTools 库提供的QUiLoader 类,因此首先要确保包含该模块的头文件:

#include <QtUiTools>

我们创建了一个静态辅助函数,用于创建一个顶层部件,并加载我们通过QFile 对象从示例资源中获取的用户界面:

static QWidget *loadCalculatorForm(QWidget *parent = nullptr)
{
    QUiLoader loader;

    QFile file(u":/forms/calculatorform.ui"_s);
    if (!file.open(QFile::ReadOnly))
        return nullptr;
    QWidget *formWidget = loader.load(&file, parent);
    file.close();
    if (formWidget == nullptr)
        return nullptr;

通过在示例资源中包含用户界面,我们可以确保在运行示例时用户界面会出现在示例中。loader.load() 函数获取文件中包含的用户界面描述,并将表单部件构建为CalculatorForm 的子部件。

我们对生成的用户界面中的三个部件感兴趣:两个旋转框和一个标签。为方便起见,我们从FormBuilder 构建的 widget 中获取指向这些 widget 的指针,并记录下来以备后用。findChild() 模板函数允许我们查询 widget,以便找到已命名的子 widget。

    auto *inputSpinBox1 = formWidget->findChild<QSpinBox*>(u"inputSpinBox1"_s);
    auto *inputSpinBox2 = formWidget->findChild<QSpinBox*>(u"inputSpinBox2"_s);
    auto *outputWidget = formWidget->findChild<QLabel*>(u"outputWidget"_s);

修改表单提供的输出 widget 的槽的定义方法与计算器表单示例中的类似,只是我们使用了 lambda 来捕获找到的 widget:

    auto updateResult = [inputSpinBox1, inputSpinBox2, outputWidget]()
    {
        const int sum = inputSpinBox1->value() + inputSpinBox2->value();
        outputWidget->setText(QString::number(sum));
    };
    QObject::connect(inputSpinBox1, &QSpinBox::valueChanged, formWidget, updateResult);
    QObject::connect(inputSpinBox2, &QSpinBox::valueChanged, formWidget, updateResult);

表单部件被添加到布局中,窗口标题也被设置:

auto *layout = new QVBoxLayout(&w);
layout->addWidget(formWidget);
w.setWindowTitle(QCoreApplication::translate("CalculatorForm",
                                             "Calculator Builder"));

这种方法的优点是,我们可以在程序运行时替换表单,但我们仍然可以操作表单中的部件,只要给它们取一个合适的名称即可。

不过,与使用User Interface Compiler (uic)工具将表单转换为 C++ 代码相比,在运行时加载表单会产生运行时成本。

示例项目 @ code.qt.io

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