1. 程式人生 > >重頭開始學Qt——day1

重頭開始學Qt——day1

以前學過Qt,但只是為了學分,現在重學。

 

1. 認識Qt應用程式框架

 

直接新建一個專案後,自動生成了一下檔案,下面一個個理解。

(1)main.cpp

  main.cpp中特別的是QApplication a,和 a.exec();

    如果不構造 QApplication 物件,直接編譯並執行,

  結果:

      成功生成可執行檔案,並且成功執行,但立即退出,並列印異常資訊:

            QWidget: Must construct a QApplication before a QWidget

  上面實驗說明 QApplication 物件被 QWidget 物件使用。

  此外,將 a.exec(); 換成死迴圈。

  結果:

    

 

    QWidget會顯示,但是無法響應使用者操作。

  經過上面兩個實驗,可以得出下面結論:

    QApplication 被 QWidget 呼叫,QApplication 會捕捉使用者輸入,將其傳給 QWidget。

    

(2).pro檔案

  

QT       += core gui

  這是加入連結模組。

  問題是如何知道需要什麼模組呢?

  對使用的類按F1就可以獲得,

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

 

   這是相容Qt4以上版本

TARGET = 01_test

  這是指定目標名稱,也就是最終生成的可執行檔名稱

TEMPLATE = app

  生成應用程式,其他二進位制檔案

SOURCES += \
        main.cpp \
        widget.cpp

HEADERS += \
        widget.h

  類似Makefile

 

(3)Qt的生成應用程式的過程

發現Qt生成應用程式有兩步:qmake 和 構建

實驗發現 qmake 是生成指導編譯連結的Makefile,和建立兩個資料夾debug和release

 

構建應該就是執行makefile

 

2. 父物件與子物件

  父子物件不是繼承關係,有點像組合。

  大概有三個性質:

  (1)父子物件機制是在QObject類中實現的,只有繼承了QObject才能使用父子物件機制。

  (2)父物件show時,子物件也會show,但是子物件不能單獨show,子物件的座標是相對於父物件的。

  (3)父物件析構時,會先析構其子物件,子物件會析構孫子物件。

 

3. 訊號與槽

  訊號與槽是觀察者模式,當控制元件發現自己的某個事件發生後就發出訊號,訊號以廣播形式傳送,誰對該訊號感興趣就呼叫connect函式將訊號與自己的槽函式繫結,只要訊號發生就回調槽函式。

  connect(sender &Sender::signal, receiver, &Receiver::slot);

  (1)關於記憶體分配

    connect 之前,釋放 sender 記憶體,程式執行時出錯, 釋放 receiver,程式執行不會報錯。

    connect 之後,釋放 sender,程式正常執行,釋放receiver,程式正常執行,這說明connect可以通過釋放sender或receiver取消。

  (2)多次執行相同connect

    當訊號發出後,會觸發多次槽函式。

  其他:

    (1)只有繼承了 QObject類並且新增巨集Q_OBJECT才能使用訊號槽。

    (2)訊號無函式體,槽函式可以為任何函式,若槽函式為成員函式,會受訪問許可權影響

    (3)訊號槽可以有引數,但槽函式引數應保證能正確接受訊號引數。

 

4. Lambda表示式

  C++11中的Lambda表示式用於定義並建立匿名的函式物件。

  格式:

[函式物件引數](操作符過載函式引數)mutable或exception ->返回值{函式體}

  []:

    標識Lambda的開始,

    確定函式物件引數(或者說是函式物件的成員函式),注意只能將 Lambda 可見範圍內的變數作為成員函式。

    =:

      以傳值的方式,將Lambda所有可見變數傳入,並且為只讀屬性。

    &:

      以引用方式。將所有可見變數傳入。

    this:

      只將this指標傳入

    a:

      只將指定變數a以傳值方式傳入。

    &a

      只將變數a以引用方式傳入

    mutable:

      以傳值方式傳入的變數可寫。

    ->返回值型別

      當返回型別為void,或只有一處返回,編譯器可以推斷出返回型別,所以可以省略。