如何知道触发了哪个 QMenu 的动作
Posted
技术标签:
【中文标题】如何知道触发了哪个 QMenu 的动作【英文标题】:how to know that which QMenu's action is triggered 【发布时间】:2018-01-29 15:51:58 【问题描述】:我有一些 QAction,并在许多 QMenu 小部件中添加了相同的 QAction。 所有动作都连接到同一个插槽。我想知道触发了哪些 QMenu 操作。
【问题讨论】:
提供minimal reproducible example 您可以尝试插槽中的sender() 功能,但如果不了解您的应用程序,我不确定。 sender() 返回一个指向发送信号的对象的指针。并且信号是由 QAction 发送的,我如何知道触发了哪个 QMenu 操作。 如果同一个QAction
绑定了同一个slot - 为什么你需要知道哪个被触发了?如果有原因,要么绑定不同的插槽,要么使用附加参数绑定插槽以进行标识。 (假设您使用新的 Qt5 风格的信号绑定)。 (@xander 由于QAction
是“可共享的”,我不确定sender()
是否足以区分。)
connect(playlist_action, SIGNAL(triggered()), this, SLOT(LoadPlaylist()));现在我在两个 QMenu 中添加了“playlist_action”。现在当 playlist_action 被触发时如何区分
【参考方案1】:
三思而后行,得出以下结论:
如果同一个QAction
被添加到多个菜单中,那么在槽中几乎没有机会区分哪个菜单项被触发了。
QAction
实例可以由多个菜单和工具栏共享。但在这种情况下,它是同一个实例(有多个父母)。出于同样的原因,使用附加参数进行区分的想法行不通。只有一个QAction
实例带有一个triggered
信号——没有区分的机会。
以下示例是我找到的最接近的示例 (testQActionShared.cc
):
#include <QtWidgets>
void actionSlot(const char *text)
qDebug() << "Action triggered:" << text;
int main(int argc, char** argv)
qDebug() << "Version:" << QT_VERSION_STR;
// main application
QApplication app(argc, argv);
QToolBar qToolbar;
qToolbar.addAction(QString::fromUtf8("Action"),
[](bool) actionSlot("action1"); );
qToolbar.addAction(QString::fromUtf8("Action"),
[](bool) actionSlot("action2"); );
qToolbar.addAction(QString::fromUtf8("Action"),
[](bool) actionSlot("action3"); );
qToolbar.show();
// run application
return app.exec();
testQActionShared.pro
:
SOURCES = testQActionShared.cc
QT += widgets
在cygwin 上以 bash 编译:
$ qmake-qt5 testQActionShared.pro
$ make
g++ -c -fno-keep-inline-dllexport -D_GNU_SOURCE -pipe -O2 -Wall -W -D_REENTRANT -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -I. -isystem /usr/include/qt5 -isystem /usr/include/qt5/QtWidgets -isystem /usr/include/qt5/QtGui -isystem /usr/include/qt5/QtCore -I. -I/usr/lib/qt5/mkspecs/cygwin-g++ -o testQActionShared.o testQActionShared.cc
g++ -o testQActionShared.exe testQActionShared.o -lQt5Widgets -lQt5Gui -lQt5Core -lGL -lpthread
$ ./testQActionShared
Version: 5.9.2
应用程序如下所示:
我用鼠标点击了三个动作,得到如下输出:
Action triggered: action1
Action triggered: action2
Action triggered: action3
这实际上不是一个共享的QAction
——它是三个具有相同标签文本和单独 lambdas 的操作。
lambda 已被用作适配器,以摆脱 QAction::triggered(bool)
的未使用的 bool
参数并改为绑定字符串。
注意:
我使用QToolBar
而不是QMenu
来保持样本更紧凑。不过原理是一样的。
【讨论】:
感谢您抽出宝贵的时间。我找到了我的答案here 我没有使用QSignalMapper
的经验,因为我发现 lambdas 更方便。 (这可能是一个品味问题。)如果您可以提供一个带有(类似的小)示例的自我答案以进行演示,我很乐意看看它。 (学习新东西永远不会太晚。);-)
仔细查看链接的 Q/A,我意识到这些代码示例没有使用共享的 QAction
- 它们使用具有相同插槽的不同 QAction
s(和我一样。 )
我的程序中有两个QMenu
,我在插槽中连接了两个不同的SLOTS
connect(menu1, SIGNAL(triggered(QAction*)), this, SLOT(slot1(QAction*)));
connect(menu2, SIGNAL(triggered(QAction*)), this, SLOT(slot2(QAction*)));
我在QAction
的帮助下区分QAction
并执行进一步操作。这对我很有用,因为我只有两个 QMenu
和许多 QAction
。
感谢您的想法,刚刚添加了 catch 'this' connect(copyUrlAction, &QAction::triggered, this, [this](bool) OnCtxMenuAction(7); );
以上是关于如何知道触发了哪个 QMenu 的动作的主要内容,如果未能解决你的问题,请参考以下文章