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

时间:2015-05-01 11:13:44

标签: qt mouseevent qtgui

我想点击QLabel,然后点击this"操作方法"。我不知道如何将这段代码放入我的GUI(我是qt的新手)。我做的是:

  1. 我创建了一个新类(只是从链接中复制/粘贴ClickableLabel,但我将信号更改为clicked(QMouseEvent* event)
  2. 我在我的GUI中添加了一个QLabel,然后推广了#34;它是ClickableLable
  3. 我将信号连接到主窗口的一个插槽,我std::cout有些东西:

    connect(this->ui->label,SIGNAL(clicked(QMouseEvent*)),
            this,SLOT(on_label_clicked(QMouseEvent*)));
    
  4. 似乎有效。问题是,每次我点击标签时,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连接到主窗口的插槽时,此插槽会将事件接收两次。

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

    我的标签正在运作,但我想了解发生了什么。实际上我不再100%确定我没有使用某些Qt创建者功能进行连接。但是,我不知道在哪里可以找到这样的连接。例如,我在同一个主窗口上有一个QButton。在gui编辑器中,我右键单击它然后&#34;显示插槽&#34; - &gt;&#34;点击()&#34; - &gt;&#34; OK&#34;并自动创建一个名为on_pushButton_clicked()的方法,但我不知道这个名称是什么/按钮的信号如何连接到这个方法。另一方面,我没有在我的标签的插槽列表中列出MyClickableLabel::clicked(QMouseEvent*),因此我不认为我以这种方式创建了连接...

1 个答案:

答案 0 :(得分:0)

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

不是mousePressEvent被解雇了两次,但我的on_label_clicked广告位收到了两次事件。

我删除了connect语句,现在每次点击只调用on_label_clicked一次。看来,引擎盖下有什么东西在发生。也许当插槽被调用on_label_clicked时,它会自动(“qtmatically”)连接到从名为label的孩子发出的鼠标事件?

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

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

使用自动连接功能。