首先,按照前面章節的方法,創建一個工程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界面及代碼之間的聯繫。