1. 程式人生 > >深入理解QT的SIGNAL\SLOT機制(五):訊號的發射過程

深入理解QT的SIGNAL\SLOT機制(五):訊號的發射過程

我們來看訊號的發起過程,先來看一個巨集定義:# define emit,這個巨集定義將emit定義為空,也就是說你在emit mysignal()的時候,這行程式碼其實就是mysignal(),所以訊號就是函式,只是換了個概念而已!
廢話不多說,來DEBUG:
這裡寫圖片描述
我們在11行打斷點F11進入:

// SIGNAL 0
void MyWidget::mysignal()
{
    QMetaObject::activate(this, &staticMetaObject, 0, nullptr);
}

居然直接呼叫了moc檔案中的mysignal函式,現在是不是更清楚訊號就是函數了啊?這裡的this是MyWidget物件,staticMetaObject就是第二章提到的靜態QMEtaObject,其餘都是空。進入active函式之前回去先計算偏移量:
這裡寫圖片描述


822~824行:將QMetaObject的所有父類偏移量加起來,目的是找到子類的第一個訊號的偏移量(5.9.1中除了類名資訊之外,只儲存了訊號和槽的資訊)。現在進入active函式:
這裡寫圖片描述
3636行:子類第一個訊號的偏移量+當前偏移量,就是我們需要的mysignal訊號的偏移量。
3637~3660行:進行安全檢查,檢查是否繫結訊號和槽。
接著來看:
這裡寫圖片描述
3694行:根據訊號的signal_index下標查詢到connectionList,這個connectionList儲存的是所有繫結到該訊號的槽函式資訊;
這裡寫圖片描述
3700~3705行:拿到列表的first和last,進行遍歷。
3707~3709行:receiver是空,就意味著沒有槽函式,continue;
3712~3721行:針對不同型別進行不同的處理;
我們的是在統一個執行緒中,呼叫3743行的switchSender函式,不同執行緒的是放到佇列中去;
這裡寫圖片描述

來看switchSender函式:

 inline void switchSender(QObject *receiver, QObject *sender, int signal_absolute_id)
    {
        this->receiver = receiver;
        currentSender.sender = sender;
        currentSender.signal = signal_absolute_id;
        currentSender.ref = 1;
        previousSender = QObjectPrivate::setCurrentSender(receiver, &currentSender);
        switched = true
; }

發現該函式基本是進行值拷貝,繼續來看active函式:
3757~3766行:如果c->callFunction不為空,並且c->methodOffset在QMetaObject的methodOffset之內(保證呼叫的函式偏移量不超過QMetaObject的偏移量),就可以呼叫callFunction.
我們看到const auto callFunction = c->callFunction;
callFunction(receiver, QMetaObject::InvokeMetaMethod, method_relative, argv ? argv : empty_argv);
實際上就是在呼叫callFunction,也就是moc_test.cpp中的qt_static_metacall函式。
呼叫完之後繼續執行do{}while(),知道所有的槽被呼叫。

接下來按F11,進入callFunction
這裡寫圖片描述
可以看到確實呼叫了moc_test.cpp中的static_metacall函式,
71行:格局傳入的id呼叫對應的槽函式,所以myslot被呼叫。
OK,完結撒花!
如有問題歡迎指正

電子科技大學
胡力衛
[email protected]

相關推薦

深入理解QT的SIGNAL\SLOT機制訊號發射過程

我們來看訊號的發起過程,先來看一個巨集定義:# define emit,這個巨集定義將emit定義為空,也就是說你在emit mysignal()的時候,這行程式碼其實就是mysignal(),所以訊號就是函式,只是換了個概念而已! 廢話不多說,來DEBUG:

深入理解多執行緒—— Java虛擬機器的鎖優化技術

本文是《深入理解多執行緒》的第五篇文章,前面幾篇文章中我們從synchronized的實現原理開始,一直介紹到了Monitor的實現原理。 前情提要 通過前面幾篇文章,我們已經知道: 1、同步方法通過ACC_SYNCHRONIZED關鍵字隱式的對方法進行加鎖。當執行緒要

深入理解Java記憶體模型——鎖

