訊號與槽的新語法 Qt5

2021-05-26 05:00:33 字數 3034 閱讀 9406

在 qt5 的 qtbase-staging **倉庫的 qobject_connect_ptr 分支中已經引入了一種全新的訊號與槽的語法。

參看 new signal slot syntax possibly coming in qt 5 一文。

connect(slider, signal(valuechanged(int)), spinbox, slot(setvalue(int)));
而使用新式語法,這個樣子:

connect(slider, &qslider::valuechanged, spinbox, &qspinbox::setvalue);
使用新式語法:

這一切都太吸引人了,我們稍候逐一檢視

例子很簡單,考慮到大家應該沒安裝該版本的qt,故稍微羅嗦一下。

(注意:現在是2023年6月15日,或許等你感興趣想安裝時,倉庫已經有了較大變化。- dbzhang800)

git clone git:
然後checkout出 qobject_connect_ptr 這個分支

剩下的工作就不用說了,configure、make、make install

看個完整的程式**,除了兩個connect是新的,其他的應該都無須解釋。

;widget::widget(qwidget *parent):

qwidget(parent)

int main(int argc, char *argv)

恩,如你所想,程式一切正常。

我們知道老式語法connect中接收的是兩個字串,

bool qobject::connect ( const qobject * sender, const char * signal, const qobject * receiver, const char * method, qt::connectiontype type = qt::autoconnection ) [static]
比如:

connect(slider, signal(valuechanged(int)), spinbox, slot(setvalue(int)));
編譯預處理以後就是:

connect(slider, "2valuechanged(int)", spinbox, "1setvalue(int)");
這有什麼問題呢?

typedef int myint;

connect(a, signal(sig(int)), b, slot(slt(myint)));

或者namespace修飾不一樣

using namespace std;

connect(a, signal(sig(std::string)), b, slot(slt(string)));

都會導致連線失敗。

我們在qt訊號和槽,與const char* 的故事一文中詳細地討論過這些問題。

新式的訊號槽寫法完全避免了這些問題。

新式語法是使用模板來實現的。由於模板的例項化是編譯期完成的,所以如果有問題編譯時直接就可以暴露出來,這比老式用法(問題要在執行時才能反應出來)是的巨大的改進。

注意看connect的寫法

connect(a, &widget::sig1, b, &widget::slt2);
都是用的函式的位址

../newconnect/main.cpp:26:20: error: 『sig1』 is not a member of 『widget』

../newconnect/main.cpp:26:41: error: 『slt2』 is not a member of 『widget』

src/gui/kernel/qwidget.h: in member function 『void qwidget::qt_check_for_qobject_macro(const t&) const [with t = widget]』:

......................

../../qt-labs/qtbase-newsignal-build/include/qtgui/../../../qtbase/src/gui/kernel/qwidget.h:149:5: error: void value not ignored as it ought to be

模板一出錯,給的東西總是這麼多,只好中間大部分都省略了。

src/corelib/kernel/qobject.h: in static member function 『static void qtprivate::functionpointer::call(ret (obj::*)(arg1), obj*, void**) [with args = qtprivate::list, obj = widget, ret = void, arg1 = qstring, ret (obj::*)(arg1) = void (widget::*)(qstring)]』...
同樣很的錯誤風格。沒辦法,模板總是這樣子

注意看我們一開始給出的例子中給出的兩個 connect 語句

connect(slider, &qslider::valuechanged, spinbox, &qspinbox::setvalue);

connect(spinbox, static_cast(&qspinbox::valuechanged), slider, &qslider::setvalue);

前乙個很簡潔,可是後乙個?什麼情況!!!

呵呵,沒辦法啊,qspinbox的valuechanged訊號是過載的:

void valuechanged ( int i )

void valuechanged ( const qstring & text )

只好顯示呼叫static_cast了。

c++0x標準引入了lambda函式,這個東西配合新式的connect使用似乎是很有意思。

比如:當qslider的值改變時,通過qdebug輸出該值,我們只需要

connect(slider, &qslider::valuechanged, (int v));

}

QT5 訊號與槽

前言 訊號與槽是qt的精華所在,也是他區分於其他軟體的關鍵地方,所以我們學習qt肯定無法繞過這一核心 當物件內部狀態發生改變,訊號就被反射,只有定義了這個訊號的類和他的子類才能發射這個訊號 訊號的宣告是在標頭檔案中進行的,qt的signals關鍵字指出進入了訊號宣告區,隨後即可宣告自己的訊號。訊號由...

QT 5 新語法之訊號過載問題

在 qt 4 qt4 中,關聯訊號和槽比較常用的是 這裡訊號用 va luec hang ed v al uech ange d 槽用 se tval ue s et valu e 演示 connect sender,signal valuechanged int receiver,slot set...

Qt5,訊號槽關聯錯誤

一 錯誤提示 error c2664 qmetaobject connection qobject connect const qobject const char const char qt connectiontype const 無法將引數 2 從 overloaded function 轉換...