【问题标题】:Qt C++ : How to get event target object?Qt C++:如何获取事件目标对象?
【发布时间】:2016-03-17 02:44:25
【问题描述】:

有一个容器Widget实例A,A中包含Widget实例C1、C2、C3、...等。

有一个槽可以处理小部件 A 的 action_triggreed() 信号。

有没有办法确定目标小部件 C1、C2、C3、... 中的哪一个被点击了? 这种必要性的原因是包含许多小部件,并且在每个小部件上使用 connect() 方法没有意义,这将需要 50 多行额外的连接语句,每个一个!

例如:考虑一个有很多按钮的 QToolBox。您如何确定使用 QToolBox action_triggered 或类似信号按下哪个 Button,而不单独使用单个 Button 的信号和插槽?

【问题讨论】:

  • 不确定this 是否是您要查找的内容;问题不清楚,但链接可能会有所帮助。
  • 旁白:与 JavaScript 事件进行比较。您可以使用 event.target 获取目标对象。链接:developer.mozilla.org/en-US/docs/Web/API/Event/target
  • 如何将按钮添加到QToolbox?在设计器中还是通过代码?

标签: c++ qt events event-handling signals-slots


【解决方案1】:

您可以使用QObject::sender() 函数。

void A::triggeredSlot() {
    QObject* obj = sender();
    QButton* but = qobject_cast<QButton*>(obj);
}

只需使用正确的类型等。

【讨论】:

    【解决方案2】:

    有几种通用方法。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-02-28
      • 1970-01-01
      • 2015-07-19
      • 2012-04-07
      • 2011-01-28
      • 2010-12-13
      相关资源
      最近更新 更多