C++ Qt:是否可以创建一种模板插槽?

Flo*_*lla 3 c++ qt

我是Qt的新手而不是C++专家所以请耐心等待.我正在开发一个具有12种不同QPushButtons的应用程序,但它们都执行非常类似的操作:它们从地图中获取一些值,然后使用它来设置该按钮的样式:

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

对于12个按钮中的每一个,我必须创建一个仅在使用的按钮上有所不同的插槽.因此,创建几乎完全相同的12个函数看起来有点奇怪.

有一个更好的方法吗?

Ale*_*x P 5

一般来说,我见过几种方法:

  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()] ) );
      });
    }
    
    Run Code Online (Sandbox Code Playgroud)

    有关如何使用Qt编写lambda函数的更多指导,请参阅" Qt Slots和C++ 11 lambda ".

  2. 更脏的方式:QObject :: sender().

    Qt允许您在插槽中使用QObject :: sender()来获取指向调用它的对象的指针.这已经是一种广泛使用的方法多年,但有一些限制,如Qt文档中所述:

    警告:如上所述,当通过Qt :: DirectConnection从与该对象的线程不同的线程调用插槽时,此函数的返回值无效.请勿在此类场景中使用此功能.

    有关详细信息,请参阅" 如何使用信号/插槽机制获取发件人窗口小部件? ".

  3. 过时的代码:QSignalMapper.

    有一个QSignalMapper类,它允许您将信号与一些数据(如字符串)相关联,然后连接到使用此参数的插槽.这曾经作为Qt中的一个便利类存在,但正逐步淘汰,因为lambda方法使它毫无意义.

    如果您需要更新使用QSignalMapper删除它的代码,本教程是一个合理的起点.