Qt工具栏Action触发时sender()返回对象名为空的问题咨询
问题分析与解决方案
这个问题我刚接触Qt工具栏的时候也踩过坑,咱们来理清楚根源和解决办法:
问题出在哪?
你对QToolBar::actionTriggered信号的理解出现了偏差:
- 这个信号本身会把触发的QAction作为参数传递出来,但你在lambda里调用
sender(),拿到的其实是发送信号的QToolBar对象(也就是你的toolBar实例),而你并没有给toolBar设置过objectName,所以返回空字符串是必然的。 - 你误以为
sender()会指向被点击的Action,但实际上sender()的作用是返回发出当前信号的对象,这里信号是QToolBar发的,所以它指向的是工具栏,不是Action。
修正后的正确写法
直接用信号传递的QAction参数就行,这也是Qt推荐的更清晰、更可靠的写法:
1. 修正connect的lambda表达式
把信号带的Action参数直接传入处理函数:
connect( &toolBar, &QToolBar::actionTriggered, this, [=](QAction *triggeredAction) { process_toolbar_ac_evt(*triggeredAction); });
2. 保持处理函数逻辑不变
现在你的process_toolbar_ac_evt拿到的就是真正被点击的QAction对象,它的objectName就是你之前设置的circle_id、triangle_id这些值,判断逻辑就能正常工作了:
void Main_Frame::process_toolbar_ac_evt(QObject &evt) { if (evt.objectName() == circle_id) { // 点击圆形Action的处理逻辑 } else if (evt.objectName() == triangle_id) { // 点击三角形Action的处理逻辑 } else if (evt.objectName() == rectangle_id) { // 点击矩形Action的处理逻辑 } }
额外优化建议
如果想让代码更严谨,可以把处理函数的参数改成QAction&,避免不必要的类型转换:
void Main_Frame::process_toolbar_ac_evt(QAction &action) { if (action.objectName() == circle_id) { // 处理逻辑 } } // 对应的lambda调用同步修改: process_toolbar_ac_evt(*triggeredAction);
内容的提问来源于stack exchange,提问作者chris576
相关产品推荐
相关产品推荐

