日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

QT对象树、信号和槽机制

發布時間:2023/12/10 c/c++ 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 QT对象树、信号和槽机制 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章目錄

  • 一 、對象樹是什么?
  • 二、信號和槽的基本概念
    • 2.1 信號
    • 2.2 槽
    • 2.3 松散耦合
    • 2.4 特點
  • 三、示例
  • 總結


一 、對象樹是什么?

對象樹是由父類和若干子類對象組成,而子類也可以由若干孫類。
QT中的對象樹是以QObject為起始父類來完成樹的構建的,如下圖所示。

當創建子類對象(QObject )的時候,會傳遞一個parent指針給子類的構造函數,該指針就是父對象指針。

//QWidget 為myWidget的父類 myWidget::myWidget(QWidget *parent): QWidget(parent) { }class myWidget : public QWidget {Q_OBJECT //parent 父對象指針傳遞給子類的構造函數。 public:myWidget(QWidget *parent = 0); };

所以在創建 QObject 對象時,會提供一個父對象的指針給構造函數,QObject 對象就會自動添加到其父對象的 children() 列表。然后當父對象進行析構的時候,這個子對象列表中的所有對象都會被析構,當析構子對象的時候,會自動從父對象的子對象列表中刪除。

這種對象樹機制的優點在于析構父類的析構時,子類對象會自動銷毀,這樣就不需要關注控件內存的銷毀情況。

但也會存在特殊情況會造成QT程序內存泄漏問題,這樣就需要我們手動刪除或者調用析構函數。
1:parent指針不會區分child對象是new出來的還是從棧上分配的,如果delete棧上的內存,就會發生錯誤。避免這一情況的方法就是全部使用new來開辟空間。

2:可以嘗試采用智能指針QPointer(模板類)的方法來自動銷毀內存空間。

3:Qt的對象清理器QObjectCleanupHandler也可以自動刪除所有監視對象。

二、信號和槽的基本概念

信號槽機制類似于C#中回調函數的概念,我們知道,回調函數的本質是函數作為參數在合適的時候(條件成立時)被某一特定的事件調用的方法,而信號槽機制是如果觸發事件,對象就會發出信號給接收者,然后調用綁定的槽函數,其中相似之處在于這兩種方式都會在滿足某一條件時觸發事件,信號類似于條件達成的方法,槽函數就像被委托調用的方法。

C#是通過委托來實現函數作為參數傳遞的,信號槽機制則是通過連接的方式實現的信號和槽的綁定。

2.1 信號

信號signal也是由不同的方法組成的,例如,按鈕的信號有9種,分別繼承自三個類QAbstractButton,QWidget,QObject:

分別表示點擊、按壓、松開、開關等不同狀態。
我們可以在自定義類里自定義信號:

signals://自定義信號寫到signals下//返回值是void,只需要聲明,不需要實現//可以有參數,可以重載//emit hungry();來發送信號void hungry();void hungry(QString food);

2.2 槽

槽(slot)的本質是類的成員函數,其參數可以是任意類型的,可以實現不同的功能,如關閉,隱藏,下降,上升等。例如QWidget類下槽函數包括:

自定義槽:

public slots://返回值是void,需要聲明,也需要實現//可以有參數,也可以重載void eat();void eat(QString food);

2.3 松散耦合

信號和槽是松散耦合的。
松散耦合是指槽可以與信號連接(connect)在一起,只有連接的信號被激發的時候,才能調用槽函數。

2.4 特點

1:一個信號可以連接多個槽函數。多個信號也可以連接同一個槽函數。
2:信號和槽函數,參數必須一一對應。

三、示例

使用一個定時器的demo做一個簡單的示例。
定義兩個定時器,實現顯示數字的功能。

Widget::Widget(QWidget *parent) :QWidget(parent),ui(new Ui::Widget) {ui->setupUi(this);//啟動定時器,每隔1s啟動一次id1 =startTimer(1000);id2 =startTimer(2000);//定時器的一種方式QTimer *timer = new QTimer(this);timer->start(500);//超時信號和顯示槽函數建立連接,timer一超時便發送一個信號setText方法遞增1connect(timer,&QTimer::timeout,[=](){static int num = 1;ui->label_3->setText(QString::number(num++));});//點擊暫停按鈕實現connect(ui->pushButton,&QPushButton::clicked,[=](){timer->stop();}); }

另外一種方法需要定義定時器的事件,用來顯示數字。

void Widget::timerEvent(QTimerEvent *event) {//number()方法轉stringif(event->timerId() == id1){static int num = 1;ui->label->setText(QString::number(num++));}if(event->timerId() == id2){static int num2 = 1;ui->label_2->setText(QString::number(num2++));} }

總結

對象樹和信號槽機制使QT界面功能的搭建變得簡易和靈活,缺點在于由于需要遍歷所有關聯造成性能降低。

總結

以上是生活随笔為你收集整理的QT对象树、信号和槽机制的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。