一.元對象
QT使用元對象編譯器(Meta Object Compiler,moc),實現了元對象(Meta Object System,mos)機制,為標准C++增加了一些特性:
信號槽機制,用於解決對象之間的通訊
可查詢可設計的對象屬性
強大的事件機制以及事件過濾器
基於上下文的字符串翻譯機制(國際化),用 tr() 函數實現
復雜的定時器實現,用於在事件驅動的GUI中嵌入能夠精確控制的任務集成
層次化的可查詢的對象樹,提供一種自然的方式管理對象關系
智能指針(QPoint),在對象析構之后自動設為0,防止野指針
能夠跨越庫邊界的動態轉換機制
元對象系統是基於以下3個條件: (1)基類QObject:任何需要使用元對象系統功能的類必須繼承自QObject類 (2)Q_OBJECT宏:必須在類的私有聲明區聲明Q_OBJECT宏(默認為private) (3)元對象編譯器(Meta-Object Compiler,moc):為QObject子類實現元對象特性提供必要的代碼
二.信號槽
QT編程中信號與槽用於處理界面各個組件的交互,類似與MFC的消息循環和綁定
注意:在使用信號與槽的類中,必須在類的定義中加入宏定義Q_OBJECT
信號(Signal)就是在特定情況下被發射的時間,類似於鼠標單擊時發生clicked()信號
槽(Slot)是對信號響應的函數
QT中的信號(Signals)和槽(Slot)的機制進行通信,需要繼承QObject基類,繼承這個基類就會生成一個moc文件,沒有這個文件就不能使用信號和槽
1.轉到槽
在需要設計槽的控件(觸發控件)上右鍵->轉到槽 或者直接按下F4進入快速選擇信號和槽函數 選擇相應的信號之后就會跳轉到該信號函數 lineEdit 文本編輯框 textChanged(QString) testEdited(QString) pushButton 按鈕 clicked() clicked(bool) pressed()
QTCreator會把該控件的信號自動生成對應的槽函數,QT會自動識別相關的槽函數,但是注意這里槽函數的名字是一一對應的,並不能自定義改動
//helloDialog.h class HelloDialog : public QMainWindow { // 聲明槽函數 private slots: void on_pushButton_clicked(); }
//helloDialog.cpp void HelloDialog::on_pushButton_clicked() { ui->lineEdit->setText("k5"); }
2.Connect信號槽
connect(
ui文件下的控件名稱
控件自帶的信號函數
自定義的對象
自定義的槽函數
)
//helloDialog.h class HelloDialog{ public: void initSignalSlots(); //初始化信號與槽連接 <br>// 聲明槽函數 private slots: void changeData(); }
//helloDialog.cpp void HelloDialog::initSignalSlots() { connect(ui->pushButton,SIGNAL(cliked()),this,SLOT(changeData)); } void HelloDialog::changeData(){ ui->lineEdit->setText("k5"); }
QT4使用宏 SIGNAL()和SLOT()來聲明信號與槽 connect(ui->pushButton, SIGNAL(clicked()), this, SLOT(close())); QT5使用指針地址來表示,可以進行編譯時的類型檢查(要考慮函數指針重載) conenct(ui->pushButton, &QPushButton::clicked, this, &MainWindow::close);
3.自定義信號與槽
除了使用QT內置的信號函數和槽函數,也可以自定義信號和槽函數.
創建兩個類繼承QObject類,添加Q_Object宏,用signals和slots標記信號和槽函數
信號需要聲明不需要實現,槽需要聲明也需要實現。信號槽都不需要返回值,可以有參數,可以重載
注意:使用 signals 標記信號函數,信號是一個函數聲明,返回void,不需要實現函數代碼
使用 emit 可以發送信號
// test.h #ifndef TEST_H #define TEST_H #include <QObject> #include <QDebug> class test : public QObject { Q_OBJECT public: test(); void send(){ emit testcall(); } signals: void testcall(); public slots: void testreveive(); } #endif // TEST_H
// test.cpp<br><br>#include "test.h" test::test() { } void test::testreceive(){ qDebug() << "receive"; }
// mainwindow.cpp #include "ui_mainwindow.h" #include "test.h" MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent), ui(new Ui::MainWindow) { test t; connect(&t, &test::testcall, &t, &test::testreceive); t.send(); }