Qt 自定義訊號與槽
注 物件與槽理解
//第一個引數lineEdit是激發事件物件,訊號中的方法必須在物件中存在,並在物件類標頭檔案signals下定義,
//第二個引數訊號,
//第三個引數this是槽方法所屬類的物件,且必須在物件類的標頭檔案的slots下定義
//第四個引數槽方法類,槽 方法
connect(lineEdit,SIGNAL(textChanged(QString)),this,SLOT(showArea()));
使用自定義的訊號和槽,需要注意以下幾點:
1、類的宣告和實現分別放在.h和.cpp檔案中;
2、類宣告中包含Q_OBJECT巨集;
3、訊號只要宣告不要設計其的實現函式;
4、發射訊號用emit關鍵字;
5、自定義槽的實現與普通成員函式的實現一樣。
6、訊號和槽方法必須在類的標頭檔案中定義
本文所示程式碼在windows xp + MingW3.4.2+ eclipse3.4+CDT5.0版本中除錯通過
QT系統為我們提供功能非常全面訊號處理機制,它的內製訊號和槽已經非常全面,因此大多數情況下,我們不需要自己設計訊號和槽,但是有些時候,我們可能需要設計一些獨特的訊號和槽,來滿足程式的需求。QT的核心機制訊號和槽是獨立於C++的,一般C++設計處理如按鈕點選等方法,多采用回撥函式,而回調函式設計上的複雜,雖然執行效率相對於QT訊號與槽要高,但是其導制容易出錯。況且在日常應用程式設計中來說,這種高效率相差不成比例,因此QT採用自己獨門設計,來高效的程式設計。本文也同樣倡導大家使用訊號與槽。
如何才能設計自己的訊號和槽呢,閱讀完本節您將會輕鬆實現自己的需求。
在建立訊號和槽之前首先大家需要建立三個檔案:類申明檔案(yourclass.h),類實現檔案(youclass.cpp),程式主體檔案(main.cpp)。
請看下面的例子,假設我們需要一個來處理文字框的內容的程式,程式主介面有兩個按鈕,當們點選按鈕[Modify]時,文字框內容被改為“jingjing”。
1、自定義槽:
按鈕點選訊號clilcked()通過繼承已經存在,因此我們暫時不需要定義這個訊號。那麼我們要改變文字框內容,就需要自己定義一個槽,來響應點選訊號。
示例程式碼(類申明檔案 yourclass.h):
複製程式碼
- #ifndef YOURCLASS_H_
- #define YOURCLASS_H_
- #include <QWidget> //QT視窗應用程式需要包含的檔案
- #include <QPushButton> //製作按鈕時,需要包含
- #include <QLineEdit> //製作文字框時,需要包含
- class MyMainWindows:public QWidget //申明一個MyMainWindows類,這個類用於實現窗體
- {
- Q_OBJECT //Q_OBJECT是在定製訊號和槽和必須包含的一條巨集語句
- public:
- MyMainWindows(); //類建構函式(用於實現程式的主體部份)
- public slots: //所有的槽函式都必須申明public slots語句內
- void SlotTest(); //這個槽函式用於顯應點選按鈕時改變文字框內容
- private:
- QPushButton * pb; //申請一個按鈕QPushButton
- QLineEdit * ledit; //申請一個文字框ledit
- };
- #endif /* YOURClASS_H_ */
在上面的示例程式碼中,我們申明瞭一視窗應用程式類檔案,它的功能是申明程式所需要全部元素資訊。在這個類中,我們申明瞭自己的槽SlotTest()函式,來響應按鈕點選的訊號。如下所示:
複製程式碼
- public slots: //所有的槽函式都必須申明public slots語句內
- void SlotTest(); //這個槽函式用於顯應點選按鈕時改變文字框內容
正如程式碼中註釋說明,在自定義槽和訊號是有兩點是至關重要的:
第一點:所有的槽函式都需要包含在public slots語句下面。它的申明和類的公有函式方法pulic是類似的。如果你有多個槽函式,只要需要一一列出即可。
第二點;在類的檔案開始部份應含Q_OBJECT巨集語句,請記住它不需要標點符號,所以不要加[;]符號。所有的QT自定義槽和訊號都需要有它的存在。
下面是製作第二個檔案:類實現檔案yourclass.cpp。在這個檔案用於yourclass.h中申明的元素實現部份。
示例程式碼(類實現檔案yourclass.cpp)
複製程式碼
- #include "yourclass.h" //包含yourclass.h類申明檔案
- MyMainWindows::MyMainWindows() //實現建構函式
- {
- setGeometry(90,90,300,200); //繪製主窗體,大小為300X200
- pb = new QPushButton("Modify",this); //實現pb按鈕,被設計其名字為Modify
- pb->setGeometry(10,10,100,20); //繪製pb按鈕的位置(10,10)和大小(100,20)
- ledit = new QLineEdit("what's your name",this); //實現ledit檔案框,其內容為what's your name
- ledit->setGeometry(10,30,200,150); //繪製ledit檔案框位置(10,30)和大小(200,150)
- connect(pb,SIGNAL(clicked()),this,SLOT(SlotTest())); //連線pb按鈕的點選clicked()訊號和自定義槽SlotTest()
- }
- void MyMainWindows::SlotTest() //自定義槽函式的實現方法,重置文字框的內容
- {
- ledit->setText("jingjing"); //“jingjing”為點選按鈕Modify後的內容
- }
在yourclass.cpp中,我們實現了程式的全部功能,程式的執行還需要有一個入口。它的主體部分mian.cpp。
複製程式碼
- #include <QApplication> //所有QT應用程式都要包含QApplication標頭檔案
- #include "yourclass.h" //包含類定義檔案yourclass.h
- int main(int argc,char * argv[])
- {
- QApplication app(argc,argv); //申明一個QT應用程式對像app
- MyMainWindows w; //申明我們實現MyMainWindows窗體對像 w.
- w.show(); //顯示這個w 窗體
- return app.exec();
- }
程式編譯完成後執行當點選Modify按鈕,文字內容what's your name 被修改為jingjing
2、自定義訊號
在上例中,我們瞭解了怎樣來實現自己的槽函式,在下文中我們將介紹怎麼實現自己的訊號。QT訊號的申明與實現,相對QT槽函式來說,要更加容易一些。它相當於一系列函式原型。不需要有具體實現處理內容。在上文中,我們是通過點選clicked()這個訊號,來連線槽函式SlotTest(),並達到修改文字框的內容。本例中,我們將在窗體新增一個文字標籤label,然後在槽函式SlotTest()中測試label內容是否發生變化,如果發生了變化,就引發訊號SigTest()。該訊號連線到槽函式SlotTest2(),將文字框內容修改為"SigSig"。
下面為實現檔案:
請開啟上節中的yourclass.h檔案,在程式碼加入一個槽函式SlotTest2(),和一個訊號SigTest()。紅色程式碼為新增加內容,如下所示:
複製程式碼
- #ifndef YOURCLASS_H_
- #define YOURCLASS_H_
- #include <QWidget> //QT視窗應用程式需要包含的檔案
- #include <QPushButton> //製作按鈕時,需要包含
- #include <QLineEdit> //製作文字框時,需要包含
- #include <QLabel> //製作文字標籤時,需要包含
- class MyMainWindows:public QWidget //申明一個MyMainWindows類,這個類用於實現窗體
- {
- Q_OBJECT //Q_OBJECT是在定製訊號和槽和必須包含的一條巨集語句
- public:
- MyMainWindows(); //類建構函式(用於實現程式的主體部份)
- public slots: //所有的槽函式都必須申明public slots語句內
- void SlotTest(); //這個槽函式用於顯應點選按鈕時改變文字框內容
- void SlotTest2(); //新增加槽函式,用於將文字框內容改為SigSig
- private:
- QPushButton * pb; //申請一個按鈕QPushButton
- QLineEdit * ledit; //申請一個文字框ledit
- QLabel * label; //申請一個文字標籤label
- Signals: //所有訊號都需要申明在signals語句內
- void SigTest() //新增加訊號SigTest()。
- };
- #endif /* YOURClASS_H_ */
在這個例子中,我們加入了自定義的訊號SigTest()。在QT中訊號的申請方法是,在類中加入signals(訊號)語句。然後在語句後面定義自己的訊號函式就可以了。有趣的是訊號的定義並不需要具體實現,它就像一系列函式原型一樣。你只需要申請就可以了。本例中,我們申請了一個不帶有任何引數的訊號SigTest()。在下文中我們將用這個訊號來實現文字框內容變化。
在窗體上要繪製文字標籤,就必須加入<QLabel>標頭檔案。其次我們在程式碼中新增加了一個槽SlotTest2()函式和一個訊號SigTest()函式,並通過connect()函式連線。
程式碼如下所示(yourclass.cpp):
複製程式碼
- #include "yourclass.h"
- MyMainWindows::MyMainWindows()
- {
- setGeometry(90,90,300,200);
- pb = new QPushButton("Modify",this);
- pb->setGeometry(10,10,100,20);
- ledit = new QLineEdit("what's your name",this);
- ledit->setGeometry(10,30,200,150);
- label = new QLabel("My MeMe",this); //實現一個文字標籤label,並將其內容初使為:My MeMe
- label->setGeometry(115,10,100,20);
- connect(pb,SIGNAL(clicked()),this,SLOT(SlotTest()));
- connect(this,SIGNAL(SigTest()),this,SLOT(SlotTest2())); //連線自定義訊號SigTest ()和SlotTest2()槽函式
- }
- void MyMainWindows::SlotTest() //訊號1
- {
- ledit->setText("jingjing");
- label->setText("TTT"); //將文字標籤label內容設定為TTT文字
- if(label->text() != "My MeMe")
- {
- emit SigTest();
- }
- }
- void MyMainWindows::SlotTest2() //訊號2
- {
- ledit->setText("SigSig"); //設定文字框內容為SigSig
- }
從上面程式碼中可以看出,首先我們在MyMainWindows()主窗體類建構函式中加入了
複製程式碼
- label = new QLabel("My MeMe",this);
- label->setGeometry(115,10,100,20);
Label文字標籤的初使內容為My MeMe。其位置為窗體的(115,10),大小為(100,20),我們在上一事例中講過的槽函式SlotTest()中新加入了對文字標籤的檢測,來達到對我們自定義訊號SigTest()觸發。如下所示:
複製程式碼
- void MyMainWindows::SlotTest() //訊號1
- {
- ledit->setText("jingjing");
- label->setText("TTT"); //將文字標籤label內容設定為TTT文字
- if(label->text() != "My MeMe")
- {
- emit SigTest();
- }
- }
- void MyMainWindows::SlotTest2() //訊號2
- {
- ledit->setText("SigSig"); //設定文字框內容為SigSig
- }
如程式碼所示當SlotTest()槽函式被呼叫時,首先將ledit文字框內容設為jingjing,並把label文字標籤內容設為TTT,然後此時我們檢測label的內容是不是還為它的初使內容My MeMe,如果不是,則引發我們自定義的SigTest()訊號。請注意程式碼中emit(發射)關鍵字,做為QT訊號與槽機制來說,emit的作用就是將訊號發出來的意思。也就是說,當我們類申明檔案中定義了一個訊號時,如果要使用這個訊號,只需在訊號語句前面加上emit關鍵字就可以了。
而在SlotTest2()槽函式中,我們把文字框ledit的內容設為:SigSig。也就是當SlotTest2()槽函式被呼叫時就又會把ledit中內容修改為SigSig。在本事例中,我們用SigTest()訊號來連線SlotTest2()這個槽,也就是說當SigTest()訊號被觸發時,就會將文字框的內容修改為:SigSig。程式碼如下:
複製程式碼
- connect(this,SIGNAL(SigTest()),this,SLOT(SlotTest2()));
現在讓我們把上例中的Main.cpp檔案放到一起,進行編譯
當第一次點選[Modify]按鈕時,程式首先產生一個訊號clicked(),而這個訊號將導致SlotTest()槽被執行,文字框的內容首先被修改為jingjing,然後label文字標籤的內容被修改為TTT,隨後在SlotTest()語句發現label的內容不是My MeMe,因此向外發射訊號SigTest()。而SigTest()訊號與SlotTest2()槽連線,因此導致SlotTest2()槽函式被呼叫,它又將文字框內容修改為了SigSig。因此當我們點選Modify時,文字框內容最終會變為SigSig文字。
相關推薦
Qt 自定義訊號與槽
注 物件與槽理解 //第一個引數lineEdit是激發事件物件,訊號中的方法必須在物件中存在,並在物件類標頭檔案signals下定義, //第二個引數訊號, //第三個引數this是槽方法所屬類的物件,且必須在物件類的標頭檔案的slots下定義
【PyQt5-Qt Designer】pyqtSignal()-高階自定義訊號與槽
PyQt 5訊號與槽的幾種高階玩法 參考:http://www.broadview.com.cn/article/824 from PyQt5.QtCore import QObject , pyqtSignal class CustSignal(QObject): #宣告無引數的訊號
170329 PyQt5 自定義訊號與槽
1625-5 王子昂 總結《2017年3月28日》 【連續第178天總結】 A.PyQt5資料傳送、處理及訊號與槽的練習 B.今天終於把手頭上的事都搞完了 資料傳輸都是很瑣碎的東西,前幾天也熟悉過了,
QT 自定義函式 自定義訊號和槽
在QT中自定義函式,訊號,槽基本上都是在基類上派生時設計的 這裡分兩種情況討論 一,程式碼模式 通過.H和.cpp設計介面佈局,並通過派生設計自定義的函式,訊號,槽 二,視覺化設計模式 1,設計工具設計介面 2,新建類繼承上面的介面,並設計自定義函
Qt 筆記:訊號與槽的連線方式
深入訊號與槽的連線方式 -Qt::DirectConnection(立即呼叫) -Qt::QueuedConnection(非同步呼叫) -Qt::BlockingQueuedConnection(同步呼叫) -Qt::AutoConnection(預設連線) -Q
Qt-登入介面訊號與槽函式
Qt訊號與槽函式可以實現任意兩個Qt類的物件之間進行通訊,比如登入類QtLoginWin 與介面上的登入按鈕loginBt 當點選按鈕的時候會發送clicked訊號,這樣就可以與QtLoginWin的槽函式關聯進行通訊如下圖: 把控制元件的名字分別修改為 使用者
Qt程式設計之訊號與槽-------unresolved external symbol "public: virtual struct QMetaObject const * __thiscall XX::metaObject(void)const
原因是加入Q_OBJECT這個macro的類,被編譯的時候就要用到moc這個命令,所以在VS2010中,沒有加入此命令的應用,當然會出錯了。所以解決辦法是加,或者如果你不使用訊號槽可以直接刪除。 當要在GUI中用到訊號與槽,就需在.h檔案中的類裡寫入Q_OBJECT巨集。而任何含有Q_Object的類都
Qt 中的訊號與槽,連線日誌庫QsLog,在介面上顯示出日誌資訊
新建一個基於QWidget的工程,在介面上新增一個QTextBrowser控制元件,用來在介面顯示日誌資訊。 在pro檔案中新增QsLog的標頭檔案和lib庫 INCLUDEPATH += include/QsLog.h \ inc
自定義型別用於訊號與槽之間的傳輸
應用場景: 使用訊號和槽的時候可以傳遞引數,但Qt只支援預設的型別,不支援自定義型別, 如果要使用自定義型別,需要通過2步來實現 第一步:在定義類的標頭檔案的尾部新增程式碼: Q_DECLARE_METATYPE(Block); class Block { public: Blo
QT 如何繫結自定義訊號槽
一 原理qt中不能繫結非基本型別的訊號槽,例如自己的結構體等。二 方法此時就需要我們用qt自帶的方法註冊一下這個訊號槽,例子:有如下一個自定義引數的訊號 void drawInfo(SDRAWINGDATA &drawInfo , DATATYPE type); 會報
QT學習day02---圖形介面、對話方塊、訊號與槽
一、QT圖形介面 ①QT座標軸 起點:左上角 X:橫軸 Y:縱軸 ②QWidget、QDialog、QMainWindow的異同點 QWidget:視窗為空,什麼內容都沒有 QMainWindow:含有選單欄,狀態列,工具欄等…已經包含了QWidget QDialog:對話方塊(
QT多執行緒中,物件訊號與槽連線不上的解決辦法
1、在接收者建立執行緒中,把接收者移動到主執行緒中: pReceiverObj->moveToThread(QApplication::instance()->thread()); 2、這樣傳送訊號的時候,就會在主執行緒事件佇列處理中來處理了。 把connect的最
QT學習記錄1(訊號與槽)
使用,學習QT的背景 剛入職新公司,工作是嵌入式軟體,工作內容包括使用QT進行一些軟體的開發等,以前沒有接觸過QT,特意建立第一篇部落格,用作QT的學習過程記錄 入職後,公司前輩要求使用QT寫一個軟體,接收硬體裝置傳回的資料並顯示,同時軟體可以對裝置的工作方式進行設定,使用TCP通訊協議。
QT使用訊號與槽注意事項
QT使用訊號與槽注意事項 如需轉載請標明出處:http://blog.csdn.net/itas109 QQ技術交流群:129518033 目錄 文章目錄 QT使用訊號與槽注意事項 @[toc] 前言
QT學習之路---訊號與槽問題解析
前兩天用到了QT的訊號與槽這個機制,剛開始發射訊號的時候,我是這麼寫的語句 connect(sender,SINGAL(),receiver,SLOT()) 由於我用的是QT 5.11這個本,從網上查到的例子來說,大部分都是以上那個形式,也沒有問題,而實際上在QT5.11版本上,向下面這樣寫
實現自己的訊號與槽機制-借鑑Qt
如果對Qt的訊號與槽機制不太理解可以檢視以下網址: http://blog.csdn.net/fuyunzhishang1/article/details/48345381 該博主講的十分的清楚。 最近我自己在做基於嵌入式的GUI,重構了好幾遍總覺得自己的訊息機制很繁瑣,直到自己看到了Q
QT:moveToThread與訊號與槽機制的第五個引數Qt::ConnectionType
原來對QThread的理解,就是重寫run(),曾經還一度搞不明白,到底它的槽屬於主執行緒還是子執行緒。後來學了MFC,一度覺得MFC的機制比較人性化,起碼有工作執行緒和介面執行緒的用法,而不像QThread只有run是真正活在子執行緒裡面的。而直到今天再次研究QThrea
Pyqt/Qt訊號與槽的理解(一)
訊號與槽有三種使用方法:內建訊號與槽,自定義訊號與槽和裝飾器的訊號與槽。 內建訊號與槽 內建訊號與槽是指在發射訊號時,使用視窗控制元件的函式,而不是自定義的函式,可通過QObject.signal.connect將一個QObject的訊號連線到另一個QO
QT 訊號與槽在不同執行緒不能連線的問題
QObject::connect: Cannot queue arguments of type 'ERROR_LEVEL' (Make sure 'ERROR_LEVEL' is registered using qRegisterMetaType().) 其中ER
PyQt5筆記之Qt Designer自定義訊號emit及傳參
from PyQt5 import QtWidgets,QtCore from untitled import Ui_Form import time class MyWindow(QtWidgets.QWidget,Ui_Form): _signal=Qt