国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

【Qt】信號和槽機(jī)制

這篇具有很好參考價(jià)值的文章主要介紹了【Qt】信號和槽機(jī)制。希望對大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

目錄

一、認(rèn)識信號和槽

二、connect函數(shù)

三、自定義槽函數(shù)

四、自定義信號

五、帶參數(shù)的信號和槽

六、信號和槽斷開連接

七、信號和槽存在的意義

八、Lambda表達(dá)式定義槽函數(shù)


一、認(rèn)識信號和槽

概述

在Qt中,用戶和控件的每次交互過程稱為一個(gè)事件。如"用戶點(diǎn)擊按鈕"是一個(gè)事件,"用戶關(guān)閉窗口"也是一個(gè)事件。每個(gè)事件都會發(fā)出一個(gè)信號,如用戶點(diǎn)擊按鈕會發(fā)出"按鈕被點(diǎn)擊"的信號,用戶關(guān)閉窗口會發(fā)出"窗口被關(guān)閉"的信號

Qt中的所有控件都具有接收信號的能力,?個(gè)控件還可以接收多個(gè)不同的信號。對于接收到的每個(gè)信號,控件都會做出相應(yīng)的響應(yīng)動(dòng)作。如:按鈕所在的窗口接收到"按鈕被點(diǎn)擊"的信號后,會做出"關(guān)閉自己"的響應(yīng)動(dòng)作;再如:輸入框自己接收到"輸入框被點(diǎn)擊"的信號后,會做出"顯示閃爍的光標(biāo),等待用戶輸入數(shù)據(jù)"的響應(yīng)動(dòng)作。在Qt中,對信號做出的響應(yīng)動(dòng)作就稱之為槽

信號和槽是Qt特有的消息傳輸機(jī)制,它能將相互獨(dú)立的控件關(guān)聯(lián)起來。如:"按鈕"和"窗口"本身是兩個(gè)獨(dú)立的控件,點(diǎn)擊"按鈕"并不會對"窗口"造成任何影響。通過信號和槽機(jī)制,可以將"按鈕"和"窗口"關(guān)聯(lián)起來,實(shí)現(xiàn)"點(diǎn)擊按鈕會使窗口關(guān)閉"的效果

信號的本質(zhì)

信號是由于用戶對窗口或控件進(jìn)行了某些操作,導(dǎo)致窗口或控件產(chǎn)生了某個(gè)特定事件,這時(shí)Qt對應(yīng)的窗口類會發(fā)出某個(gè)信號,以此對用戶的操作做出反應(yīng)。因此,信號的本質(zhì)就是事件

槽的本質(zhì)

槽(Slot)就是對信號響應(yīng)的函數(shù)。槽就是?個(gè)函數(shù),與一般的C++函數(shù)是一樣的,可以定義在類的任何位置(public、protected或private),可以具有任何參數(shù),可以被重載,也可以被直接調(diào)用(但是不能有默認(rèn)參數(shù))。槽函數(shù)與一般的函數(shù)不同的是:槽函數(shù)可以與信號關(guān)聯(lián),當(dāng)信號被發(fā)射時(shí),關(guān)聯(lián)的槽函數(shù)被自動(dòng)執(zhí)行

說明

  • 信號和槽機(jī)制底層是通過函數(shù)間的相互調(diào)用實(shí)現(xiàn)的。每個(gè)信號都可以用函數(shù)來表示,即信號函數(shù);每個(gè)槽也可以用函數(shù)表示,即槽函數(shù)
  • 信號函數(shù)和槽函數(shù)通常位于某個(gè)類中,和普通的成員函數(shù)相比,它們的特別之處在于:

信號函數(shù)用signals關(guān)鍵字修飾,槽函數(shù)用public slots、protected slots或者private slots修飾(使用普通成員函數(shù)的方式修飾也可)。signals和slots是Qt在C++的基礎(chǔ)上擴(kuò)展的關(guān)鍵字,專門用來指明信號函數(shù)和槽函數(shù);信號函數(shù)只需要聲明,不需要定義(實(shí)現(xiàn)),而槽函數(shù)需要定義(實(shí)現(xiàn))

