2018-01-11:Qt5界面開發(fā)中如何渲染出界面

在Qt5項目中要想讓程序運行時顯示出我們設計的界面逆甜,關鍵是要執(zhí)行界面文件生成的類中的setupUi(QWidget *Widget)函數(shù)镰吆,否則界面是無法顯示出來的.

首先芒粹,我們來看一下自動生成的Qt5項目中是如何調(diào)用界面類中的setupUi()函數(shù)的.

widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT

public:
    explicit Widget(QWidget *parent = 0);
    ~Widget();

private slots:
    void on_pushButton_clicked();

private:
    Ui::Widget *ui;
};

#endif // WIDGET_H

可以看出超棺,在該頭文件中镐侯,首先是前置聲明了Ui界面類奕巍,也就是通過uic工具吟策,將我們設計的.ui文件翻譯成標準的界面頭文件中的界面類.
然后,定義了一個一個繼承自QWidget的類Widget, 并且將界面類的作為其私有子對象.

namespace Ui {
class Widget;
}
...

private:
    Ui::Widget *ui;

接著我們來看widget.cpp
widget.cpp

#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
}

Widget::~Widget()
{
    delete ui;
}

void Widget::on_pushButton_clicked()
{

}

可以看出的止,在這里檩坚,繼承自QWidget的Widget類的構造函數(shù)實現(xiàn)了對類Widget子對象ui實現(xiàn)了初始化操作

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this); #這里的this就是調(diào)用構造函數(shù)的對象
}

一種與上面等效的簡單直接的方式如下:

#include <QApplication>
#include <QDialog>
#include "ui_dialog.h"
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Ui::Dialog ui;
    QDialog *d=new QDialog;
    ui. setupUi(d);
    d->show();
    return a.exec();
}

main.cpp文件

#include "widget.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Widget w;
    w.show();

    return a.exec();
}

界面頭文件
ui_widget.h

/********************************************************************************
** Form generated from reading UI file 'widget.ui'
**
** Created by: Qt User Interface Compiler version 5.9.3
**
** WARNING! All changes made in this file will be lost when recompiling UI file!
********************************************************************************/

#ifndef UI_WIDGET_H
#define UI_WIDGET_H

#include <QtCore/QVariant>
#include <QtWidgets/QAction>
#include <QtWidgets/QApplication>
#include <QtWidgets/QButtonGroup>
#include <QtWidgets/QHeaderView>
#include <QtWidgets/QPushButton>
#include <QtWidgets/QWidget>

QT_BEGIN_NAMESPACE

class Ui_Widget
{
public:
    QPushButton *pushButton;

    void setupUi(QWidget *Widget)
    {
        if (Widget->objectName().isEmpty())
            Widget->setObjectName(QStringLiteral("Widget"));
        Widget->setEnabled(false);
        Widget->resize(927, 533);
        QIcon icon;
        icon.addFile(QStringLiteral("../../python3_project/heihei.png"), QSize(), QIcon::Normal, QIcon::Off);
        Widget->setWindowIcon(icon);
        Widget->setWindowOpacity(0.5);
        pushButton = new QPushButton(Widget);
        pushButton->setObjectName(QStringLiteral("pushButton"));
        pushButton->setGeometry(QRect(430, 250, 106, 29));

        retranslateUi(Widget);
        QObject::connect(pushButton, SIGNAL(clicked()), Widget, SLOT(close()));

        QMetaObject::connectSlotsByName(Widget);
    } // setupUi

    void retranslateUi(QWidget *Widget)
    {
        Widget->setWindowTitle(QApplication::translate("Widget", "MyWidget", Q_NULLPTR));
        pushButton->setText(QApplication::translate("Widget", "PushButton", Q_NULLPTR));
    } // retranslateUi

};

namespace Ui {
    class Widget: public Ui_Widget {};
} // namespace Ui

QT_END_NAMESPACE

#endif // UI_WIDGET_H

