1. 程式人生 > >Qt中的訊號槽機制詳解

Qt中的訊號槽機制詳解

一、關於Qt

我們都知道Qt是一個用於做gui介面開發的框架,Qt擁有強大的元件開發機制,Qt同時也是一個跨平臺的C++介面開發框架,他和MFC不太一樣,MFC主要是專注於windows上的介面開發。Qt中比較有特點的東西也就是訊號槽機制,在講訊號槽機制之前,我們將說一下Qt中一些比較基礎的東西。

1、Qt中常用的快捷鍵
1)、幫助文件的轉換,F1可以檢視幫助文件,兩次F1可以將文件全憑顯示。
2)、.h和.cpp檔案的轉換,快捷鍵為F4
3)、編譯並且執行:Ctrl + R
4)、函式的宣告和定義之間的轉換:F2
5)、程式碼的註釋與取消:Ctrl + /
6)、字型的大小寫變換:Ctrl + 滑鼠滾輪向上向下
7)、移動程式碼:選中所要移動的程式碼 -> 按住 ctrl + shift -> 鍵盤方向鍵
8)、查詢替換關鍵字:ctrl + f
9)、快速開啟程式碼所在目錄:編輯模式下 -> 選中專案檔案 -> 右擊 -> 選擇“顯示包含的目錄”,即可顯示專案所在目錄(此方法同樣可以開啟程式碼檔案所在目錄)

2、如何檢視Qt的幫助文件
1)、類使用的相關介紹
2)、檢視所有部件類的相應的成員函式(功能、引數、返回值)
3)、檢視部件的訊號
4)、檢視部件的部件(所對應的虛擬函式如何編寫)

這裡寫圖片描述
這裡寫圖片描述
這裡寫圖片描述

公有成員函式:操作部件屬性的相關函式。
公有槽函式:Qt類中已經定義好的槽函式,直接可與訊號相連線。
訊號:軟中斷,如按下按鈕觸發 pressed() 訊號等。
保護成員函式:通常事件所對應的虛擬函式放在此處。
事件:常用事件,如操作滑鼠觸發的滑鼠事件。
文件使用簡單介紹到這來,它裡面沒有什麼有難度的東西。

3、Qt中的基本模組
1)、Qt widgets
2)、Qt WebKit
3)、Qt Test
4)、Qt Sql
5)、Qt quick
6)、Qt Qml
7)、Qt Multimedia Widgets
8)、Qt Core
9)、Qt gui
10)、Qt network
11)、Qt Multimedia
12)、Qt quick Control
13)、Qt quick dialog

4、Qt中的視窗繼承關係
這裡寫圖片描述

5、Qt中的記憶體回收機制
1)、 類直接或間接從QObject類派生
2)、給這個類指定父類

二、Qt中的訊號槽機制
Qt中的訊號槽由訊號和槽函式構成,所以接下來我們先聊聊訊號和槽函式
1、訊號
1)、是一個函式
a. 這個函式不需要實現, 只宣告就可以
b. 使用關鍵字 signals 限定
2)、 訊號函式返回值: void
3)、 可以過載
4)、訊號可以連線訊號
5)、訊號可以連線多個槽函式
connect(sender, sig, recv, slot1);
connect(sender, sig, recv, slot2);
connect(sender, sig, recv, slot3);
connect(sender, sig, recv, slot4);
6)、 多個訊號可以連結同一個槽函式

2、槽函式
* 槽函式
1)、qt5中的槽函式, 類的成員函式, 全域性函式, 靜態函式, lambda表示式(C++11的新特性, 匿名函式)
2)、 返回值void
3)、可以過載
4)、引數需要跟訊號的引數一一對應
void sig(int, double, QStirng)
void slot(int, double, QStirng)
5)、 槽函式的引數個數 小於 訊號的引數個數 — 可以
6)、槽函式的引數個數 大於 訊號的引數個數 — 不可以
7)、 自定義槽函式 – 一般的時候新增一個類的成員函式(C++)

3、Qt4的訊號槽

connect(sender, SINGAL(sig(int, QString), receiver, SLOT(slot(int, QString));

兩個巨集 SINGAL, SLOT 將函式名轉換為字串
qt4缺陷:
不安全, 巨集替換的時候不會做錯誤判斷

案例程式碼:
pro檔案中的程式碼

QT       += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = HelloQt
TEMPLATE = app
SOURCES += main.cpp\
        mywidget.cpp \
    mybutton.cpp \
    subwidget.cpp
HEADERS  += mywidget.h \
    mybutton.h \
    subwidget.h
CONFIG += c++11

main檔案中的程式碼:

#include "mywidget.h"
#include <QApplication>
int main(int argc, char *argv[])
{
    QApplication a(argc, argv)
    MyWidget w;
    w.show();
    return a.exec();
}

標頭檔案mywidget.h中的程式碼

#ifndef MYWIDGET_H
#define MYWIDGET_H
#include <QWidget>
#include <QPushButton>
#include "mybutton.h"
#include "subwidget.h"
class MyWidget : public QWidget
{
    Q_OBJECT

public:
    MyWidget(QWidget *parent = 0);
    ~MyWidget();
public slots:
    void mySlot();
    void showMainWindow(QString str);

signals:
    void aaa(); 

private:
    QPushButton* m_btn1;
    MyButton *m_btn2;
    SubWidget m_sub;   
};
#endif 

標頭檔案subwidget.h中的程式碼:

#ifndef SUBWIDGET_H
#define SUBWIDGET_H
#include <QWidget>
#include <QPushButton>
class SubWidget : public QWidget
{
    Q_OBJECT
public:
    explicit SubWidget(QWidget *parent = 0);
signals:
    void mainShow();
    void mainShow(QString);
public slots:
    void subSlot();
private:
    QPushButton* btn;
};
#endif 

原始檔mywidget.cpp中的程式碼

#include "mywidget.h"
#include <QDebug>

MyWidget::MyWidget(QWidget *parent)
    : QWidget(parent)
{
    this->setWindowTitle("0105");
    this->setWindowIcon(QIcon("D:\\face.png"));
    m_btn1 = new QPushButton(this);
    m_btn1->setText("hello, Qt");
    m_btn1->move(100, 100);
    m_btn2 = new MyButton(this);
    m_btn2->move(200, 200);
    m_btn2->show();
    void (SubWidget::*func1)() = &SubWidget::mainShow;
    connect(&m_sub, func1, this, &MyWidget::show);
    connect(m_btn2, &MyButton::clicked, this, [=]()
    {
        m_btn1->setText("aaaa");
    });
}
MyWidget::~MyWidget()
{

}

void MyWidget::mySlot()
{
    m_btn2->setText("aaa");
    m_sub.show();
    this->hide();
}

void MyWidget::showMainWindow(QString str)
{
    qDebug() << str.toUtf8().data();
}

原始檔subwidget.cpp中的程式碼:

#include "subwidget.h"

SubWidget::SubWidget(QWidget *parent) : QWidget(parent)
{
   btn = new QPushButton(this);
    btn->move(200, 200);
    void (SubWidget::*func1)() = &SubWidget::mainShow;
    connect(btn, &QPushButton::clicked, this, &SubWidget::subSlot);
    connect(btn, &QPushButton::clicked, this, func1);
}

void SubWidget::subSlot()
{
    emit mainShow("aaa!!!");
    this->hide();
}