日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

qt中实现息屏开平mousepress_QT信号槽分析

發布時間:2024/1/23 c/c++ 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 qt中实现息屏开平mousepress_QT信号槽分析 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

環境安裝

默認安裝好了VS2015 和QT

下載QT pdb和QT src壓縮包(選擇自己的版本,我是5.9.8)

qt下載網址

拷貝自己需要的文件,qt目錄中D:\Qt\Qt5.9.8\5.9.8我是這個

并且把源碼也拷貝進同一目錄,當然其他的目錄也行

設置VS選項

工具->選項->調試->符號

項目->xxxx屬性->vc++目錄(添加源碼路徑)

測試

對著qt的函數或者宏按F12

安裝查看源碼的軟件(Source Insight)

這個工具可以很好的分析源碼

分析QT信號槽

分析moc生成的文件

案例代碼

#include class QtClass : public QObject{ Q_OBJECTpublic: QtClass(QObject *parent); ~QtClass(); void Test(){ emit Sig1(5); }signals: void Sig1(int nVal); //void Sig2(bool b); //void Sig3(bool b); //void Sig4(bool b, int nVal); private slots: void Slot1(int nVal0){ qDebug() << nVal0; }}

信號函數只有聲明,沒有實現?

emit Sig1(5);這句代碼調用信號,但是我們沒有實現信號這個函數呀。我們沒有實現,那么是什么能夠幫我們實現呢?當然是編譯器。

調試信號函數

F11發現是有實現代碼的吧

打開文件所在目錄

查看moc文件夾,分析編譯器都給我們生成了什么

定義了一個結構體

qt_meta_stringdata_QtClass_t

struct qt_meta_stringdata_QtClass_t { QByteArrayData data[6]; char stringdata0[31];};

后面創建了一個結構體靜態變量里面存放一些類、參數、函數名等信息。這個第一個參數應該是ID,字符串的開始位置,字符串size

QT_MOC_LITERAL(0, 0, 7), // "QtClass"

static const qt_meta_stringdata_QtClass_t qt_meta_stringdata_QtClass = { {QT_MOC_LITERAL(0, 0, 7), // "QtClass" //類名QT_MOC_LITERAL(1, 8, 4), // "Sig1" //信號名QT_MOC_LITERAL(2, 13, 0), // "" QT_MOC_LITERAL(3, 14, 4), // "nVal" //參數名QT_MOC_LITERAL(4, 19, 5), // "Slot1" //槽函數名QT_MOC_LITERAL(5, 25, 5) // "nVal0" //槽參數名 }, "QtClass\0Sig1\0\0nVal\0Slot1\0nVal0"};

qt_meta_data_QtClass : 存儲類中函數相關的信息

static const uint qt_meta_data_QtClass[] = { // content: 7, // revision //qt對應版本 0, // classname 0, 0, // classinfo 2, 14, // methods //2個函數 context長度14 0, 0, // properties 0, 0, // enums/sets 0, 0, // constructors 0, // flags 1, // signalCount //信號數量 // signals: name, argc, parameters, tag, flags 1, 1, 24, 2, 0x06 /* Public */,//name:對應qt_meta_stringdata_QtClass_t結構體的ID,是"Sig1"//argc:是參數個數//parameters:該函數的具體聲明在在qt_meta_data_QtClass結構體的偏移 // slots: name, argc, parameters, tag, flags 4, 1, 27, 2, 0x08 /* Private */,//上面的parameters就是指向這里// 返回值 參數1... 這個結構的大小24 // signals: parameters QMetaType::Void, QMetaType::Int, 3,27 // slots: parameters QMetaType::Void, QMetaType::Int, 5, 0 // eod};

qt_static_metacall類的信號/槽函數調用的實現地址判斷傳進來的ID然后調用函數

void QtClass::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, { if (_c == QMetaObject::InvokeMetaMethod) { QtClass *_t = static_cast(_o); Q_UNUSED(_t) switch (_id) { case 0: _t->Sig1((*reinterpret_cast< int(*)>(_a[1]))); break; case 1: _t->Slot1((*reinterpret_cast< int(*)>(_a[1]))); break; default: ; } } else if (_c == QMetaObject::IndexOfMethod) { int *result = reinterpret_cast<int *>(_a[0]); { typedef void (QtClass::*_t)(int ); if (*reinterpret_cast<_t *>(_a[1]) == static_cast<_t>(&QtClass:: *result = 0; return; } } }}

staticMetaObject : 類信息的總和

紅色框是父類地址,藍色是存儲字符串的結構體的地址,黑色是存放信號槽函數信息的結構體,類的信號/槽函數調用的實現地址

metaObject:判斷靜態/動態調用

qt_metacast:返回類名稱

+qt_metacall:函數調用

void** _a:數組指針, 每個指針指向一個函數的地址

_c:實現函數的類型

_id : 函數id, 判斷是否實現 & 以何種方式實現該函數

信號函數的實現

void* _a[]是一個信號對應的槽函數的地址

一個信號可以對應多個槽,所有這里是void* _a[]數組

Q_OBJECT

從這里看是不是很明顯的能看出,這里寫了虛函數,然后生成moc文件幫我們實現

* qmake ignore Q_OBJECT */#define Q_OBJECT \ public: \ QT_WARNING_PUSH \ Q_OBJECT_NO_OVERRIDE_WARNING \ static const QMetaObject staticMetaObject; \ virtual const QMetaObject *metaObject() const; \ virtual void *qt_metacast(const char *); \ virtual int qt_metacall(QMetaObject::Call, int, void **); \ QT_TR_FUNCTIONS \ private: \ Q_OBJECT_NO_ATTRIBUTES_WARNING \ Q_DECL_HIDDEN_STATIC_METACALL static void qt_static_metacall(QObject *, Q QT_WARNING_POP \ struct QPrivateSignal {}; \ QT_ANNOTATE_CLASS(qt_qobject, "")

分析connect函數

檢查函數

判斷參數是否為NULL

給Sender賦值獲取名字、對象、參數等

獲取sender的Index,并且判斷是否有效

接收方信息

判斷信號槽是否被關聯

判斷接收方是否有效可以被關聯

檢查發送者和接收者參數是否一致

執行關聯操作函數

進入實現函數

先是強轉了sender 和receiver保存在兩變量里面

檢測版本

估計是為了防止多線程,給了鎖

生成信號槽的對應關系Connection,并把Connection插入ConnectionList中

為對應的connect賦值

解鎖,并且檢查是否關聯成功

分析activate函數

當我們發Sig1信號時調用的函數

紅框計算父類的信號

前面做了一系列檢查,是否還關聯著

構造一個ConnectListRef的結構體,類似ConnectList引用

這里用上面的Index找到關聯鏈表

遍歷表找到對應得connect

調用鏈表得槽函數

大體圖

end

總結

以上是生活随笔為你收集整理的qt中实现息屏开平mousepress_QT信号槽分析的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。