QObject類

徐紅偉@百香果科技

QObject類是所有Qt對(duì)象的基類汁蝶。是Qt對(duì)象模型(Object Model)的基礎(chǔ)轻猖,該模型最核心的特點(diǎn)是對(duì)象間的無(wú)縫通信诸典,即信號(hào)和槽(signals and slots)媒至。

Signals和Slots機(jī)制

signals 和 slots是用于「對(duì)象間」通信的。

signal像(但不是)函數(shù)指針季二,更像C#中的事件檩咱,槽就是「函數(shù)」揭措。

signal-slot的功能比函數(shù)指針更多,比如可以多對(duì)一刻蚯,和一對(duì)多的連接绊含。代價(jià)是調(diào)用速度略慢。

用QObject的 static method:connect()和disconnect()進(jìn)行信號(hào)和槽的連接/解連接炊汹。(這解釋了為何使用信號(hào)-槽的Class中必須加入?Q_OBJECT宏)


自動(dòng)內(nèi)存管理

QObjects使用「對(duì)象樹(shù)」(object-tree)進(jìn)行內(nèi)存管理躬充,啥子意思呢?

QObject(QObject *parent= nullptr)

QPushButton(QWidget *parent = nullptr)

QChart::QChart(QGraphicsItem *parent = nullptr, Qt::WindowFlags wFlags = ...)

其實(shí)QObject在的構(gòu)造函數(shù)里有個(gè)parent參數(shù)兵扬。如果創(chuàng)建時(shí)指定了parent參數(shù)麻裳,對(duì)象就會(huì)自動(dòng)添加到parent的?children()?的列表中口蝠。此時(shí)parent對(duì)象就會(huì)接管子對(duì)象器钟。就是說(shuō)parent對(duì)象銷毀的時(shí)候,會(huì)自動(dòng)delete所有子對(duì)象妙蔗,不用怕「內(nèi)存泄露」傲霸。

其實(shí)Qt的內(nèi)存管理是「半自動(dòng)」的(參考[3]),delete的子對(duì)象是在棧上分配的眉反,那么delete就會(huì)出問(wèn)題昙啄。所以Qt推薦子對(duì)象用new()函數(shù)生成,而不是直接定義實(shí)體寸五。

[virtual] QObject::~QObject()" All child objects are deleted. If any of these objects are on the stack or global, sooner or later your program will crash."這是QObject析構(gòu)函數(shù)的描述梳凛。如果QObject的child objects在棧上或是全局變量,則程序遲早會(huì)崩潰梳杏。

這就像一棵大樹(shù)韧拒,只要把根砍了(銷毀了),會(huì)自動(dòng)銷毀它的枝葉十性。

QObjects通過(guò) ?event() 函數(shù)接收事件叛溢,并可以過(guò)濾事件,參考?installEventFilter() and?eventFilter()劲适。還可以通過(guò)?childEvent()來(lái)捕獲子對(duì)象的事件楷掉。

其他

當(dāng)QObject對(duì)象被銷毀時(shí),會(huì)發(fā)射 ?destroyed() 信號(hào)霞势,可以用之來(lái)監(jiān)測(cè)信號(hào)的生命周期 烹植。

最后,QObject提供一個(gè)定時(shí)器?QTimer愕贡,用于定時(shí)刊橘。

如果對(duì)象要實(shí)現(xiàn)signals-slots或properties,就必須使用?Q_OBJECT宏颂鸿。推薦在所有QObject的派生類中添加?Q_OBJECT宏促绵,無(wú)論是否用到signals-slots特性。

所有的QWidgets對(duì)象繼承于QObject,用isWidgetType()函數(shù)能快速查看對(duì)象是否為widget败晴。

線程親和性(Thread Affinity)

QObject 具有線程親和性浓冒,即它存在于特定的線程里。當(dāng)它接收到 queued signals 或 posted events 時(shí)尖坤,slots 或 event handlers 在 QObject 所在的線程里運(yùn)行稳懒。(QObject 對(duì)象的 slot成員函數(shù)在其被創(chuàng)建的線程里運(yùn)行,而不是發(fā)射信號(hào)的線程了)慢味。

注意:如果QObject 沒(méi)有親和的線程(即 thread() 函數(shù)返回 0)场梆,則它所在的線程沒(méi)有運(yùn)行事件循環(huán),因此它就無(wú)法接收到 queued signals或posted events.

默認(rèn)情況下纯路,QObject生存在創(chuàng)建它的線程下或油。可以用 thread() 函數(shù)查看它所在線程驰唬,也可以用 moveToThread()改變所在線程顶岸。

所有的 QObjects 都必須和其parent在同一個(gè)線程里,因此:

1.? 如果兩個(gè)QObject在不同的線程里叫编,則不能用setParent() 建立父子關(guān)系辖佣。

2. 當(dāng) QObject 移動(dòng)到另一個(gè)線程里后,其所有子對(duì)象(指定parent關(guān)系的)也自動(dòng)移動(dòng)到相同線程搓逾。

3.如果QObject有父對(duì)象卷谈,則對(duì)其進(jìn)行moveToThread()時(shí)會(huì)失敗。

4.如果QObject在 QThread::run()中創(chuàng)建霞篡,則它不能成為QThread的子對(duì)象世蔗,因?yàn)镼Thread不在QThread::run()線程里。

注意:QObject的成員變量不會(huì)自動(dòng)成為其子對(duì)象寇损。只有現(xiàn)實(shí)調(diào)用setParent()或再子對(duì)象的構(gòu)造函數(shù)里指定父對(duì)象parent凸郑,才能建立父子關(guān)系。因此把QObject移動(dòng)到一個(gè)線程時(shí)矛市,他的成員變量(非子對(duì)象)不會(huì)移動(dòng)芙沥。

無(wú)拷貝構(gòu)造函數(shù)(copy constructor)和=操作

在設(shè)計(jì)QObject時(shí),特意取消了「拷貝構(gòu)造函數(shù)」和 = 操作浊吏。

所在在傳遞QObjet及其子對(duì)象時(shí)而昨,要傳遞指針。在容器類中找田,也只能存儲(chǔ)其指針歌憨。

國(guó)際化

所有QObject的子類都支持Qt的翻譯特性,讓app的UI可以翻譯成不同語(yǔ)言墩衙。為了使UI上的字符可翻譯务嫡,必須用?tr() 函數(shù)包起來(lái)甲抖,詳細(xì)內(nèi)容見(jiàn)Writing Source Code for Translation


[1]參考Qt官方文檔:“QObejct

[2]徹底弄清 QObject —— 元對(duì)象模型的核心類.

[3].Qt淺談之一:內(nèi)存泄露(總結(jié))

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末心铃,一起剝皮案震驚了整個(gè)濱河市准谚,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌去扣,老刑警劉巖柱衔,帶你破解...
    沈念sama閱讀 217,509評(píng)論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異愉棱,居然都是意外死亡唆铐,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,806評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門奔滑,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)艾岂,“玉大人,你說(shuō)我怎么就攤上這事档押“难危” “怎么了祈纯?”我有些...
    開(kāi)封第一講書(shū)人閱讀 163,875評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵令宿,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我腕窥,道長(zhǎng)粒没,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,441評(píng)論 1 293
  • 正文 為了忘掉前任簇爆,我火速辦了婚禮癞松,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘入蛆。我一直安慰自己响蓉,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,488評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布哨毁。 她就那樣靜靜地躺著枫甲,像睡著了一般。 火紅的嫁衣襯著肌膚如雪扼褪。 梳的紋絲不亂的頭發(fā)上想幻,一...
    開(kāi)封第一講書(shū)人閱讀 51,365評(píng)論 1 302
  • 那天,我揣著相機(jī)與錄音话浇,去河邊找鬼脏毯。 笑死,一個(gè)胖子當(dāng)著我的面吹牛幔崖,可吹牛的內(nèi)容都是我干的食店。 我是一名探鬼主播渣淤,決...
    沈念sama閱讀 40,190評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼吉嫩!你這毒婦竟也來(lái)了砂代?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,062評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤率挣,失蹤者是張志新(化名)和其女友劉穎刻伊,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體椒功,經(jīng)...
    沈念sama閱讀 45,500評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡捶箱,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,706評(píng)論 3 335
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了动漾。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片丁屎。...
    茶點(diǎn)故事閱讀 39,834評(píng)論 1 347
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖旱眯,靈堂內(nèi)的尸體忽然破棺而出晨川,到底是詐尸還是另有隱情,我是刑警寧澤删豺,帶...
    沈念sama閱讀 35,559評(píng)論 5 345
  • 正文 年R本政府宣布共虑,位于F島的核電站,受9級(jí)特大地震影響呀页,放射性物質(zhì)發(fā)生泄漏妈拌。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,167評(píng)論 3 328
  • 文/蒙蒙 一蓬蝶、第九天 我趴在偏房一處隱蔽的房頂上張望尘分。 院中可真熱鬧,春花似錦丸氛、人聲如沸培愁。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,779評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)定续。三九已至,卻和暖如春雹洗,著一層夾襖步出監(jiān)牢的瞬間香罐,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,912評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工时肿, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留庇茫,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,958評(píng)論 2 370
  • 正文 我出身青樓螃成,卻偏偏與公主長(zhǎng)得像旦签,于是被迫代替她去往敵國(guó)和親查坪。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,779評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容