QT学习:概念解析
一、伙伴編輯模式
QLabel標(biāo)簽和伙伴(buddy)窗口部件包括一個(gè)標(biāo)簽 (QLabel) 和一個(gè)窗口部件,它們具有伙伴關(guān)系,指當(dāng)用戶激活標(biāo)簽的快捷鍵時(shí),鼠標(biāo)/鍵盤的焦點(diǎn)將會(huì)轉(zhuǎn)移到它的伙伴窗口部件上。只有QLabel標(biāo)簽對(duì)象才可以有伙伴窗口部件,也只有在該QLabel對(duì)象具有快捷鍵(在顯示文本的某個(gè)字符前面添加一個(gè)前綴“&”,就可以定義快捷鍵)時(shí),伙伴關(guān)系才有效。例如:
QLineEdit* ageLineEdit = new QLineEdit (this) ; QLabel* ageLabel = new QLabel ("&Age", this) ; ageLabel->setBuddy (ageLineEdit) ;代碼定義了ageLabel標(biāo)簽的組合鍵為Alt+A,并將行編輯框ageLineEdit設(shè)為它的伙伴窗口部件。當(dāng)用戶按下Alt+A組合鍵時(shí),焦點(diǎn)將會(huì)跳至行編輯框ageLineEdit中。
Qt設(shè)計(jì)器提供了伙伴編輯模式,可以通過鼠標(biāo)拖曳操作快捷地建立標(biāo)簽QLabel和其他窗口部件的伙伴關(guān)系。
二、信號(hào)與槽機(jī)制
Qt提供了信號(hào)和槽機(jī)制用于完成界面操作的響應(yīng),信號(hào)和槽機(jī)制是完成任意兩個(gè)Qt對(duì)象之間的通信機(jī)制。其中,信號(hào)會(huì)在某個(gè)特定情況或動(dòng)作下被觸發(fā),槽是等同于接收并處理信號(hào)的函數(shù)。例如,若要將一個(gè)窗口部件的變化情況通知給另一個(gè)窗口部件,則一個(gè)窗口部件發(fā)送信號(hào),另一個(gè)窗口部件的槽接收此信號(hào)并進(jìn)行相應(yīng)的操作,即可實(shí)現(xiàn)兩個(gè)窗口部件之間的通信。每個(gè)Qt對(duì)象都包含若干個(gè)預(yù)定義的信號(hào)和若干個(gè)預(yù)定義的槽。當(dāng)某一個(gè)特定事件發(fā)生時(shí),一個(gè)信號(hào)被發(fā)送,與信號(hào)相關(guān)聯(lián)的槽則會(huì)響應(yīng)信號(hào)并完成相應(yīng)的處理。當(dāng)一-個(gè)類被繼承時(shí),該類的信號(hào)和槽也同時(shí)被繼承,也可以根據(jù)需要自定義信號(hào)和槽。
1、信號(hào)與槽機(jī)制的連接方式
(1)一個(gè)信號(hào)可以與另一個(gè)信號(hào)相連,代碼如下:
connect (Object1, SIGNAL (signall),Object2, SIGNAL(signall)) ;表示ObjectI的信號(hào)1發(fā)送可以觸發(fā)Object2的信號(hào)I發(fā)送。
(2)同一個(gè)信號(hào)可以與多個(gè)槽相連,代碼如下:
(3)同一個(gè)槽可以響應(yīng)多個(gè)信號(hào),代碼如下:
connect (Object1,SIGNAL (signa12) , Object2, SIGNAL (slot2)); connect (Object3, SIGNAL (signa12),Object2, SIGNAL(slot2));但是,常用的連接方式為:
connect (Object1,SIGNAL (signal),Object2, SLOT(slot)) ;其中,signal 為對(duì)象Object1的信號(hào),slot 為對(duì)象Object2的槽。
SIGNAL()和SLOT()是Qt定義的兩個(gè)宏,它們返回其參數(shù)的C語言風(fēng)格的字符串(const char*)。因此,下 面關(guān)聯(lián)信號(hào)和槽的兩個(gè)語句是等同的:
2、信號(hào)與槽機(jī)制的優(yōu)點(diǎn)
(1)類型安全。
需要關(guān)聯(lián)的信號(hào)和槽的簽名必須是等同的,即信號(hào)的參數(shù)類型和參數(shù)個(gè)數(shù)與接收該信號(hào)的槽的參數(shù)類型和參數(shù)個(gè)數(shù)相同。不過,一個(gè)槽的參數(shù)個(gè)數(shù)是可以少于信號(hào)的參數(shù)個(gè)數(shù)的,但缺少的參數(shù)必須是信號(hào)參數(shù)的最后一個(gè)或幾個(gè)參數(shù)。 如果信號(hào)和槽的簽名不符,編譯器就會(huì)報(bào)錯(cuò)。
(2)松散耦合。
信號(hào)和槽機(jī)制減弱了Qt對(duì)象的耦合度。激發(fā)信號(hào)的Qt對(duì)象無須知道是哪個(gè)對(duì)象的哪個(gè)槽需要接收它發(fā)出的信號(hào),它只需做的是在適當(dāng)?shù)臅r(shí)間發(fā)送適當(dāng)?shù)男盘?hào)就可以了,而不需要知道也不關(guān)心它的信號(hào)有沒有被接收到,更不需要知道是哪個(gè)對(duì)象的哪個(gè)槽接收到了信號(hào)。同樣,對(duì)象的槽也不知道是哪些信號(hào)關(guān)聯(lián)了自己,而一旦關(guān)聯(lián)信號(hào)和槽,Qt 就保證了適合的槽得到了調(diào)用。即使關(guān)聯(lián)的對(duì)象在運(yùn)行時(shí)被刪除,應(yīng)用程序也不會(huì)崩潰。
一個(gè)類若要支持信號(hào)和槽,就必須從QObject或QObject的子類繼承。注意,Qt信號(hào)和槽機(jī)制不支持對(duì)模板的使用。
3.信號(hào)與槽機(jī)制的效率
信號(hào)和槽機(jī)制增強(qiáng)了對(duì)象間通信的靈活性,然而,這也損失了一些性能。同回調(diào)函數(shù)相比,信號(hào)和槽機(jī)制運(yùn)行速度有些慢。通常,通過傳遞一個(gè)信號(hào)來調(diào)用槽函數(shù)會(huì)比直接調(diào)用非虛函數(shù)的運(yùn)行速度慢10倍。主要原因如下。
(1)需要定位接收信號(hào)的對(duì)象。
(2)安全地遍歷所有的關(guān)聯(lián)(如一個(gè)信號(hào)關(guān)聯(lián)多個(gè)槽的情況)。
(3)編組(marshal)/(解組(unmarshal) 傳遞的參數(shù)
(4)在多線程時(shí),信號(hào)可能需要排隊(duì)等待。
然而,與創(chuàng)建堆對(duì)象的new操作及刪除堆對(duì)象的delete操作相比,信號(hào)和槽的運(yùn)行代價(jià)很小。信號(hào)和槽機(jī)制導(dǎo)致的這點(diǎn)性能損失對(duì)實(shí)時(shí)應(yīng)用程序是可以忽略的;同信號(hào)和槽提供的靈活性和簡便性相比,這點(diǎn)性能損失也是值得的。
三、Qt5元對(duì)象系統(tǒng)
Qt5元對(duì)象系統(tǒng)提供了對(duì)象間的通信機(jī)制(信號(hào)和槽)、運(yùn)行時(shí)類型信息和動(dòng)態(tài)屬性系統(tǒng)的支持,是標(biāo)準(zhǔn)C++的一個(gè)擴(kuò)展,它使Qt能夠更好地實(shí)現(xiàn)GUI圖形用戶界面編程。Qt5的元對(duì)象系統(tǒng)不支持C++模板,盡管該模板擴(kuò)展了標(biāo)準(zhǔn)C++的功能。但是,元對(duì)象系統(tǒng)提供了模板無法提供的一些特性。Qt5元對(duì)象系統(tǒng)基于以下三個(gè)事實(shí)。
(1)基類QObject:任何需要使用元對(duì)象系統(tǒng)功能的類必須繼承自QObject。
(2)Q_OBJECT宏:Q_OBJECT宏必須出現(xiàn)在類的私有聲明區(qū)中,用干啟動(dòng)元對(duì)象的特性
(3)元對(duì)象編譯器( Meta-Object Compiler, moc): 為QObject 子類實(shí)現(xiàn)元對(duì)象特性提供必要的代碼實(shí)現(xiàn)。
四、布局管理器
在設(shè)計(jì)較復(fù)雜的GUI用戶界面時(shí),僅通過指定窗口部件的父子關(guān)系以期達(dá)到加救和排列窗口部件的方法是行不通的,最好的辦法是使用Qt提供的布局管理器。
QGridLayout *mainLayout=new QGridLayout (this);// (a) mainLayout->addwidget (label1,0,0);// (b) mainLayout->addwidget (lineEdit,0,1); mainLayout->addwidget (labe12,1,0); mainLayout->addwidget (button,1,1); setLayout (mainLayout) ;// (C)其中,
(a) QGridLayout *mainLayout=new QGridLayout(this): 創(chuàng)建一個(gè)網(wǎng)格 布局管理器對(duì)象mainLayout,并用this)指出父窗口。
(b) mainLayout->addWidget(…):分別將控件對(duì)象label1、lineEdit、 label2 和button 放置在布局管理器中,還可以在創(chuàng)建布局管理器對(duì)象時(shí)不必指明父窗口。
? Qwidget::setLayout(…):將布局管理器添加到對(duì)應(yīng)的窗口部件對(duì)象中。因?yàn)檫@里的主窗口就是父窗口,所以直接調(diào)用setLayout(mainLayout)即可。
總結(jié)
- 上一篇: QT学习:QT下载与安装
- 下一篇: QT学习:字符串类QString