Qt創建一個按鈕,點擊按鈕關閉窗口


一、概述

  開發工具:Qt Creator 

  QApplication類簡單介紹:

QApplication應用程序類
    1.管理圖形用戶界面應用程序的控制流和主要設置。
    2.是Qt的整個后台管理的命脈它包含主事件循環,在其中來自窗口系統和其它資源的所有事件處理和調度。它也處理應用程序的初始化和結束,並且提供對話管理。
    3.對於任何一個使用Qt的圖形用戶界面應用程序,都正好存在一個QApplication     對象,而不論這個應用程序在同一時間內是不是有0、1、2或更多個窗口。
    4.exec()方法:程序進入消息循環,等待對用戶輸入進行響應。這里main()把控制權轉交給Qt,Qt完成事件處理工作,當應用程序退出的時候exec()的值就會返回。在exec()中,Qt接受並處理用戶和系統的事件並且把它們傳遞給適當的窗口部件。

 對象模型(對象樹)介紹:

在Qt中創建對象的時候會提供一個Parent對象指針,下面來解釋這個parent到底是干什么的。
    1.QObject是以對象樹的形式組織起來的。
    2.當你創建一個QObject對象時,會看到QObject的構造函數接收一個QObject指針作為參數,這個參數就是 parent,也就是父對象指針。這相當於,在創建QObject對象時,可以提供一個其父對象,我們創建的這個QObject對象會自動添加到其父對象的children()列表。
    3.當父對象析構的時候,這個列表中的所有對象也會被析構。(注意,這里的父對象並不是繼承意義上的父類!)這種機制在 GUI 程序設計中相當有用。例如,一個按鈕有一個QShortcut(快捷鍵)對象作為其子對象。當我們刪除按鈕的時候,這個快捷鍵理應被刪除。這是合理的。
    4.QWidget是能夠在屏幕上顯示的一切組件的父類。
    5.QWidget繼承自QObject,因此也繼承了這種對象樹關系。一個孩子自動地成為父組件的一個子組件。因此,它會顯示在父組件的坐標系統中,被父組件的邊界剪裁。例如,當用戶關閉一個對話框的時候,應用程序將其刪除,那么,我們希望屬於這個對話框的按鈕、圖標等應該一起被刪除。事實就是如此,因為這些都是對話框的子組件。
    6.當然,我們也可以自己刪除子對象,它們會自動從其父對象列表中刪除。比如,當我們刪除了一個工具欄時,其所在的主窗口會自動將該工具欄從其子對象列表中刪除,並且自動調整屏幕顯示。
    Qt 引入對象樹的概念,在一定程度上解決了內存問題。
    7.當一個QObject對象在堆上創建的時候,Qt 會同時為其創建一個對象樹。不過,對象樹中對象的順序是沒有定義的。這意味着,銷毀這些對象的順序也是未定義的。
    8.任何對象樹中的 QObject對象 delete 的時候,如果這個對象有 parent,則自動將其從 parent 的children()列表中刪除;如果有孩子,則自動 delete 每一個孩子。Qt 保證沒有QObject會被 delete 兩次,這是由析構順序決定的。
    如果QObject在棧上創建,Qt 保持同樣的行為。正常情況下,這也不會發生什么問題。來看下下面的代碼片段:
    {
        QWidget window;
        QPushButton quit("Quit", &window);
    }
    作為父組件的 window 和作為子組件的 quit 都是QObject的子類(事實上,它們都是QWidget的子類,而QWidget是QObject的子類)。這段代碼是正確的,quit 的析構函數不會被調用兩次,因為標准 C++要求,局部對象的析構順序應該按照其創建順序的相反過程。因此,這段代碼在超出作用域時,會先調用 quit 的析構函數,將其從父對象 window 的子對象列表中刪除,然后才會再調用 window 的析構函數。
    但是,如果我們使用下面的代碼:
    {
        QPushButton quit("Quit");
        QWidget window;
        quit.setParent(&window);
    }
    情況又有所不同,析構順序就有了問題。我們看到,在上面的代碼中,作為父對象的 window 會首先被析構,因為它是最后一個創建的對象。在析構過程中,它會調用子對象列表中每一個對象的析構函數,也就是說, quit 此時就被析構了。然后,代碼繼續執行,在 window 析構之后,quit 也會被析構,因為 quit 也是一個局部變量,在超出作用域的時候當然也需要析構。但是,這時候已經是第二次調用 quit 的析構函數了,C++ 不允許調用兩次析構函數,因此,程序崩潰了。
    由此我們看到,Qt 的對象樹機制雖然幫助我們在一定程度上解決了內存問題,但是也引入了一些值得注意的事情。這些細節在今后的開發過程中很可能時不時跳出來煩擾一下,所以,我們最好從開始就養成良好習慣,在 Qt 中,盡量在構造的時候就指定 parent 對象,並且大膽在堆上創建。

 

二、創建程序步驟

 

 

 

 

 

 

 

 

 

 

三、代碼示例

  整個小案例的目錄結構:

  2.主類main.cpp的代碼

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

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Widget w;
    QPushButton *btn = new QPushButton;
    btn->setParent(&w);//設置父控件
    btn->setText("皮城女警");//給按鈕設置文字
    btn->move(100,100);

    w.setWindowTitle("項目主頁");//窗口標題
    w.setFixedSize(800,480);//窗口大小


    //創建一個關閉按鈕
    QPushButton *closeBtn = new QPushButton("關閉窗口",&w);
    closeBtn->move(300,300);
    //點擊closeBtn關閉窗口
    /**
     * @brief QObject::connect
     * 參數介紹:
     * 1.sender發出信號的對象
     * 2.signal發送對象發出的信號
     * 3.receiver接收信號的對象
     * 4.solt接收對象在接收到信號之后所需要調用的函數(槽函數)
     */
    QObject::connect(closeBtn,&QPushButton::clicked,&w,&Widget::close);

    w.show();//將widget show出來,因此在widget上的子控件都將顯示出來。

    return a.exec();
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM