我是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个函数看起来有点奇怪.
有一个更好的方法吗?
一般来说,我见过几种方法:
首选方法: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 ".
更脏的方式:QObject :: sender().
Qt允许您在插槽中使用QObject :: sender()来获取指向调用它的对象的指针.这已经是一种广泛使用的方法多年,但有一些限制,如Qt文档中所述:
警告:如上所述,当通过Qt :: DirectConnection从与该对象的线程不同的线程调用插槽时,此函数的返回值无效.请勿在此类场景中使用此功能.
有关详细信息,请参阅" 如何使用信号/插槽机制获取发件人窗口小部件? ".
过时的代码:QSignalMapper.
有一个QSignalMapper类,它允许您将信号与一些数据(如字符串)相关联,然后连接到使用此参数的插槽.这曾经作为Qt中的一个便利类存在,但正逐步淘汰,因为lambda方法使它毫无意义.
如果您需要更新使用QSignalMapper删除它的代码,本教程是一个合理的起点.