为什么我的 mousePressEvent 被调用了两次?

Why is my mousePressEvent called twice?

我想使 QLabel 可点击并跟随 this "how-to"。我不确定如何将这段代码放入我的 GUI(我是 qt 的新手)。我所做的是:

  1. 我创建了一个新的 class(只是 link 中 ClickableLabel 的 copy/paste,但我将信号更改为 clicked(QMouseEvent* event)
  2. 我在我的 GUI 中添加了一个 QLabel 并且 "promoted" 它到 ClickableLable
  3. 我将信号连接到我的主 window 的一个插槽,在那里我 std::cout 一些东西:

    connect(this->ui->label,SIGNAL(clicked(QMouseEvent*)),
            this,SLOT(on_label_clicked(QMouseEvent*)));
    

这似乎有效。问题是每次我点击标签时 mousePressedEvent 都会被调用两次。我也试过 mouseReleasedEvent 但它是一样的。

有什么可能出错的想法吗?

编辑:这是我修改后的 ClickableLable:

class MyClickableLabel : public QLabel {
    Q_OBJECT
    public:
        MyClickableLabel(QWidget* parent=0);
        ~GBoardLabel();
    signals:
        void clicked(QMouseEvent* event);
    protected:
        void mouseReleaseEvent(QMouseEvent* event);
};
MyClickableLabel::MyClickableLabel(QWidget* parent) : QLabel(parent) {this->setText("");}
MyClickableLabel::~MyClickableLabel() {}
void MyClickableLabel::mouseReleaseEvent(QMouseEvent *event){
    std::cout << "CLICKED R" << std::endl;
    std::cout << event->type() << std::endl;
    std::cout << event->pos().x() << std::endl;
    std::cout << event->pos().y() << std::endl;
    emit clicked(event);
}

上面方法中的cout是我后来才加的,发现mouseReleaseEvent其实只调用了一次。但是当我将 clicked 连接到我的 mainwindow 的一个插槽时,这个插槽接收到事件两次。

然后我删除了 connect 语句,令我惊讶的是信号仍然发出和接收(仅一次)。我有点困惑这是如何工作的,因为我很确定我没有在代码中的任何地方错误地使用 connect

我的标签工作正常,但我想了解发生了什么。实际上,我不再 100% 确定我没有使用 Qt Creator 的某些功能来建立连接。但是,我不知道在哪里可以找到这样的联系。例如,我在同一个主 window 上有一个 QButton。在 gui 编辑器中,我右键单击它,然后 "show slots"->"clicked()"->"OK" 并自动创建一个名为 on_pushButton_clicked() 的方法,但我不知道它在哪里被调用/按钮的信号如何连接到此方法。另一方面,我没有在我的标签的插槽列表中列出 MyClickableLabel::clicked(QMouseEvent*),因此我不认为我以这种方式创建了连接...

我可以修复它,但我真的不明白发生了什么...

不是 mousePressEvent 触发了两次,而是我的 on_label_clicked 插槽收到了两次事件。

我删除了 connect 语句,现在每次点击仅调用一次 on_label_clicked。看起来,幕后发生了一些事情。也许当插槽被称为 on_label_clicked 时,它会自动 ("qtmatically") 连接到从名为 label 的 child 发出的鼠标事件?

编辑:仍然没有找到官方文档,但是this blog 解释得很好。总之,只需要使用插槽的命名约定

void on_<widget name="">_<signal name="">(<signal parameters="">);

使用自动连接功能。