初探Qt中的消息處理


Qt消息模型
Qt封裝了具體操作系統的消息機制
Qt遵循經典的GUI消息驅動事件模型

 

 如果你只關注兩頭,即用戶做某個操作,那么應用程序中的消息處理函數將被調用。

Qt中如何表示用戶消息?用字符串來描述消息
Qt中如何映射用戶消息到消息處理函數?connect
Qt中消息映射需要遵循什么規則

信號與槽
Qt中定義了與系統消息相關的概念
——信號(Signal)
  由操作系統產生的消息
——槽(Slot)
  程序中的消息處理函數
——連接(Connect)
  將系統消息綁定到消息處理函數

Qt中的消息處理機制

 

 信號到槽的連接必須發生在兩個Qt類對象之間

Qt的核心——QObject::connect函數

bool connect(const QObject* sender,    //發送對象
             const QObject* signal,    //消息名
             const QObject* receiver,  //接收對象
             const char* method,       //接受對象的成員函數
             Qt::connectionType type = Qt::AutoConnection);

注意:
在Qt中,消息用字符串進行描述
connect函數在消息名和處理函數之間建立映射

Qt中的新關鍵字
——SIGNAL
  用於指定消息名
——SLOT
  用於指定消息處理函數名
——Q_OBJECT
  所有自定義槽的類必須在類聲明的開始處加上Q_OBJECT
——slots
  用於在類中聲明消息處理函數

初探信號與槽

#include <QApplication> #include <QPushButton>

int main(int argc, char *argv[]) { QApplication a(argc, argv); QPushButton btn; btn.setText("click me to quit..."); btn.show(); QObject::connect(&btn, SIGNAL(clicked()),&a, SLOT(quit()) ); return a.exec(); }

點擊按鈕對象,當前應用程序退出。

自定義槽
只有QObject的子類才能自定義槽
定義槽的類必須在聲明的最開始處使用Q_OBJECT
類中聲明槽時需要使用slots關鍵字
槽與所處理的信號在函數簽名上必須一致  //就是指信號如果帶有參數類型,那么槽就得帶有參數類型。總之兩者要保持一致。
SIGNAL和SLOT所指定的名稱中:
——可以包含參數類型
——不能包含具體的參數名

QCalculatorUI.h

#ifndef _QCALCULATORUI_H_ #define _QCALCULATORUIH_ #include <QWidget> #include <QPushButton> #include <QLineEdit>

class QCalculatorUI : public QWidget { Q_OBJECT private: QLineEdit* m_edit; QPushButton* m_buttons[20]; QCalculatorUI(); bool construct(); private slots: void onButtonClicked(); public: static QCalculatorUI* NewInstance(); void show(); ~QCalculatorUI(); }; #endif // _QCALCULATORUI_H_

QCalculatorUI.cpp

#include "QCalculatorUI.h" #include <QDebug> QCalculatorUI::QCalculatorUI(): QWidget(NULL,Qt::WindowCloseButtonHint) //此處QCalculatorUI就是作為頂層窗口存在的,雖然這個地方繼承自QWidget,但是賦值為NULL,相當於它是沒有父類的(但是實際上還是有的)。 //將窗口中的最大化和最小化去掉
{ //因為QLineEdit與QCalculatorUI以及QPushButton與QCalculatorUI是組合關系,那么就應該同生死,因此需要在構造函數對其定義。因為此處涉及到在堆上申請內存空間,因此需要 //使用二階構造
 } bool QCalculatorUI::construct() { bool ret = true; const char* btnText[20] = { "7", "8", "9", "+", "(", "4", "5", "6", "-", ")", "1", "2", "3", "*", "<-", "0", ".", "=", "/", "C", }; m_edit = new QLineEdit(this); if(m_edit != NULL) { m_edit->move(10,10); m_edit->resize(240,30); m_edit->setReadOnly(true);  //使QLineEdit只讀
 } else { ret = false; } for(int i=0; (i<4) && ret; i++) { for(int j=0; (j<5) && ret; j++) { if(m_buttons[i*5 + j] != NULL) { m_buttons[i*5 + j] = new QPushButton(this); m_buttons[i*5 + j]->move(10 + (10 + 40)*j, 50 + (10 + 40)*i); m_buttons[i*5 + j]->resize(40,40); m_buttons[i*5 + j]->setText(btnText[i*5 + j]); connect(m_buttons[i*5 + j],SIGNAL(clicked()), this, SLOT(onButtonClicked())); } else { ret = false; } } } return ret; } QCalculatorUI* QCalculatorUI::NewInstance() { QCalculatorUI* ret = new QCalculatorUI(); if((ret == NULL) || !(ret->construct())) { delete ret; ret = NULL; } return ret; } void QCalculatorUI::onButtonClicked() { QPushButton* btn = (QPushButton*)sender(); qDebug()<< "onButtonClicked"; qDebug() << btn->text(); } void QCalculatorUI::show() { QWidget::show(); this->setFixedSize(this->width(),this->height()); //固定窗口的大小
} QCalculatorUI::~QCalculatorUI() { }

main.cpp

#include <QApplication> #include "QCalculatorUI.h"

int main(int argc, char *argv[]) { QApplication a(argc, argv); QCalculatorUI* cal = QCalculatorUI::NewInstance(); int ret = 0; if(cal != NULL) { cal->show(); ret = a.exec(); delete cal; //當程序運行到最后時,將生成的cal對象釋放掉。
 } return ret; }

將20個按鈕映射到了同一個消息處理函數中,如何辨別哪個按鈕被點擊了呢?

在消息處理函數中:QPushButton* btn = (QPushButton*)sender();,通過sender()函數獲取點擊了哪個按鈕

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM