一.元對象
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();
}