QT的核心——信號與槽

目錄

回顧C 語言信號

1、信號與槽

2、關聯信號與槽

2.1自動關聯信號與槽

2.2手動關聯信號與槽

2.3斷開信號與槽

3、自定義信號

3.1自定義信號使用條件

3.2自定義槽函數使用條件

4、信號與槽參數傳遞

4.1自定義一個帶參的信號

4.2關聯帶參的信號與槽

4.3發送一個帶參的信號

5、信號與槽的相互關聯

6、lambda表達式

?lambda 表達式的應用

?7、lambda 與 信號和槽


回顧C 語言信號

signal(設置信號處理方式)功能:注冊一個信號處理函數,當收到該信號后,就會觸發handler 函數表頭文件 #include<signal.h>定義函數 void *signal(int signum,void(* handler)(int));signum : 需要捕捉的信號。handler : 收到信號后執行的函數

1.捕捉的信號能自定義嗎? 不可以,只能使用系統預定義好的信號

2.信號可以傳輸數據嗎? 不可以,信號只負責通知

所以QT 在 C 語言的信號基礎進行封裝,把上述兩個問題都解決了。 在QT 中用戶可以自定義信號, 在QT 中用戶可以通過信號與槽傳遞參數。

信號:各種事件

槽: 響應信號的動作

1、信號與槽

當某個事件發生后,如某個按鈕被點擊了一下,它就會發出一個被點擊的信號(signal)。

某個對象接收到這個信號之后,就會做一些相關的處理動作(稱為槽slot)。

但是Qt對象不會無故收到某個信號,要想讓一個對象收到另一個對象發出的信號,這時候需要建立連接(connect)

//QT的四個信號

  1. pressed():鼠標按下時觸發。對應的函數是 mousePressEvent()。
  2. clicked():鼠標松開時觸發。如果鼠標拖拽到按鈕區域之外釋放則不會觸發。對應的函數是 mouseReleaseEvent()。一般情況下 connect 槽函數時使用該信號。
  3. released():鼠標松開時觸發。即使鼠標拖拽到按鈕區域之外釋放也會觸發。對應的函數是 mouseReleaseEvent()。
  4. toggled():設置 setCheckable(true) 后再單擊按鈕才會觸發該信號。一般用于多個按鈕組成 QButtonGroup 并且 setExclusive(true) 設置按鈕間互斥。 正常情況下單擊按鈕,響應順序為:pressed() — about 215ms — released() — almost 0ms — clicked()。

2、關聯信號與槽

關聯的方法有兩種:自動關聯,手動關聯。下面對此進行一次次介紹

2.1自動關聯信號與槽

在項目 增加信號和槽的方法一:在UI設計師中增加

第一步:右擊控件,在彈出的對話框,

在下拉列表中,選擇"轉到槽",會彈出選擇對話框

第二步:選擇自己信號

會自動生成槽函數(.h和.cpp)

第三步:當點擊相應的控件時,對應的槽函數就會被調用,從面是實現動態交互的效果

槽函數

2.2手動關聯信號與槽

QMetaObject::Connection QObject::connect(const QObject *sender,const char *signal,const QObject *receiver,const char *method,Qt::ConnectionType type = Qt::AutoConnection
);
其中,sender 表示信號發送者,signal 表示信號名,receiver 表示信號接收者,method 表示槽函數名,type 表示連接類型

type參數的值

描述

解釋

Qt::DirectConnection

直接連接

即在信號發出時直接調用槽函數,槽函數會立即執行,而不管當前的線程是否與信號發出者在同一個線程

Qt::QueuedConnection

排隊連接

將信號事件放入接收對象的事件隊列中,槽函數會在事件循環處理時被執行,適用于跨線程的連接

Qt::BlockingQueuedConnection

阻塞排隊連接

槽函數會在接收對象的線程中執行,并且當前線程會阻塞,直到槽函數執行完成

Qt::AutoConnection

自動連接

