1.什麼是Qt
Qt是一個跨平台的==C++==圖形使用者界面(GUI)應用程式架構。
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiIyVGduV2YfNWawNCM38FdsYkRGZkRG9lcvx2bjxiNx8VZ6l2cs0TPnplZCpWTmR2MMBjVtJWd0ckW65UbM5WOHJWa5kHT20ESjBjUIF2X0hXZ0xCMx81dvRWYoNHLrdEZwZ1Rh5WNXp1bwNjW1ZUba9VZwlHdssmch1mclRXY39CXldWYtlWPzNXZj9mcw1ycz9WL49zZuBnLwczNyEjNzEjMwITNwAjMwIzLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
2.建立一個新Qt視窗檔案
2.1第一步
按如上選擇,生成一個帶Qt Widget 的APP
2.2第二步
路徑不能有中文
2.3第三步
相當于選擇編譯器
2.4第四步
QMainWindow、QWidget、QDialog都是基類。QMainWindow是一個帶菜單欄的視窗,主要用在Windows下;QWidget是Qt視窗類的一個基類,空白視窗,所有按鈕标簽都繼承于此基類;QDialog是一個對話框(不能伸縮)。
類名MyWidget是QWidget的子類,Qt會生成名為mywidget.h的頭檔案和mywidget.c的檔案。mywidget.h檔案中會有一行代碼:
class MyWidget:public QWidget
代表MyWidget繼承自父類QWidget
建立界面是用來圖形化設計界面,第一天用不到。
2.5完成
最後會Qt工程會生成以下檔案:
軟體左下角為編譯等按鈕:
最上為項目,生成可執行檔案類型的選擇;第二個為編譯且運作;第三個為編譯并調試;第四個為編譯不運作。運作完會生成一個空白視窗。按下以上按鈕會在同級目錄下生成一個檔案夾,裡面有不同類型的可執行檔案,以build開頭:
3. 生成的新Qt視窗檔案
3.1 main.cpp為主函數,它的内容為:
#include "mywidget.h"
//QApplication應用程式類
//Qt頭檔案沒有.h
//頭檔案和類名一樣
#include <QApplication>
int main(int argc, char *argv[])
{
//有且隻有一個應用程式類的對象a
QApplication a(argc, argv);
//MyWidget繼承于QWidget ,QWidget是一個視窗基類
//MyWidget也是視窗類
//w就是一個視窗
MyWidget w;
//視窗預設隐藏,需要人為調用show顯示
w.show();
//讓程式一直執行,等待使用者操作
//等待事件的發生
a.exec();
return 0;
}
3.2mywidget.h為mywidget視窗類檔案,内容為:
#ifndef MYWIDGET_H
#define MYWIDGET_H
#include <QWidget>
class MyWidget : public QWidget
{
//信号與槽的時候需要
Q_OBJECT
public:
MyWidget(QWidget *parent = 0);
~MyWidget();
};
#endif // MYWIDGET_H
3.3 Qt_test.pro為項目檔案,内容為:
#子產品
QT += core gui
#高于QT4版本添加 QT += widgets,為了相容Qt4
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
#應用程式的名字
TARGET = Qt1_test
#指定makefile的類型,app
TEMPLATE = app
DEFINES += QT_DEPRECATED_WARNINGS
CONFIG += c++11
#源檔案 .cpp檔案
SOURCES += \
main.cpp \
mywidget.cpp \
subwidget.cpp
#頭檔案 .h檔案
HEADERS += \
mywidget.h \
subwidget.h
# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
4.第一個Qt程式
按上章節建立Qt視窗程式。
4.1添加QWidget控件
程式添加頭檔案:
#include<QWidget> //包含頭檔案
主程式main.cpp中寫入以下代碼可以直接調用:
//執行FirstWidget的構造函數
FirstWidget w;
//視窗預設隐藏,需要人為顯示
w.show();
添加頭檔案firstwidget.h:
#include <QWidget>
class FirstWidget : public QWidget
{
Q_OBJECT //信号與槽
public:
FirstWidget(QWidget *parent = 0);
~FirstWidget();
private:
};
添加.cpp檔案firstwidget.cpp:
FirstWidget::FirstWidget(QWidget *parent)
: QWidget(parent)
{
}
FirstWidget繼承自父類QWidget,若直接運作此程式,則出現以下内容:
僅有一個空視窗,無其他内容。
4.2 添加QPushButton控件
僅一個空視窗無法滿足要求,是以需要加入QPushButton控件。程式添加頭檔案:
#include<QPushButton>
需要代用QPushButton控件的程式寫以下程式段:
QPushButton b1; //初始化QPushButton控件b1
b1.setText("NMSL"); //設定按鍵内容
b1.show(); //顯示按鍵
程式執行後内容如下:
在上圖中,有一個空視窗和一個按鈕,但是存在一個問題就是他們在兩個視窗内,為讓其“合并”,還需要指定父對象。
4.3 指定父對象
如果不指定父對象,對象和對象(視窗和視窗)獨立。a指定b為它的父對象,a放在b上面。指定父對象有2種方式:(1)setParent(2)通過構造函數傳參。指定父對象,隻需要父對象顯示,上面的子對象自動顯示,如:
b1.setParent(&w);
上述是通過setParent方法設定按鈕b1父對象是w視窗。
QPushButton b1(&w);
上述是通過構造函數傳參方法設定按鈕b1父對象是w視窗。
程式運作結果如下:
隻有一個視窗,主視窗上顯示兩個按鈕,結合在一起合并顯示。另外為不斷運作後按鈕還能顯示在視窗上,按鈕相關的所有程式寫在視窗類firstwidget中,即firstwidget.cpp和.h中。按鈕聲明在.h,寫下:
private:
QPushButton b1;
用按鈕寫在.cpp中:
b1.setParent(this); //指定b1的父對象是目前的類,this指FirstWidget
b1.setText("NMSL");
b1.move(100,100);
主函數中直接使用w.show函數可顯示。
4.4 标準信号與槽
信号與槽機制非常重要,接收到某個信号,執行某個槽函數。需要添加槽信号與槽、在firstwidget.cpp中添加:
connect(&b1,&QPushButton::pressed, this , &QWidget::close);
/*
* &b1 信号發出者,指針類型
* &QPushButton::pressed 處理的信号, &發送者的類名::信号名字
* this 信号接收者
* &FirstWidget::close 槽函數,信号處理函數 &接收的類名::槽函數名字
*/
這段代碼含義是b1按下,FirstWidget視窗關閉,FirstWidget是繼承QWiget的類。程式執行後點選b1按鈕視窗關閉。
4.5 自定義槽函數
有時Qt提供的槽函數不能滿足我們的要求,或者需要一個信号執行多個操作時,我們就需要自定義槽函數。
在頭檔案firstwidget.h裡面添加:
public:
void myslot();
在源檔案firstwidget.cpp的FirstWidget類裡面添加:
connect(b2,&QPushButton::pressed, this , &FirstWidget::myslot);
/*
* 自定義槽,普通函數
* Qt5:任意的成員函數,普通全局函數,靜态函數
* 槽函數需要和信号一緻
* 因為信号都沒有傳回值,是以槽函數也一定沒有傳回值
*/
這段代碼含義是b2按下,執行我們自定義的槽函數myslot。程式執行後點選b1按鈕視窗關閉。
源檔案firstwidget.cpp中槽函數内容是:
void FirstWidget::myslot()
{
b1.setText("QNMD"); //b1顯示QNMD
}
b1按鈕上文字改變為QNMD,槽函數myslot為視窗類FirstWidget的子類。
4.6 兩個獨立視窗
有時我們需要在主視窗上點選一個按鈕出現副視窗。下面具體說明步驟:
首先,往工程裡面添加副視窗,Qt自動生成頭檔案subwidget.h和源檔案subwidget.cpp。雖然生成了副視窗,但是通過主視窗我們無法進入副視窗,是以需要在firstwidget中添加副視窗。firstwidget.h檔案中添加頭檔案#include"subwidget.h",firstwidget視窗類中聲明一個副視窗w1:
#include"subwidget.h"
class FirstWidget : public QWidget
{
private:
QPushButton b3;
SubWidget w1;
}
b3按鈕用來召喚出副視窗w1,w1是副視窗。firstwidget.cpp源檔案中添加代碼:
connect(&b3,&QPushButton::released,this, &FirstWidget::changeWin);
代表b3按下後釋放,主視窗函數調用使用者自定義函數changWin,這個函數作用是顯示副視窗w1。
4.7自定義信号
4.6小節是主視窗顯示副視窗的過程,主視窗FirstWidget包含副視窗,是副視窗的父類。是以主視窗隻要通過信号直接調用槽函數就可以顯示副視窗。但是如何從副視窗傳回主視窗,副視窗如何與主視窗通信,這就必須用到自定義信号,副視窗内某事件發送時,副視窗子類向主視窗父類發送某個信号,主視窗在判斷該不該對這個信号做出反應,又應該做出什麼反應。自定義信号要在subwidget.h頭檔案中添加代碼:
class SubWidget : public QWidget
{
public:
void sendSlot();
private:
QPushButton b;
signals:
/*
* 信号必須有signals關鍵字來聲明
* 信号沒有傳回值,但可以有參數
* 信号就是函數的聲明,隻需聲明,無需定義
* 使用:emit mySignal();
*/
void mySignal();
};
b為按鍵;sendSlot為自定義函數,按鍵觸發後調用;mySignal為信号,向主視窗發送。然後在源檔案subwidget.cpp中寫入:
SubWidget::SubWidget(QWidget *parent) : QWidget(parent)
{
setWindowTitle("第二視窗");
b.setParent(this);
b.setText("切換到主視窗");
connect(&b,&QPushButton::pressed,this, &SubWidget::sendSlot);
resize(300,300);
}
void SubWidget::sendSlot()
{
emit mySignal();
}
上述函數作用是當b按鈕按下時,發送信号mySignal。
在主視窗主FirstWidget.cpp中隻需要添加:
connect(&w,&SubWidget::mySignal,this,&FirstWidget::dealSignal);
用來接收來自子視窗的信号mySignal,然後調用槽函數重新顯示主視窗即可。
程式運作結果如下:
當按下切換到下一個視窗按鈕:
再次按下切換到主視窗按鈕則傳回主視窗。