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

时间:2012-05-22 13:33:09

标签: c++ qt qt-creator

我刚开始学习Qt,我正在尝试使用此QUiLoader创建一个简单的小部件。但我收到此错误:“Designer:在第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

1 个答案:

答案 0 :(得分:4)

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

为了向项目添加资源,您需要创建一个资源文件,列出要注册为资源的文件。该文件将是另一个XML文件,可以由QtCreator创建和编辑。在项目管理器中,添加另一个文件并选择类型Qt - &gt;来自对话框内的Qt资源文件。

在你的.pro文件中会出现一个部分:

RESOURCES += \
    resources.qrc

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

请注意,此类UI创建在运行时中进行。这意味着,它更灵活(可能只在运行时创建ui文件),但速度稍慢(因为解析和更多的运行时处理发生)。


如果您是Qt的新手,您可能不知道您也可以让Qt在构建过程中为您的ui文件创建一个类文件。当您在FORMS +=部分的专业文件中列出您的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;
}