如果信號發送者和接收者在同一個線程,使用直接連接,否則使用排隊連接

Qt::UniqueConnection

唯一連接

已經存在相同的連接,則不會創建新的連接,可以避免重復連接導致的問題,如重復執行槽函數等

?在QT4和QT5中,手動關聯有著意義重大的調整,QT4不會檢查信號與槽的參數是否匹配,而QT5會自動檢查信號與槽的參數是否匹配。

下面給出QT4和QT5的關聯例子:

QT4:

 //手動關聯信號與槽        this 表示的是當前窗體,MainWindow
connect(ui->pushButton,SIGNAL(clicked()),this,SLOT(on_pushButton_clicked()));

QT5:

connect(ui->pushButton,&QPushButton::clicked,this,&MainWindow::show_msg);

2.3斷開信號與槽

語法:

語法: QT4: disconnect(信號發送者地址,SIGNAL(信號名(參數列表)),信號接收者地址,SLOT(槽名稱(參數列表)));

QT5: disconnect(信號發送者地址,&發送者類名::信號名,信號接收者地址,&接受者類名::槽名稱);

void MainWindow::on_pushButton_2_clicked()
{//取消信號與槽的關聯 QT4// disconnect(ui->pushButton,SIGNAL(clicked()),this,SLOT(on_pushButton_clicked()));//取消信號與槽的關聯 QT5disconnect(ui->pushButton,&QPushButton::clicked,this,&MainWindow::on_pushButton_clicked);//因為自動關聯,QT軟件采用的是QT4的語法關聯,所以取消只能用QT4 。//關聯時使用了那種方法,取消時要一致!!qDebug() << "取消關聯";
}

注意:使用自動關聯的時候,QT軟件采用的是QT4的語法關聯,所以取消關聯只能用QT4;使用手動關聯的時候,關聯時使用了那種方法,取消時要一致

3、自定義信號

在QT中,信號是可以自定義的,語法如下:

//在xxx.h頭文件中 聲明信號 
signals:  void 信號名(參數列表); 

注意:信號只需要聲明不需要定義!!!

?但是可以看到定義信號的時候可以參數,參數的類型在信號定義的時候必須已經確定,而且不能改變,信號默認只能傳遞基本的類型如下(列舉部分):

int:整數類型

double:雙精度浮點數類型

QString:字符串類型

QDate:日期類型

QTime:時間類型

QColor:顏色類型

在C++中,參數支持默認參數,那么在QT的信號定義時,當然也可以為參數設置默認值

定義完自定義信號之后,需要代碼來控制發送信號,發送語法如下:

//使用  emit 信號名(參數列表); 發送信號  
emit  mysig(); //發送一個mysig信號 

在發出信號時,如果沒有指定參數,則使用默認值。

自定義信號與槽的關聯和上面的關聯是類似的:

 //信號在那個類中定義的,該類就是發送者connect(this,SIGNAL(mysig()),this,SLOT(getsig()));//發送信號emit  mysig();//溫馨提示:信號的發送必須在"關聯后"發送,否則該信號失效 

3.1自定義信號使用條件

  1. 聲明在類的signals域下
  2. 沒有返回值,void類型的函數
  3. 只有函數聲明,沒有定義
  4. 可以有參數,可以重載
  5. 通過emit關鍵字來觸發信號,形式:emit object->sig(參數);

3.2自定義槽函數使用條件

  1. qt4 必須聲明在 private/public/protected slots域下面,qt5之后可以聲明public下,同時還可以是靜態的成員函數,全局函數,lambda表達式
  2. 沒有返回值,void類型的函數
  3. 不僅有聲明,還得要有實現
  4. 可以有參數,可以重載

4、信號與槽參數傳遞

4.1自定義一個帶參的信號