Q_OBJECT

若一個(gè)類要使用信號和槽機(jī)制,必須在類中添加Q_OBJECT這個(gè)宏

【Qt】信號和槽機(jī)制,Qt,qt

二、connect函數(shù)

在Qt中,QObject類提供了一個(gè)靜態(tài)成員函數(shù)connect(),該函數(shù)專門用來關(guān)聯(lián)指定的信號函數(shù)和槽
函數(shù)。QObject是Qt內(nèi)置的父類,Qt中提供的很多類都是直接或者間接繼承自QObject

Qt Assistant中connect函數(shù)原型:

//舊版
connect (const QObject *sender,
    const char * signal ,
    const QObject * receiver ,
    const char * method ,
    Qt::ConnectionType type = Qt::AutoConnection )
  • sender:信號的發(fā)送者
  • signal:發(fā)送的信號(信號函數(shù))
  • receiver:信號的接收者
  • method:接收信號的槽函數(shù)
  • type:用于指定關(guān)聯(lián)方式,默認(rèn)的關(guān)聯(lián)方式為Qt::AutoConnection,通常不需要手動(dòng)設(shè)定

但是C++不允許使用兩個(gè)不同的指針類型相互賦值,使用const char*明顯是不行的。因?yàn)镼t Assistant中的函數(shù)聲明,是以前舊版本的Qt的connect函數(shù)的聲明

在以前的版本中,給信號參數(shù)傳參需要要搭配一個(gè)SIGNAL宏,給槽參數(shù)傳參需要搭配一個(gè)SLOT宏。從Qt5開始,對上述寫法進(jìn)行了簡化,給connect重載版本,第二個(gè)參數(shù)和第四個(gè)參數(shù)成了泛型函數(shù),允許傳入任意參數(shù)了

【Qt】信號和槽機(jī)制,Qt,qt

此時(shí)connect函數(shù)就帶有了一定的參數(shù)檢查的功能,若傳入的第一個(gè)參數(shù)和第二個(gè)參數(shù),或者第三個(gè)參數(shù)和第四個(gè)參數(shù)不匹配,代碼出現(xiàn)編譯錯(cuò)誤。不匹配是指:2、4參數(shù)傳入的函數(shù)指針,不是1、3參數(shù)的成員函數(shù)的指針

connect函數(shù)使用案例:點(diǎn)擊按鈕關(guān)閉窗口

#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent), ui(new Ui::Widget)
{
    ui->setupUi(this);
    QPushButton* btn = new QPushButton("按鈕", this);
    btn->move(200, 200);
    connect(btn, &QPushButton::clicked, this, &QWidget::close);
}

Widget::~Widget()
{
    delete ui;
}

三、自定義槽函數(shù)

  • 早期的Qt版本要求槽函數(shù)必須寫到"public slots"下,但是現(xiàn)在高級版本的Qt允許寫到類的"public"作用域中或者全局下
  • 返回值為void,需要聲明,也需要實(shí)現(xiàn)
  • 可以有參數(shù),可以發(fā)生重載

代碼編寫槽函數(shù)

widget.h:?

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QPushButton>

QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();
    void HandleClicked();//槽函數(shù)聲明

private:
    Ui::Widget *ui;
};
#endif // WIDGET_H

widget.cpp

#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    QPushButton* btn = new QPushButton("按鈕", this);
    btn->move(200, 200);
    connect(btn, &QPushButton::clicked, this, &Widget::HandleClicked);
}

Widget::~Widget()
{
    delete ui;
}

//槽函數(shù)定義
void Widget::HandleClicked()
{
    setWindowTitle("按鈕已按下");
}

ui創(chuàng)建槽函數(shù)

【Qt】信號和槽機(jī)制,Qt,qt

【Qt】信號和槽機(jī)制,Qt,qt

自動(dòng)生成的槽函數(shù)的名字是on_pushButton_clicked,其中on是固定的,pushButton是ui中的objectName,clicked寫明了是哪種信號。ui自動(dòng)生成的槽函數(shù)不需要connect函數(shù)就能在觸發(fā)信號時(shí)被回調(diào)。(ui_widget.h中調(diào)用了QMetaObject::connectSlotsByName,它會觸發(fā)自動(dòng)連接信號槽的規(guī)則)

