[英]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个函数看起来有点奇怪。
有一个更好的方法吗?
一般来说,我见过几种方法:
首选方法: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 ”。
更脏的方式:QObject :: sender()。
Qt允许您在插槽中使用QObject :: sender()来获取指向调用它的对象的指针。 这已经是一种广泛使用的方法多年,但有一些限制,如Qt文档中所述:
警告:如上所述,当通过Qt :: DirectConnection从与该对象的线程不同的线程调用插槽时,此函数的返回值无效。 请勿在此类场景中使用此功能。
有关详细信息,请参阅“ 如何使用信号/插槽机制获取发件人窗口小部件? ”。
过时的代码: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.