#ifndef MAINWINDOW_H
#define MAINWINDOW_Hclass MainWindow : public QMainWindow
{Q_OBJECT
public:MainWindow(QWidget *parent = nullptr);~MainWindow();//自定義一個帶參的信號
signals:void mysig(int a);//注意:信號與槽的參數類型必須匹配!! 
//聲明一個帶參的槽函數
public  slots: void getsig(int a);  private:Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H

4.2關聯帶參的信號與槽

#include "mainwindow.h"
#include "ui_mainwindow.h"MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);//關聯帶參的信號與槽,信號與槽的參數都需要在關聯是列舉出來 connect(this,SIGNAL(mysig(int)),this,SLOT(getsig(int)));
}MainWindow::~MainWindow()
{delete ui;
}

4.3發送一個帶參的信號

emit  mysig(10010); 

?注意事項:

  1. 信號參數的類型必須要與槽函數的類型匹配 參數類型不匹配會發生報錯: MainWindow::mysig(QString) --> MainWindow::myslot(int)
  2. 信號參數的個數必須大于槽函數參數的個數(理解:能少接受發來的信號,不能多接受發來的信號) 槽參數的個數大于信號參數個數 : MainWindow::mysig(int) --> MainWindow::myslot(int,int,int)

5、信號與槽的相互關聯

6、lambda表達式

  1. capture 子句(在 C++ 規范中也稱為 Lambda 引導。)
  2. 參數列表(可選)。 (也稱為 Lambda 聲明符)
  3. mutable 規范(可選)。
  4. 異常規范(可選)。
  5. 后面的-返回值-類型(可選)。
  6. Lambda 體。
語法:
auto func = [capture] (params) opt -> ret { func_body; };func是可以當作lambda表達式的名字,作為一個函數使用
capture是捕獲列表
params是參數表
opt是函數選項(mutable之類)
ret是返回值類型
func_body是函數體。  capture是捕獲列表:
[]不捕獲任何變量
[&]引用捕獲,捕獲外部作用域所有變量,在函數體內當作引用使用,可以修改值
[=]值捕獲,捕獲外部作用域所有變量,在函數內內有個副本使用  ,不可以修改值
[=, &a]值捕獲外部作用域所有變量,按引用捕獲a變量
[a]只值捕獲a變量,不捕獲其它變量
[this]捕獲當前類中的this指針opt選擇:
int a = 0;
auto f1 = [=](){ return a; }; // 值捕獲a
cout << f1() << endl;
auto f2 = [=]() { return a++; }; // 修改按值捕獲的外部變量,error
auto f3 = [=]() mutable { return a++; }; //添加mutable 選項可以修改

?lambda 表達式的應用

#include <iostream>
#include <list>
using  namespace std;int main() {list<int> vec;vec.push_back(10);vec.push_back(45);vec.push_back(4);vec.push_back(48);vec.sort(); for(int i:vec){cout << i << endl;}//自定義排序的規則 vec.sort([](int a,int b){return a>b;});for(int i:vec){cout << i << endl;}
}

基礎寫法

?數據捕獲問題

?7、lambda 與 信號和槽