補充資料 1:
使用new創(chuàng)建對象指針
使用delete刪除對象指針
使用new創(chuàng)建對象對象的同時,會返回對象的指針诅福,因此匾委,我們需要定義一個類的指針變量來接收返回的對象指針.

ClassName *object=new ClassName(param);
delete object;

除了這種通過new方法創(chuàng)建對象外,還有我們最常用的創(chuàng)建對象的方式:

ClassName object(param);

這樣就聲明了一個ClassName類型的object對象氓润,C++會為它分配足夠的存放對象所有成員的存儲空間.
注意:為節(jié)省存儲空間赂乐,C++創(chuàng)建對象時僅分配用于保存數(shù)據(jù)成員的空間,而類中定義的成員函數(shù)則被分配到存儲空間中的一個公用區(qū)域咖气,由該類的所有對象共享.
這種方法創(chuàng)建的對象挨措,內(nèi)存分配是分配到棧中的,由C++缺省創(chuàng)建和撤銷崩溪,自動調(diào)用構造函數(shù)和析構函數(shù).
注意:該方法創(chuàng)建的對象調(diào)用類方法時运嗜,必須用“.”,而不能用“->”.
使用這種方式創(chuàng)建的類對象悯舟,在創(chuàng)建之初就已經(jīng)分配了內(nèi)存空間. 而類指針,如果未經(jīng)過對象初始化砸民,則不需要delete釋放, 因為沒有初始化就沒有為指針綁定的對象分配內(nèi)存.
一般來說抵怎,編譯器將內(nèi)存分為三部分:靜態(tài)存儲區(qū)域、棧岭参、堆反惕。靜態(tài)存儲區(qū)主要保存全局變量和靜態(tài)變量,棧存儲調(diào)用函數(shù)相關的變量演侯、地址等姿染,堆存儲動態(tài)生成的變量
C++中有三種創(chuàng)建對象的方法:

#include <iostream>  
using namespace std;  
class A  
{  
private:  
    int n;  
public:  
    A(int m):n(m)  
    { }  
    ~A(){}  
};  
int main()  
{  
    A a(1);  //棧中分配  
    A b = A(1);  //棧中分配  
    A* c = new A(1);  //堆中分配  
  delete c;  
    return 0;  
}

第一種和第二種沒什么區(qū)別,一個隱式調(diào)用,一個顯式調(diào)用悬赏,兩者都是在進程虛擬地址空間中的棧中分配內(nèi)存狡汉,而第三種使用了new,在堆中分配了內(nèi)存闽颇,而棧中內(nèi)存的分配和釋放是由系統(tǒng)管理盾戴,而堆中內(nèi)存的分配和釋放必須由程序員手動釋放。采用第三種方式時兵多,必須注意一下幾點問題:

new創(chuàng)建類對象需要指針接收尖啡,一處初始化,多處使用
new創(chuàng)建類對象使用完需delete銷毀
new創(chuàng)建對象直接使用堆空間剩膘,而局部不用new定義類對象則使用椥普叮空間
new對象指針用途廣泛,比如作為函數(shù)返回值怠褐、函數(shù)參數(shù)等
頻繁調(diào)用場合并不適合new畏梆,就像new申請和釋放內(nèi)存一樣
棧的大小遠小于堆的
棧是機器系統(tǒng)提供的數(shù)據(jù)結構,計算機會在底層對棧提供支持:分配專門的寄存器存放棧的地址惫搏,壓棧出棧都有專門的指令執(zhí)行具温,這就決定了棧的效率 比較高。堆則是C/C++函數(shù)庫提供的筐赔,它的機制是很復雜的铣猩,例如為了分配一塊內(nèi)存,庫函數(shù)會按照一定的算法(具體的算法可以參考數(shù)據(jù)結構/操作系統(tǒng))在 堆內(nèi)存中搜索可用的足夠大小的空間茴丰,如果沒有足夠大小的空間(可能是由于內(nèi)存碎片太多)达皿,就有可能調(diào)用系統(tǒng)功能去增加程序數(shù)據(jù)段的內(nèi)存空間,這樣就有機會 分 到足夠大小的內(nèi)存贿肩,然后進行返回峦椰。顯然,堆的效率比棧要低得多汰规。