四、自定義信號

自定義信號很少用到。因?yàn)樵贕UI中,用戶的操作行為是可以窮舉的,Qt內(nèi)置的信號已經(jīng)覆蓋到了大部分可能的用戶操作

  • 信號是一種特殊的函數(shù),程序員只需寫出函數(shù)聲明,并告訴Qt,這是一個(gè)信號即可。這個(gè)函數(shù)的定義,是Qt在編譯過程中,自動(dòng)生成的(無法干預(yù))
  • 信號函數(shù)的返回值必須是void,有沒有參數(shù)都可以,也支持函數(shù)重載
  • 信號可以使用emit關(guān)鍵字進(jìn)行發(fā)射(Qt5 emit不寫也行)

【Qt】信號和槽機(jī)制,Qt,qt

五、帶參數(shù)的信號和槽

信號和槽也可以帶參數(shù)。發(fā)射信號時(shí),就可以給信號函數(shù)傳遞實(shí)參,這個(gè)參數(shù)就會被傳遞到對應(yīng)的槽函數(shù)中。信號和槽函數(shù)的參數(shù)類型必須一致,個(gè)數(shù)可以不一致,但是信號的參數(shù)個(gè)數(shù)必須大于槽函數(shù)的參數(shù)個(gè)數(shù)(當(dāng)個(gè)數(shù)不一致時(shí),就會按順序拿到信號的前N個(gè)參數(shù))

【Qt】信號和槽機(jī)制,Qt,qt

一個(gè)信號可以通過connect關(guān)聯(lián)多個(gè)槽函數(shù),一個(gè)槽函數(shù)也能被多個(gè)信號關(guān)聯(lián)

六、信號和槽斷開連接

使用disconnect斷開信號槽的連接(主動(dòng)斷開往往是把信號重新綁定到另一個(gè)槽函數(shù)上)

widget.cpp:

#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    btn = new QPushButton("按鈕", this);
    btn->move(200, 200);
    connect(btn, &QPushButton::clicked, this, &Widget::HandleClicked_1);

    QPushButton* changeBtn = new QPushButton("修改按鈕功能", this);
    changeBtn->move(200, 400);
    connect(changeBtn, &QPushButton::clicked, this, &Widget::ChangeButtonRole);
}

Widget::~Widget()
{
    delete ui;
}

void Widget::HandleClicked_1() { setWindowTitle("修改窗口標(biāo)題1"); }

void Widget::HandleClicked_2() { setWindowTitle("修改窗口標(biāo)題2"); }

void Widget::ChangeButtonRole()
{
    disconnect(btn, &QPushButton::clicked, this, &Widget::HandleClicked_1);
    connect(btn, &QPushButton::clicked, this, &Widget::HandleClicked_2);
    qDebug() << "修改成功";
}

widget.h:

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QPushButton>
#include <QDebug>

QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();

    void HandleClicked_1();
    void HandleClicked_2();
    void ChangeButtonRole();

private:
    Ui::Widget *ui;
    QPushButton* btn;
};
#endif // WIDGET_H

若這里沒有disconnect,會使一個(gè)信號綁定兩個(gè)槽函數(shù),觸發(fā)點(diǎn)擊按鈕,同時(shí)執(zhí)行兩個(gè)槽函數(shù)

七、信號和槽存在的意義

  • 解耦合:信號發(fā)送者不需要知道發(fā)出的信號被哪個(gè)對象的槽函數(shù)接收,槽函數(shù)也不需要知道哪些信號關(guān)聯(lián)了自己,Qt的信號槽機(jī)制保證了信號與槽函數(shù)的調(diào)用。支持信號槽機(jī)制的類或者父類必須繼承于QObject類
  • 實(shí)現(xiàn)"多對多"的效果:一個(gè)信號可以connect到多個(gè)槽函數(shù)上,一個(gè)槽函數(shù)也可以被多個(gè)信號connect(實(shí)際開發(fā)中,這種情況極少)