QT 中的一些簡單功能的槽函數可以直接設計為 lambda 表達式,這樣就不用在頭文件聲明槽,在源文件定義槽。

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{ui->setupUi(this);//手動關聯信號與槽 , 去頭文件聲明 myslot  ,再定義 myslot  很麻煩//connect(ui->pushButton,&QPushButton::clicked,this,&MainWindow::myslot);//把槽函數修改為 lambda表達式connect(ui->pushButton,&QPushButton::clicked,this,[](){qDebug() << "按鈕點擊";});}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/42715.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/42715.shtml
英文地址,請注明出處:http://en.pswp.cn/news/42715.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

YOLOv5、YOLOv8改進:S2注意力機制

目錄 1.簡介 2.YOLOv5改進 2.1增加以下S2-MLPv2.yaml文件 2.2common.py配置 2.3yolo.py配置 1.簡介 S2-MLPv2注意力機制 最近&#xff0c;出現了基于 MLP 的視覺主干。與 CNN 和視覺Transformer相比&#xff0c;基于 MLP 的視覺架構具有較少的歸納偏差&#xff0c;在圖像識…

LVS-DR+keepalived實現高可用負載群集

VRRP 通信原理&#xff1a; VRRP就是虛擬路由冗余協議&#xff0c;它的出現就是為了解決靜態路由的單點故障。 VRRP是通過一種競選的一種協議機制&#xff0c;來將路由交給某臺VRRP路由。 VRRP用IP多播的方式&#xff08;多播地址224.0.0.18&#xff09;來實現高可用的通信&…

基于STM32+OneNet設計的物聯網智慧路燈

一、前言 近年來&#xff0c;構筑智慧城市、推動城鎮發展被國家列入重要工作范疇。發布的《超級智慧城市報告》顯示&#xff0c;全球已啟動或在建的智慧城市有1000多個&#xff0c;中國在建500個&#xff0c;遠超排名第二的歐洲&#xff08;90個&#xff09;。從在建智慧城市的…

(五)Unity開發Vision Pro——FAQ

常見問題 (FAQ) 1.問&#xff1a;我看到在visionOS 模擬器中運行的結果與在硬件上運行的結果不同 請注意&#xff0c;在模擬器中運行時&#xff0c;某些特定于硬件的功能不可用 - 最明顯的是 AR 數據。這可能意味著 VisionOS 模擬器中的模擬結果可能與 Vision Pro 耳機上的模…

Android oaid

官方GitHub地址 https://github.com/gzu-liyujiang/Android_CN_OAID 生成和用途介紹 https://www.jianshu.com/p/1c7ef27d6db4 圖片來源于上述網站 其他關于id的介紹 https://www.cnblogs.com/chenKnowledgeConllection/p/17380960.html https://zhuanlan.zhihu.com/p/55…

微信小程序拉起支付報: 調用支付JSAPI缺少參數: total_fee

1. 調用支付JSAPI缺少參數: total_fee 2. 檢查返回給前端調起支付的參數是否正確 一開始是params.put("package", prepay_id); 回來改回params.put("package", "prepay_id"prepay_id);

leetcode 415.字符串相加

?? 題目描述 &#x1f31f; leetcode鏈接&#xff1a;https://leetcode.cn/problems/add-strings/description/ ps&#xff1a; 從兩個字符串的末尾開始遍歷&#xff0c;依次相加&#xff0c;若大于等于 10 則使用一個變量記錄進位&#xff0c;遍歷的時候若兩個字符串其中一…

算法通關村——不簡單的字符串轉換問題

1. 轉換成小寫字母 給你一個字符串 s &#xff0c;將該字符串中的大寫字母轉換成相同的小寫字母&#xff0c;返回新的字符串。 轉換成小寫字母 1.1 利用ASCII 首先需要直到常見的ASCII值 a-z: 97-122 A-Z: 65-90 0-9: 48-57 只需要將這個字符串先轉換成字符&#xff0c;然后…

ASR(自動語音識別)任務中的LLM(大語言模型)

一、LLM大語言模型的特點 二、大語言模型在ASR任務中的應用 淺度融合 淺層融合指的是LLM本身并沒有和音頻信息進行直接計算。其僅對ASR模型輸出的文本結果進行重打分或者質量評估。 深度融合 LLM與ASR模型進行深度結合&#xff0c;統一語音和文本的編碼空間或者直接利用ASR…

OKCC在系統安全方面做了哪些措施?

語音通信行業&#xff0c;運營者普遍比較關心的問題是&#xff0c;運營風險如何控制&#xff1f;運營安全如何保證&#xff1f;OKCC呼叫中心又有那些風控措施來保證運營安全。 當前階段&#xff0c;語音通信運營&#xff0c;最主要的風險主要包括以下幾個方面&#xff1a; 一、…

無涯教程-Perl - wait函數

描述 該函數等待子進程終止,返回已故進程的進程ID。進程的退出狀態包含在$?中。 語法 以下是此函數的簡單語法- wait返回值 如果沒有子進程,則此函數返回-1,否則將顯示已故進程的進程ID Perl 中的 wait函數 - 無涯教程網無涯教程網提供描述該函數等待子進程終止,返回已故…

Three.js 實現模型材質局部輝光效果和解決輝光影響場景背景圖顯示的問題

1.Three.js 實現模型材質局部輝光效果 2.解決輝光效果影響場景背景圖顯示的問題 相關API的使用&#xff1a; 1. EffectComposer&#xff08;渲染后處理的通用框架&#xff0c;用于將多個渲染通道&#xff08;pass&#xff09;組合在一起創建特定的視覺效果&#xff09; 2. …

MME: A Comprehensive Evaluation Benchmark for Multimodal Large Language Models

本文也是LLM系列相關文章&#xff0c;針對《MME: A Comprehensive Evaluation Benchmark for Multimodal Large Language Models》的翻譯。 MME:一個多模態大型語言模型的綜合評估基準 摘要1 引言2 MME評估套件3 實驗4 分析5 結論 摘要 多模態大語言模型&#xff08;MLLM&…

Java-運算符和控制語句(上)(基于c語言的補充)

算術運算符 關于求余 不管分子&#xff0c;分母是正還是負&#xff0c;對于分母&#xff0c;直接取正&#xff1b;對于分子若有負號&#xff0c;則先提取出來&#xff1b;剩下兩個正的分子分母運算&#xff1b;最后&#xff0c;若剛才的分子有負號&#xff0c;對最后的結果添加…

Java版 招投標系統簡介 招投標系統源碼 java招投標系統 招投標系統功能設計tbms

? 項目說明 隨著公司的快速發展&#xff0c;企業人員和經營規模不斷壯大&#xff0c;公司對內部招采管理的提升提出了更高的要求。在企業里建立一個公平、公開、公正的采購環境&#xff0c;最大限度控制采購成本至關重要。符合國家電子招投標法律法規及相關規范&#xff0c;以…

scala中json4s 使用詳解

預備知識 json4s的數據結構AST (Abstract Syntax Tree)。 sealed abstract class JValue case object JNothing extends JValue // zero for JValue case object JNull extends JValue case class JString(s: String) extends JValue case class JDouble(num: Double) extend…

arcgis--坐標系

1、arcgis中&#xff0c;投影坐標系的y坐標一定是7位數&#xff0c;X坐標有兩種&#xff1a;6位和8位。 6位&#xff1a;省略帶號&#xff0c;這是中央經線形式的投影坐標&#xff0c;一般投影坐標中會帶CM字樣&#xff1b;8位&#xff1a;包括帶號&#xff0c;一般投影坐標中…

數字化時代,數據倉庫和商業智能BI系統演進的五個階段

數字化在逐漸成熟的同時&#xff0c;社會上也對數字化的性質有了進一步認識。當下&#xff0c;數字化除了前邊提到的將復雜的信息、知識轉化為可以度量的數字、數據&#xff0c;在將其轉化為二進制代碼&#xff0c;引入計算機內部&#xff0c;建立數據模型&#xff0c;統一進行…

一鍵搭訕以及打招呼設置(swift)

項目描述&#xff1a;用戶通過打招呼設置錄制打招呼語音&#xff0c;添加打招呼文字&#xff0c;首頁feed頁面展示sayhi的小動畫&#xff0c;點開可查看將要搭訕的列表&#xff0c;選擇想要搭訕的用戶以及搭訕的文字和語音&#xff0c;也可隨機選擇文案、語音&#xff0c;未通過…

CAS 一些隱藏的知識,您了解嗎

目錄 ConcurrentHashMap 一定是線程安全的嗎 CAS 機制的注意事項 使用java 并行流 &#xff0c;您要留意了 ConcurrentHashMap 在JDK1.8中ConcurrentHashMap 內部使用的是數組加鏈表加紅黑樹的結構&#xff0c;通過CASvolatile或synchronized的方式來保證線程安全的,這些原理…