參考文獻

補充資料 2
什么是堆內(nèi)存汤功?什么是棧內(nèi)存?
棧區(qū)(stack)— 由編譯器自動分配釋放 溜哮,存放函數(shù)的參數(shù)值滔金,局部變量的值等。其操作方式類似于數(shù)據(jù)結
構中的棧茂嗓。
內(nèi)存中的棧區(qū)處于相對較高的地址以地址的增長方向為上的話餐茵,棧地址是向下增長的。

棧中分配局部變量空間述吸,堆區(qū)是向上增長的用于分配程序員申請的內(nèi)存空間忿族。另外還有靜態(tài)區(qū)是分配靜態(tài)變量,全局變量空間的;只讀區(qū)是分配常量和程序代碼空間的道批;以及其他一些分區(qū)错英。

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市屹徘,隨后出現(xiàn)的幾起案子走趋,更是在濱河造成了極大的恐慌,老刑警劉巖噪伊,帶你破解...
    沈念sama閱讀 216,544評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件簿煌,死亡現(xiàn)場離奇詭異,居然都是意外死亡鉴吹,警方通過查閱死者的電腦和手機姨伟,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,430評論 3 392
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來豆励,“玉大人夺荒,你說我怎么就攤上這事×颊簦” “怎么了技扼?”我有些...
    開封第一講書人閱讀 162,764評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長嫩痰。 經(jīng)常有香客問我剿吻,道長,這世上最難降的妖魔是什么串纺? 我笑而不...
    開封第一講書人閱讀 58,193評論 1 292
  • 正文 為了忘掉前任丽旅,我火速辦了婚禮,結果婚禮上纺棺,老公的妹妹穿的比我還像新娘榄笙。我一直安慰自己,他們只是感情好祷蝌,可當我...
    茶點故事閱讀 67,216評論 6 388
  • 文/花漫 我一把揭開白布茅撞。 她就那樣靜靜地躺著,像睡著了一般巨朦。 火紅的嫁衣襯著肌膚如雪米丘。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,182評論 1 299
  • 那天罪郊,我揣著相機與錄音,去河邊找鬼尚洽。 笑死悔橄,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播癣疟,決...
    沈念sama閱讀 40,063評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了舞箍?” 一聲冷哼從身側(cè)響起溃蔫,我...
    開封第一講書人閱讀 38,917評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎扎狱,沒想到半個月后侧到,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,329評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡淤击,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,543評論 2 332
  • 正文 我和宋清朗相戀三年匠抗,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片污抬。...
    茶點故事閱讀 39,722評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡汞贸,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出印机,到底是詐尸還是另有隱情矢腻,我是刑警寧澤,帶...
    沈念sama閱讀 35,425評論 5 343
  • 正文 年R本政府宣布射赛,位于F島的核電站多柑,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏咒劲。R本人自食惡果不足惜顷蟆,卻給世界環(huán)境...
    茶點故事閱讀 41,019評論 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望腐魂。 院中可真熱鬧帐偎,春花似錦、人聲如沸蛔屹。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,671評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽兔毒。三九已至漫贞,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間育叁,已是汗流浹背迅脐。 一陣腳步聲響...
    開封第一講書人閱讀 32,825評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留豪嗽,地道東北人谴蔑。 一個月前我還...
    沈念sama閱讀 47,729評論 2 368
  • 正文 我出身青樓豌骏,卻偏偏與公主長得像,于是被迫代替她去往敵國和親隐锭。 傳聞我的和親對象是個殘疾皇子窃躲,可洞房花燭夜當晚...
    茶點故事閱讀 44,614評論 2 353