概述
Qt 中的信號和槽應該是最熟悉不過的了,連接信號和槽的關鍵字 connect有五種連接類型,今天不是介紹這五種連接類型,而是簡單的總結一下 connect 的幾種新舊寫法,其實在新版本中幾種寫法都能適用,看個人習慣吧。
第一種
首先來看看老版本的 connect 寫法,比較復雜些,需要將信號和槽進行明確的指定,包括形參。
看一個示例:
為方便演示,先自定義一個 Button,然后定義兩個重載的信號
1
2
3
4
5
6
7
8
9
10
|
class
MyButton :
public
QWidget
{
Q_OBJECT
public
:
explicit MyButton(QWidget *parent = nullptr);
signals:
void
sigClicked();
void
sigClicked(bool check);
};
|
那么在用這個 Button 的時候連接這兩個信號,按照舊版本的寫法,應該是這樣:
1
2
|
connect(m_pBtn,SIGNAL(sigClicked()),
this
,SLOT(onClicked()));
connect(m_pBtn,SIGNAL(sigClicked(bool)),
this
,SLOT(onClicked(bool)));
|
這種寫法比較麻煩,常常在用的時候缺少括號,不過該寫法很明確,一眼就能看出來是將哪個信號連接到哪個槽。
第二種
接着上面的示例,在 Qt5.0以后推出一種新的寫法,如下:
1
|
connect(m_pBtn,&MyButton::sigClicked,
this
,&Widget::onClicked);
|
這種寫法看起來很簡潔,但是存在一些坑需要注意,這句寫法如果用在上面的示例中,會報錯下面的錯誤:
1
2
|
error: no matching member function
for
call to
'connect'
connect(m_pBtn,&MyButton::sigClicked,
this
,&Widget::onClicked);
^~~~~~~
|
這是因為我們自定義的 Button 中存在兩個重載信號,然后用這種 connect 的方式會無法識別到底想要連接哪個信號。所以,如果信號是重載的話,需要用下面的寫法來替換:
1
|
connect(m_pBtn, static_cast<
void
>(&MyButton::sigClicked),
this
, &Widget::onClicked);</
void
>
|
問題又來了,如果我的onClicked槽也是重載的話,還是會報同樣的錯誤。因為編譯器不知道你想要真正連接哪個槽。所以這里建議,如果信號重載,可以用上面的方法來寫,如果槽重載…還是用第一種方法來 connect 吧,比較保險,雖然比較麻煩點。
第三種
最后來看一種最新的寫法,忘記是在 Qt 的哪個版本推出的了,主要針對重載信號的連接做了調整,會更簡單些:
同樣是上面的示例:
1
|
connect(m_pBtn, QOverload<bool>::of(&MyButton::sigClicked),
this
,&Widget::onClicked);</bool>
|
很顯然這種寫法相對於第二種會比較簡單些,但依然不能連接到重載的槽函數,如果連接重載槽函數,還是會報之前的錯誤。
Lambda 函數寫法
個人比較喜歡用lambda函數的方式,如果槽函數中的內容比較簡單的話,沒必要再去單獨定義一個槽來連接, 直接用Lambda 函數會更簡單。
來看一下示例:
1
2
3
4
|
connect(m_pBtn, QOverload<bool>::of(&MyButton::sigClicked),
[=](bool check){
/* do something.. */
});</bool>
|
1
2
3
|
connect(m_pBtn, static_cast<
void
>(&MyButton::sigClicked),
this
, [=](bool check){
//do something
});</
void
>
|