有一个容器Widget实例A,A中包含Widget实例C1,C2,C3,...等。
有一个插槽可以处理Widget A的action_triggreed()信号。
有没有办法确定点击了哪个目标小部件C1,C2,C3 ......? 这种必要性的原因在于有许多包含的小部件,并且在每个小部件上使用connect()方法没有意义,这需要50多行额外的连接语句,每个都需要一个!
例如:考虑一个包含大量按钮的QToolBox。如何使用QToolBox action_triggered或类似信号确定按下哪个按钮,而不单独使用各个按钮的信号和插槽?
答案 0 :(得分:1)
有一些通用方法。
第一个是直截了当的 - 您应该将每个小部件的信号连接到插槽并检查sender()
是什么。是的,用于连接的代码行。
第二个是使用一种映射器。每个小部件都连接到映射器,只有映射器连接到目标插槽。再次使用代码行,至少在将小部件连接到映射器的部分中。有一个通用QSignalMapper
或者您可以使用更适合您的小部件的特定版本。例如,如果它们是按钮,那么您可以使用QButtonGroup
类。每个按钮都在组中注册,只需要一个信号/插槽连接。
QButtonGroup group;
group->addButton(buttonC1,C1_ID);
...
group->addButton(buttonC1,Cn_ID);
connect(&group,SIGNAL(buttonClicked(QAbstractButton*),this,SLOT(buttonClicked(QAbstractButton*));
第三种方法是仅在母亲的小部件A上检测鼠标事件,然后迭代其所有子节点并找到哪一个在鼠标下。更少的代码,您可以轻松添加新的小部件,但成本是在运行时迭代所有小部件。以下是一个例子。请注意,您可以将特定的QObject
名称或属性添加到窗口小部件C1 ...以便您可以过滤它们,如果您只对给定类型的子窗口小部件感兴趣。
void mousePressEvent(QMouseEvent* event)
{
if (event->button()==Qt::LeftButton)
{
QList<QToolButton*> buttons=findChildren<QToolButton*>(); // you can also use specific object names on the widgets under your interest
foreach (QToolButton* button, buttons)
{
if (button->underMouse()) // you could try isDown() for button, but I'm not sure if that will work here
{
emit buttonClicked(button);
break;
}
}
}
}
嗯,你也可以尝试另一种方法。检测鼠标事件,获取光标位置并在该位置上查找子窗口小部件。运行时费用不高。
void mousePressEvent(QMouseEvent* event)
{
if (event->button()==Qt::LeftButton)
{
QPoint pt=mapFromGlobal(QCursor::pos());
QWidget* child=childAt(pt);
if (child)
{
emit childClicked(child);
}
}
}
答案 1 :(得分:0)
您可以使用QObject::sender()
功能。
void A::triggeredSlot() {
QObject* obj = sender();
QButton* but = qobject_cast<QButton*>(obj);
}
只需使用正确的类型等。