缺點(diǎn)

與回調(diào)函數(shù)相比,信號和槽稍微慢?些,因?yàn)樗鼈兲峁┝烁叩撵`活性,盡管在實(shí)際應(yīng)用程序中差別不大。通過信號調(diào)用的槽函數(shù)比直接調(diào)用的速度慢約10倍(這是定位信號的接收對象所需的開銷;遍歷所有關(guān)聯(lián);編組/解組傳遞的參數(shù);多線程時(shí),信號可能需要排隊(duì)),這種調(diào)用速度對性能要求不是非常高的場景是可以忽略的,是可以滿足絕大部分場景
?

八、Lambda表達(dá)式定義槽函數(shù)

  • 注意被捕獲變量的生命周期
  • 盡量傳值捕獲,傳引用捕獲可能會捕獲到已經(jīng)被釋放的變量,造成程序崩潰
#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent), ui(new Ui::Widget)
{
    ui->setupUi(this);
    setFixedSize(1000, 1000);

    QPushButton* button = new QPushButton("點(diǎn)擊移動(dòng)", this);
    button->move(400, 800);
    connect(button, &QPushButton::clicked, this, [=](){
        qDebug() << "Lambda";
        button->move(800, 800);
    });
}

Widget::~Widget()
{
    delete ui;
}

上述代碼傳值捕獲沒問題,傳引用捕獲會崩潰。原因是button是局部變量(它指向的空間位于堆區(qū),但其本身是一個(gè)局部變量的指針),構(gòu)造函數(shù)結(jié)束后button變量即被銷毀,造成程序崩潰文章來源地址http://www.zghlxwxcb.cn/news/detail-836438.html

到了這里,關(guān)于【Qt】信號和槽機(jī)制的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 【Qt】信號和槽

    【Qt】信號和槽

    ?需要云服務(wù)器等云產(chǎn)品來學(xué)習(xí)Linux的同學(xué)可以移步/--騰訊云--/--阿里云--/--華為云--/官網(wǎng),輕量型云服務(wù)器低至112元/年,新用戶首次下單享超低折扣。 ? 目錄 一、Qt中的信號和槽 1、信號 2、槽 3、Q_OBJECT 二、Qt中的connect函數(shù) 三、自定義信號、自定義槽 1、自定義槽函數(shù) 1.1使

    2024年01月21日
    瀏覽(32)
  • 【QT】信號和槽(15)

    【QT】信號和槽(15)

    前面的內(nèi)容說了很多不同的控件如何使用,今天來看下QT的核心, 信號與槽(Signals and slots) ! 簡單理解一下,就是我們的信號與槽連接上了之后,發(fā)射一個(gè)信號給到槽,槽函數(shù)接收到了這個(gè)信號之后,槽函數(shù)會被調(diào)用。 1.python 3.7.8?? 可直接進(jìn)入官網(wǎng)下載安裝:Download Pyt

    2024年02月10日
    瀏覽(21)
  • QT之信號和槽

    QT之信號和槽

    一、什么是信號和槽? 我們經(jīng)??吹降墓δ埽c(diǎn)擊一個(gè)按鈕實(shí)現(xiàn)窗口關(guān)閉。 這一過程發(fā)生了什么?是怎么實(shí)現(xiàn)的 按鈕相當(dāng)于一個(gè)信號,點(diǎn)擊相當(dāng)于發(fā)送一個(gè)信號,窗口是個(gè)接收者,關(guān)閉窗口是個(gè)槽函數(shù) 信號:各種事件 槽:響應(yīng)信號的動(dòng)作 當(dāng)一個(gè)按鈕(信號)被觸發(fā)(發(fā)送

    2024年02月07日
    瀏覽(24)
  • 07.QT信號和槽-2

    07.QT信號和槽-2

    ????????在Qt中,允許?定義信號的發(fā)送?以及接收?,即可以?定義信號函數(shù)和槽函數(shù)。但是對于?定義的信號函數(shù)和槽函數(shù)有?定的書寫規(guī)范。 1.1 自定義信號 (1)?定義信號函數(shù)必須寫到\\\"signals\\\"下; (2)返回值為void,只需要聲明,不需要實(shí)現(xiàn); (3)可以有參數(shù),

    2024年04月14日
    瀏覽(21)
  • Qt6.2教程——3.Qt信號和槽

    信號和槽是Qt中一個(gè)強(qiáng)大的特性,用于處理對象之間的通信。它們是一種事件處理機(jī)制,允許一個(gè)對象在某個(gè)事件發(fā)生時(shí)通知另一個(gè)對象。 定義 : 信號是一個(gè)QObject的成員函數(shù),當(dāng)某個(gè)特定事件發(fā)生時(shí),它被自動(dòng)調(diào)用。它可以與一個(gè)或多個(gè)槽關(guān)聯(lián)。 聲明 : 在Qt類的聲明中,信號

    2024年02月10日
    瀏覽(19)
  • [Qt的學(xué)習(xí)日常]--信號和槽

    [Qt的學(xué)習(xí)日常]--信號和槽

    前言 作者 :小蝸牛向前沖 名言 :我可以接受失敗,但我不能接受放棄 ??如果覺的博主的文章還不錯(cuò)的話,還請 點(diǎn)贊,收藏,關(guān)注??支持博主。如果發(fā)現(xiàn)有問題的地方歡迎?大家在評論區(qū)指正 本期學(xué)習(xí):什么是信號和槽,自定義槽函數(shù)和信號函數(shù),信號和槽的傳參,斷開,

    2024年04月28日
    瀏覽(20)
  • 20221210 QT----信號和槽的使用

    20221210 QT----信號和槽的使用

    什么是信號(signal) 以QPushButton為例: (1)按下按鈕時(shí),會觸發(fā)一個(gè)mousePressEvent事件,此時(shí)會發(fā)出一個(gè)pressed信號; (2)松開按鈕時(shí),會觸發(fā)一個(gè)mouseReleaseEvent事件,此時(shí)會發(fā)出released和clicked信號。 事件的種類有很多,不同的事件都對應(yīng)著不同的信號,當(dāng)事件發(fā)生時(shí),對應(yīng)

    2024年02月15日
    瀏覽(25)
  • 02 qt基本控件及信號和槽

    02 qt基本控件及信號和槽

    功能:顯示一個(gè)字符串內(nèi)容 主要接口函數(shù) 構(gòu)造函數(shù): 賦值運(yùn)算符重載: 功能函數(shù): 1)基本數(shù)據(jù)類型(int,float,double,char*)轉(zhuǎn)換成字符串 number(long , int ) : QString number(int , int ) : QString number(uint , int ) : QString number(ulong , int ) : QString number(qlonglong , int ) : QString number(qulonglong , int

    2024年02月12日
    瀏覽(21)
  • qt信號和槽避免多次連接

    qt同一個(gè)信號和槽多次連接,則槽函數(shù) 會觸發(fā)多次 (默認(rèn)),可能不是我們想要的結(jié)果。 有3種方法可以解決這個(gè)問題: 因?yàn)槌跏蓟瘮?shù)在在整個(gè)程序中只運(yùn)行一次,所以這里面連接信號和槽,就能避免重復(fù)連接問題了。 Qt::UniqueConnection 的作用是:如果該信號以前沒連接過

    2024年02月10日
    瀏覽(47)
  • Qt快速學(xué)習(xí)(一)--對象,信號和槽

    Qt快速學(xué)習(xí)(一)--對象,信號和槽

    目錄 1.Qt概述 1.1 什么是Qt 2.2?手動(dòng)創(chuàng)建 2.3?pro文件 2.4?一個(gè)最簡單的Qt應(yīng)用程序 ? ? ? ?3 第一個(gè)Qt小程序 3.1 按鈕的創(chuàng)建 3.2 對象模型(對象樹) ??????3.3?Qt窗口坐標(biāo)體系 4 信號和槽機(jī)制 ????????4.1 系統(tǒng)自帶的信號和槽 4.2 自定義信號和槽 ????4.3信號槽的拓展 ????

    2024年02月12日
    瀏覽(16)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包