有几种通用方法。
第一个很简单 - 您应该将每个小部件的信号连接到插槽并检查 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);
}
}
}