首先,按照前面章节的方法,创建一个工程demo,位于目录demo/下,然后直接编译运行。弹出一个空窗口,如下:
工程项目在Qt creator的管理界面显示如下:
在工程目录demo/下,生成了两个文件夹:build-xxx-Debug和demo,
所含文件分别如下:
Qt creator中的项目界面显示的文件与这两个文件夹分别是什么关系?demo里面的就是Qt creator中显示的文件,是重要的源码文件,而build-xxx-Debug似乎并不重要,只是编译生成的一些目标文件。确实也如此,把build-xxx-Debug文件夹删掉,重新编译工程,还能重新生成。
一、文件夹build-xxx-Debug与demo之间的关系
从上面的实验来看,build-xxx-Debug只是临时生成的,无关重要,而demo里面的才是真正有用的文件。
首先从xxx.ui文件入手,这是个界面文件,添加控件:一个“Hello world”的标签label
然后,编译,运行,结果:如你所想
查看代码添加了什么内容。。。没变化???!!!
按理来说,我把一个控件拉进界面里面,重新编译出来的源码会添加相应的代码,但是,事实并没有并没有。
mainwindow.cpp代码如下:
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
MainWindow::~MainWindow()
{
delete ui;
}
确实没有"Hello world"的label相关代码,但是发现包含的一个头文件“ui_mainwindow.h”,这个文件不在Qt creator的项目界面上,也不在demo目录下,而是在build-xxx-Debug里面。其代码如下:
/********************************************************************************
** Form generated from reading UI file 'mainwindow.ui'
**
** Created by: Qt User Interface Compiler version 5.12.4
**
** WARNING! All changes made in this file will be lost when recompiling UI file!
********************************************************************************/
#ifndef UI_MAINWINDOW_H
#define UI_MAINWINDOW_H
#include <QtCore/QVariant>
#include <QtWidgets/QApplication>
#include <QtWidgets/QLabel>
#include <QtWidgets/QMainWindow>
#include <QtWidgets/QMenuBar>
#include <QtWidgets/QStatusBar>
#include <QtWidgets/QToolBar>
#include <QtWidgets/QWidget>
QT_BEGIN_NAMESPACE
class Ui_MainWindow
{
public:
QWidget *centralWidget;
QLabel *label;
QMenuBar *menuBar;
QToolBar *mainToolBar;
QStatusBar *statusBar;
void setupUi(QMainWindow *MainWindow)
{
if (MainWindow->objectName().isEmpty())
MainWindow->setObjectName(QString::fromUtf8("MainWindow"));
MainWindow->resize(400, 300);
centralWidget = new QWidget(MainWindow);
centralWidget->setObjectName(QString::fromUtf8("centralWidget"));
label = new QLabel(centralWidget);
label->setObjectName(QString::fromUtf8("label"));
label->setGeometry(QRect(60, 60, 101, 31));
MainWindow->setCentralWidget(centralWidget);
menuBar = new QMenuBar(MainWindow);
menuBar->setObjectName(QString::fromUtf8("menuBar"));
menuBar->setGeometry(QRect(0, 0, 400, 28));
MainWindow->setMenuBar(menuBar);
mainToolBar = new QToolBar(MainWindow);
mainToolBar->setObjectName(QString::fromUtf8("mainToolBar"));
MainWindow->addToolBar(Qt::TopToolBarArea, mainToolBar);
statusBar = new QStatusBar(MainWindow);
statusBar->setObjectName(QString::fromUtf8("statusBar"));
MainWindow->setStatusBar(statusBar);
retranslateUi(MainWindow);
QMetaObject::connectSlotsByName(MainWindow);
} // setupUi
void retranslateUi(QMainWindow *MainWindow)
{
MainWindow->setWindowTitle(QApplication::translate("MainWindow", "MainWindow", nullptr));
label->setText(QApplication::translate("MainWindow", "Hello world", nullptr));
} // retranslateUi
};
namespace Ui {
class MainWindow: public Ui_MainWindow {};
} // namespace Ui
QT_END_NAMESPACE
#endif // UI_MAINWINDOW_H
竟然惊奇地发现,有我们之前添加的label,而且setText设置文本为"Hello world"!
看来,就是它了!不信?可以再拉些控件进来重新编译生成,再看这个文件是否有产生相关代码。
二、操作xxx.ui界面文件如何转换成相应程序代码?
其实,xxx.ui文件是一个XML文件,在Qt creator双击打开就是显示窗口界面,以文本方式打开:
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<widget class="QWidget" name="centralWidget">
<widget class="QLabel" name="label">
<property name="geometry">
<rect>
<x>60</x>
<y>60</y>
<width>101</width>
<height>31</height>
</rect>
</property>
<property name="text">
<string>Hello world</string>
</property>
</widget>
</widget>
<widget class="QMenuBar" name="menuBar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>28</height>
</rect>
</property>
</widget>
<widget class="QToolBar" name="mainToolBar">
<attribute name="toolBarArea">
<enum>TopToolBarArea</enum>
</attribute>
<attribute name="toolBarBreak">
<bool>false</bool>
</attribute>
</widget>
<widget class="QStatusBar" name="statusBar"/>
</widget>
<layoutdefault spacing="6" margin="11"/>
<resources/>
<connections/>
</ui>
可看出,全是XML语言描述的,其作用就是通过XML语言定义了窗口上的所有组件的属性设置、布局,及其信号与槽函数的关联等。当我们在界面上添加/删除控件时,其界面会被解析为相应的XML代码,所以其代码与界面是相互转换、等价的。
其实,Qt是通过一个名为“uic”的工具,将ui文件生成.h文件的(有兴趣的可以自行用命令执行)。
当我们在界面上操作控件时,查看xxx.ui文件会产生相应的代码,如我们添加的label,也出现在上面。
可通过比对“在界面上操作控件”前后代码的变化来一探究竟。
三、通过代码来访问ui界面文件中的控件
1、在ui界面中设置组件属性
我们可以在ui界面右下角的组件属性窗口设置组件的属性,属于图形界面设计方式,如下:
如设置label字体大小和内容在QWidget的“font”和QLabel的“text”里(如图),具体每项属性就不详细列出了。
2、通过代码来访问并操作组件
首先,想要代码访问,必须先知道它的标签是什么,也就是变量名是什么?
在ui界面右下角的组件属性的QObject中objectName就是了,如label的如下图,且支持修改。
同理,往界面上拖入一个按键Push Button组件,可在objectName将其修改(如改为“myButton”)。
现在回到代码中,在mainwindow.cpp中的构造函数访问label组件和button组件,设置其text内容、大小等。
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
/* 设置label属性 */
ui->label->setText("Welcome Zengzr");
ui->label->resize(300,60);
/* 设置PushButton属性 */
ui->myButton->setText("My Button");
}
MainWindow::~MainWindow()
{
delete ui;
}
编译运行,如下图:
如上,通过ui->label和ui->myButton访问,label和myButton均是objctName项的名称。
添加其他组件亦是如此道理。
以上举例较简单,意在梳理清楚ui界面及代码之间的联系。