大家好,我是IT文藝男,來自一線大廠的一線程序員
大家在使用Qt開發程序時,都知道怎么使用Qt的信號槽,但是Qt信號槽是怎么工作的? 大部分人仍然不知道;也就是說大家只知道怎么使用,卻不知道基於什么原理,顯然這是不符合深層次發展的;那么今天我就給大家基於Qt源碼以及示例代碼深度剖析Qt的信號槽機制,一定會對大家有幫助。
基本概念
信號
當對象改變其狀態時,信號就由該對象發射 (emit) 出去,而且對象只負責發送信號,它不知道另一端是誰在接收這個信號。
槽
用於接收信號,而且槽只是普通的對象成員函數。一個槽並不知道是否有任何信號與自己相連接。
信號與槽的連接
QMetaObject::Connection QObject::connect(const QObject *sender, const char *signal,
const QObject *receiver, const char *method,
Qt::ConnectionType type = Qt::AutoConnection)
通過QObject::connect靜態函數建立連接;其中sender與receiver是指向對象的指針,signal與method分別通過SIGNAL()與SLOT()宏來進行轉換。
元對象編譯器
MOC, the Meta Object Compiler。
Qt程序在交由標准編譯器(例如MSVC)編譯之前,先使用moc分析cpp頭文件;如果它發現在一個頭文件中包含了Q_OBJECT宏,則會生成另外一個cpp源文件(moc_文件名.cpp),該cpp源文件中包含了Q_OBJECT宏的實現、運行時信息(反射)等。因此Qt程序的完整編譯過程為moc->預處理->編譯->鏈接
示例代碼
Counter.h文件
#pragma once
#include <QtCore/QObject>
class Counter : public QObject
{
Q_OBJECT
public:
Counter();
public:
int value() const;
public slots:
void setValue(int value);
signals:
void valueChanged(int newValue);
private:
int m_value;
};
Counter.cpp文件
#include "Counter.h"
Counter::Counter():m_value(0)
{
}
int Counter::value() const
{
return m_value;
}
void Counter::setValue(int value)
{
if (value != m_value)
{
m_value = value;
emit valueChanged(value);
}
}
main.cpp文件
#include <QtCore/QCoreApplication>
#include "Counter.h"
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
Counter counterA;
Counter counterB;
QObject::connect(&counterA, SIGNAL(valueChanged(int)),
&counterB, SLOT(setValue(int)));
counterA.setValue(10);//counterA.value()=10, counterB.value()=10
counterB.setValue(20);//counterA.value()=10, counterB.value()=20
return a.exec();
}
Qt宏
宏定義在qobjectdefs.h文件中(位於QtCore目錄)
signals
slots
Q_OBJECT
emit
SIGNAL
SLOT
Qt信號槽源碼剖析系列會分拆為多個具體的細致講解,后續我會一一分析並發布
今天就講解到這里,更詳細的原理分析與講解,請關注微信公眾號(itwenyinan),觀看對應的的視頻版講解;謝謝