[Qt學習]Qt 類中Q_OBJECT的作用及其程序代碼體現

Qt中類裏爲什麼要加上Q_OBJECT這個東西呢,原來這是一個Qt定義的宏.它的作用是什麼呢? 
原來這個宏中包含了Qt中最重要的一個機制:也就是信號和槽的機制.所有的Qt程序一定會使用這個機制!

下面我們可以先看一個簡單的小程序,一個類似於圖片加載器的小程序.

以下是先用Qt設計師簡單拖拽出來的一個沒有經過佈局的圖片:

這裏寫圖片描述

我拖拽了一個QLabel框,兩個QPushButton,並且給他們改過了對象名.


以下是picture.cpp中的代碼:我會一行一行的解釋.

#include "picture.h"picture::picture(QWidget *parent)
    : QWidget(parent)
{
    ui.setupUi(this);
    initSeaList();
    initCliffList();
    ui.label->setScaledContents(true);    this->setWindowTitle(QString::fromLocal8Bit("圖片遊覽"));
    connect(ui.seaButton, SIGNAL(clicked()), this, SLOT(showSeaPictureSlot()));
    connect(ui.cliffButton, SIGNAL(clicked()), this, SLOT(showCliffPictureSlot()));
}

picture::~picture()
{

}void picture::showSeaPictureSlot()
{
    ui.label->setPixmap(QPixmap(seaList[seaNumber % 10]));
    seaNumber++;
}void picture::initSeaList()
{    for (int i = 0; i < 10; ++i)
    {
        QString path = "Pixmap/sea/" + QString::number(i) + ".jpg";
        seaList.push_back(path);
    }
}void picture::showCliffPictureSlot()
{
    ui.label->setPixmap(QPixmap(cliffList[cliffNumber % 10]));
    cliffNumber++;
}void picture::initCliffList()
{    for (int i = 0; i < 10; ++i)
    {
        QString path = "Pixmap/cliff/" + QString::number(i) + ".jpg";
        cliffList.push_back(path);
    }
}123456789101112131415161718192021222324252627282930313233343536373839404142434445

第1行:包含了”picture.h”文件,不用多解釋吧. 
第6行:picure的構造函數中,ui.setupUi(this);用來調用Qt設計師中通過拖拽而形成的頁面. 
第7.8行:對於兩個StringList的初始化,也就是把圖片的相對路徑放到容器中,方便以後調用. 
第9行:ui.label->setScaledContents(true);這個成員函數的作用是把label框中的東西進行填充,舉個例子,如果裏面放了張圖片,但是圖片的大小比label框要小,那麼label框中就會有一些多餘的空白,顯得很難看,而調用了這個函數之後,就可以讓圖片填充滿這個label框. 
第10行:this->setWindowTitle(QString::fromLocal8Bit(“圖片遊覽”));首先通過this指針來設置當前的標題爲”圖片遊覽”,但是由於Qt的編碼問題,顯示中文的話就會亂碼,所以有了fromLocal8Bit()這個函數,它是靜態的,所以可以直接用QString這個類名來調用它. 
第11.12行:通過調用QObject::connect().這個連接函數,來吧QPushButton和Label連接起來,QPushButton如果被單擊了,就會發出clicked()信號,所以會調用一個我們自定義的showSeaPictureSlot函數,這就體現了信號與槽的機制.等於把兩個部件連接了起來,搭上了一層關係.

initSeaList函數中:首先我把10張圖片放在了文件夾裏,然後放在了Pixmap文件中這裏是我對於10張圖片的命名. 
這裏寫圖片描述


然後把Pixmap文件放在了這裏: 
這裏寫圖片描述 
特別注意,要想在程序中調用外部圖片或者電影資源的話,最好和qrc文件放在一起.這樣可以便於查找路徑.(小編用的VS2013+Qt5.2版本,如果不會搭建這個環境的話,可以看我第一個帖子.)


initSeaList()函數中:QString類似於STL中的string,可以直接進行字符串相加,而資源文件的路徑是從qrc文件開始的.所以QString path = “Pixmap/sea/” + QString::number(i) + “.jpg”;,QString::number()也是QString的一個靜態函數,可以把數字轉化爲字符串,十分的方便. 
然後調用seaList.push_back(path);把圖片的路徑放進去就行了.

showCliffPictureSlot()函數中:label->setPixmap(QPixmap())),這個函數是在label框中設置一個圖片的,並且QStringList類似於STL中的vector.所以它也是重載了[]的,可以直接調用.用cliffNumber保存上一次的序號,可以方便遊覽下一張,而cliffNumber%10的作用是:避免訪問的序號超過容器的大小.類似於以前的循環隊列的做法.

以下是picture.h的代碼:

#ifndef PICTURE_H#define PICTURE_H#include <QtWidgets/QWidget>#include "ui_picture.h"#include <QLabel>#include <QPushButton>#include <QPixmap>class picture : public QWidget{
    Q_OBJECTprivate slots:    void showSeaPictureSlot();    void showCliffPictureSlot();public:
    picture(QWidget *parent = 0);
    ~picture();    void initSeaList();    void initCliffList();private:
    Ui::pictureClass ui;    int seaNumber = 0;    int cliffNumber = 0;
    QStringList seaList;
    QStringList cliffList;
};#endif // PICTURE_H1234567891011121314151617181920212223242526272829303132

這裏是運行編譯後的展示. 
這裏寫圖片描述


總結: 
Q_OBJECT宏有着連接信號與宏的功能,一旦類中沒有這個宏定義的話,信號與槽的關聯也就消失了,有興趣的小夥伴們可以做個測試,你把這個宏給註釋掉,你就會發現程序一樣可以正常編譯通過,且成功運行,但是我點擊按鈕後,圖片是不會顯示的,原因就是缺少這個宏!


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章