簡體   English   中英

C ++ Qt:是否可以創建一種模板插槽?

[英]C++ Qt: is it possible to create a sort of template slot?

我是Qt的新手而不是C ++專家所以請耐心等待。 我正在開發一個具有12種不同QPushButtons的應用程序,但它們都執行非常類似的操作:它們從地圖中獲取一些值,然后使用它來設置該按鈕的樣式:

void MainWindow::on_btn01_clicked(){
    QString img=images["btn01"];
    ui->btn01->setStyleSheet("#btn01{ background-image: url(://" + img + ") }");
}

對於12個按鈕中的每一個,我必須創建一個僅在使用的按鈕上有所不同的插槽。 因此,創建幾乎完全相同的12個函數看起來有點奇怪。

有一個更好的方法嗎?

一般來說,我見過幾種方法:

  1. 首選方法:lambda表達式。

    如果您使用的是現代C ++(C ++ 11或更高版本),則可以使用lambda函數來獲得所描述的精確效果。

    我希望結果代碼看起來像這樣:

     foreach( QPushButton * button : buttons ) { connect( button, &QPushButton::clicked, [button, &images]() { button->setStyleSheet( QString( "{ background-image: url(://%1) }" ) .arg( images[button->objectName()] ) ); }); } 

    有關如何使用Qt編寫lambda函數的更多指導,請參閱“ Qt Slots和C ++ 11 lambda ”。

  2. 更臟的方式:QObject :: sender()。

    Qt允許您在插槽中使用QObject :: sender()來獲取指向調用它的對象的指針。 這已經是一種廣泛使用的方法多年,但有一些限制,如Qt文檔中所述:

    警告:如上所述,當通過Qt :: DirectConnection從與該對象的線程不同的線程調用插槽時,此函數的返回值無效。 請勿在此類場景中使用此功能。

    有關詳細信息,請參閱“ 如何使用信號/插槽機制獲取發件人窗口小部件? ”。

  3. 過時的代碼:QSignalMapper。

    有一個QSignalMapper類,它允許您將信號與一些數據(如字符串)相關聯,然后連接到使用此參數的插槽。 這曾經作為Qt中的一個便利類存在,但正逐步淘汰,因為lambda方法使它毫無意義。

    如果您需要更新使用QSignalMapper刪除它的代碼, 本教程是一個合理的起點。

您可以嘗試一種更簡單的方法,即分別設置QPushButton的對象名稱,並檢查插槽中的對象名稱並使用該字符串。 這為您節省了大量代碼。

例如:
QPushButton 1對象名設置為button->setObjectName("btn01"); 並且你可以分別設置按鈕的其他名稱,在你的插槽中你可以做這樣的事情

void MainWindow::on_button_clicked(){
     QPushButton* btn=qobject_cast<QPushButton*>(sender()); 
     QString name=btn->objectName(); 
     QString img=images[name]; btn->setStyleSheet("#" + name + "{ background-image: url(://" + img + ");
}

然后將所有QPushButtons連接到此插槽

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM