Qt - 使用 QUiLoader 加载没有父级的小部件

Qt - Using QUiLoader to load a widget with no parent

本文关键字:小部 使用 QUiLoader 加载 Qt      更新时间:2023-10-16

我刚刚开始学习Qt,我正在尝试使用这个QUiLoader创建一个简单的小部件。但是我收到此错误:"设计器:读取第 1 行第 0 列的 UI 文件时出错:文档过早结束。

#include <QtGui/QApplication>
#include <QtUiTools/QUiLoader>
#include <QFile>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    QUiLoader loader;
    QFile file(":/aks.ui");
    file.open(QFile::ReadOnly);
    QWidget *myWidget = loader.load(&file);
    if(myWidget){
        myWidget->show();
    }
    return a.exec();
}

我使用 QtCreator 2.4.1 构建了 ui 文件,我在 Qt 4.7.4 上。也请查看 ui 文件。

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>Form</class>
 <widget class="QWidget" name="Form">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>131</width>
    <height>129</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>Form</string>
  </property>
  <layout class="QGridLayout" name="gridLayout">
   <item row="0" column="0">
    <layout class="QVBoxLayout" name="verticalLayout">
     <item>
      <widget class="QCheckBox" name="checkBox">
       <property name="text">
        <string>A</string>
       </property>
      </widget>
     </item>
     <item>
      <widget class="QCheckBox" name="checkBox_2">
       <property name="text">
        <string>B</string>
       </property>
      </widget>
     </item>
     <item>
      <widget class="QCheckBox" name="checkBox_3">
       <property name="text">
        <string>C</string>
       </property>
      </widget>
     </item>
     <item>
      <widget class="QCheckBox" name="checkBox_4">
       <property name="text">
        <string>D</string>
       </property>
      </widget>
     </item>
     <item>
      <widget class="QCheckBox" name="checkBox_5">
       <property name="text">
        <string>E</string>
       </property>
      </widget>
     </item>
    </layout>
   </item>
   <item row="0" column="1">
    <widget class="QPushButton" name="pushButton">
     <property name="text">
      <string>PushButton</string>
     </property>
    </widget>
   </item>
  </layout>
 </widget>
 <resources/>
 <connections/>
</ui>

我的项目文件:

#-------------------------------------------------
#
# Project created by QtCreator 2012-05-21T19:48:31
#
#-------------------------------------------------
QT       += core gui
TARGET = Example
TEMPLATE = app

SOURCES += main.cpp 
    sortdialog.cpp
HEADERS  += 
    sortdialog.h
FORMS    += 
    sortdialog.ui 
    aks.ui
CONFIG += uitools

您需要将 .ui 文件添加到项目的资源中。资源是应用程序内部"编译"的文件,然后通过以":/"开头的文件路径提供给Qt类。

为了向项目添加资源,您需要创建一个资源文件,列出要注册为资源的文件。此文件将是另一个XML文件,可以由QtCreator创建和编辑。在项目管理器中,添加另一个文件,然后从对话框中选择 Qt -> Qt 资源文件类型。

然后,在您的 .pro 文件中会出现一个部分:

RESOURCES += 
    resources.qrc

在资源文件中,您需要添加一个前缀;只需将其命名为 /(或将其留空(。在此前缀中,您可以添加文件aks.ui,以便将其命名为 :/aks.ui

请注意,这种类型的 UI 创建在运行时进行。这意味着,它更灵活(也许 ui 文件仅在运行时创建(,但速度稍慢(因为进行了解析和更多的运行时处理(。


如果你是Qt的新手,你可能不知道你也可以让Qt在构建过程中为你的upi文件创建一个类文件。当您在 FORMS += 部分的 pro 文件中列出您的 ui 文件时,这已经完成。

若要使用自动生成的类,还应创建一个设计器窗体类,这是另一个类,您可以在其中放置自己的代码。此类将加载自动生成的类来设置 UI。

所以有两个类:* 为 ui 文件自动生成的类,称为 Ui::Aks(在命名空间 Ui 中(,在文件ui_aks.h生成文件夹中找到。* 你自己的包装类;Acutal Widget 类,它使用 UI 类。

如果你想手动创建第二个类,你可以编写(QtCreator实际上在你添加一个设计器窗体类而不是一个设计器窗体时执行了这一步(:

AKS.H:

#ifndef AKS_H
#define AKS_H
#include <QWidget>
namespace Ui {
    class Aks; // <-- this is the automatically created ui class which we need
}
class aks : public QWidget // <-- your own widget class using the designer UI
{
    Q_OBJECT
public:
    explicit Aks(QWidget *parent = 0);
    ~Aks();
private:
    Ui::Aks *ui; // <-- instance of the automatically created ui class
};
#endif // AKS_H

AKS.cpp:

#include "aks.h"
#include "ui_aks.h" // <-- include the automatically generated ui class
Aks::Aks(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Aks)
{
    ui->setupUi(this); // <-- here, the widgets from the ui file get created
}
Aks::~Aks()
{
    delete ui;
}