鎖的釋放-獲取建立的happens before 關係 鎖是java併發程式設計中最重要的同步機制。鎖除了讓臨界區互斥執行外,還可以讓釋放鎖的執行緒向獲取同一個鎖的執行緒傳送訊息。下面是鎖釋放-獲取的示例程式碼: class MonitorExample { int a = 0;

深入理解android訊息機制——handler Looper原始碼

android 重要核心知識點,怎麼深刻理解都不為過,本篇部落格從常用api ,Looper Hanldery以及HanlderTread原始碼角度解讀 一 常用api,主執行緒接收處理訊息 private Handler handler = ne

深入理解JAVA虛擬機器虛擬機器類載入機制

虛擬機器把描述類的資料從Class檔案載入到記憶體,並對資料進行校驗、轉換解析和初始化,最終形成可以被虛擬機器直接使用的Java型別,這就是虛擬機器的類載入機制。在Java語言裡面,型別的載入、連線和初始化過程都是在程式執行期間完成的。 1、類載入的時機 類從被載入到虛擬機

再次深入理解類載入機制

一、類的載入方法1、ClassLoader的的基本概念:       與c與c++編寫的程式不同,Java程式並不是可執行檔案,而是有許多的類檔案組成,每個檔案對應一個Java類。而且這些類並不是全部裝進記憶體,而是根據程式執行的需要逐步裝載。ClassLoader是JVM的

深入理解Java的註解Annotation註解處理器3

isp 通過反射 out peid 擴展 .cn 自定義註解 忽略 否則 如果沒有用來讀取註解的方法和工作,那麽註解也就不會比註釋更有用處了。使用註解的過程中,很重要的一部分就是創建於使用註解處理器。Java SE5擴展了反射機制的API,以幫助程序員快速的構造自定義註解處

深入理解MyBatis的原理配置文件上

dynamic 如何 turn ready conf 屬性。 支持 left bool 前言:前文提到一個入門的demo,從這裏開始,會了解深入 MyBatis 的配置,本文講解 MyBatis 的配置文件的用法。 目錄 1、properties 元素 2、設置(set

深入理解MyBatis的原理配置文件用法

pac amt 單個 gis obb rri tab obj 用戶 前言:前文講解了 MyBatis 的配置文件一部分用法,本文將繼續講解 MyBatis 的配置文件的用法。 目錄 1、typeHandler 類型處理器 2、ObjectFactory 3、插件 4、e

深入理解線性迴歸演算法正則項的詳細分析

前言 當模型的複雜度達到一定程度時,則模型處於過擬合狀態,類似這種意思相信大家看到個很多次了,本文首先討論了怎麼去理解複雜度這一概念,然後回顧貝葉斯思想(原諒我有點囉嗦),並從貝葉斯的角度去理解正則項的含義以及正則項降低模型複雜度的方法,最後總結全文。     &nb

深入理解線性迴歸演算法淺談貝葉斯線性迴歸

前言 上文介紹了正則化項與貝葉斯的關係,正則化項對應於貝葉斯的先驗分佈,因此通過設定引數的先驗分佈來調節正則化項。本文首先介紹了貝葉斯線性迴歸的相關性質,和正則化引數λ的作用,然後簡單介紹了貝葉斯思想的模型比較,最後總結全文。   目錄 1、後驗引數分佈和預測變數分

深入理解maven與應用靈活的構建

 一個優秀的構建系統必須足夠靈活,應該能夠讓專案在不同的環境下都能成功構建。maven為了支援構建的靈活性,內建了三大特性,即:屬性、profile和資源過濾。 1、maven屬性  maven屬性分6類:     1、內建屬性:如${basedir}表示專案根目錄,$

深入理解java虛擬機器java記憶體區域記憶體結構劃分

圖一:java記憶體結構劃分 由上圖可知,java記憶體主要分為6部分,分別是程式計數器,虛擬機器棧,本地方法棧,堆,方法區和直接記憶體,下面將逐一詳細描述。 1、程式計數器 執行緒私有,即每個執行緒都會有一個,執行緒之間互不影響,獨立儲存。 代表著當前執行緒所執行

深入理解Eureka自我保護機制

為什麼要有自我保護機制 眾所周知,Eureka在CAP理論當中是屬於AP , 也就說當產生網路分割槽時,Eureka保證系統的可用性,但不保證系統裡面資料的一致性, 舉個例子。當發生網路分割槽的時候,Eureka-Server和client端的通訊被終止,server端收不

第13講 | 深入區塊鏈技術PoS共識機制

運行 離線 難題 感謝 並且 發現 即使 pos系統 分享   上一篇我們講到了PoW共識機制,這一篇我們就來分享另外一種共識機制,PoS共識機制。   PoS全稱是Proof of Stake,中文翻譯為權益證明。這一篇我們會將PoS與PoW對比講解,幫助你加深理解。

深入Mysql鎖機制樂觀鎖CAS

深入Mysql鎖機制(五)樂觀鎖CAS 執行緒安全 眾所周知,Java是多執行緒的。但是,Java對多執行緒的支援其實是一把雙刃劍。一旦涉及到多個執行緒操作共享資源的情況時,處理不好就可能產生執行緒安全問題。執行緒安全性可能是非常複雜的,在沒有充足的同步的情況下,多個執行緒中的操

深入理解JVM類檔案結構

今天我們來介紹一下Class類檔案結構 1.概述 計算機雖然只能識別0和1,但是越來越多的程式語言選擇了與作業系統和機器指令集無關的、平臺中立的格式作為程式編譯後的儲存格式。Java虛擬機器不和包括Java在內的任何語言繫結,只與“class檔案”這種特定的二進

深入理解java虛擬機器十三 Java 即時編譯器JIT機制以及編譯優化

在部分的商用虛擬機器中,Java 程式最初是通過直譯器( Interpreter )進行解釋執行的,當虛擬機發現某個方法或程式碼塊的執行特別頻繁的時候,就會把這些程式碼認定為“熱點程式碼”。為了提高熱點程式碼的執行效率,在執行時,即時編譯器(Just In Time Com

深入理解ClassLoader工作機制jdk1.8

關於 擁有 作用 再次 lin public 雙親委托模型 rap 訪問 ClassLoader 顧名思義就是類加載器,ClassLoader 作用: 負責將 Class 加載到 JVM 中 審查每個類由誰加載(父優先的等級加載機制) 將 Class 字節

深入理解OkHttp源碼——提交請求

mat esp 屬於 idt set ref setname 失敗 class 本篇文章主要介紹OkHttp執行同步和異步請求的大體流程。主要流程如下圖: 主要分析到getResponseWidthInterceptorChain方法,該方法為具體的根據請求獲取響應