0

I want to make a QLabel clickable and followed this "how-to". I was not sure how to get this piece of code into my GUI (I am quite newbie to qt). What I did was:

  1. I created a new class (just copy/paste of ClickableLabel from the link, but I changed the signal to clicked(QMouseEvent* event))
  2. I added a QLabel to my GUI and "promoted" it to a ClickableLable
  3. I connected the signal to a slot of my main window where I std::cout some stuff:

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

It seems to work. The problem is that each time I click on the label the mousePressedEvent gets called twice. I also tried mouseReleasedEvent but its the same.

Any ideas what could go wrong?

EDIT: Here is my modified 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);
}

The couts in the in the above method I added only later and realized that the mouseReleaseEvent is actually only called once. But when I connect the clicked to a slot of my mainwindow, this slot recieves the event twice.

Then I removed the connect statement and to my surprise the signal is still emited and recieved (only once). I am a bit puzzled how this works, because I am pretty sure that I do not mistakenly have a connect anywhere in the code.

My label is working, but I would like to understand what is going on. Actually I am not 100% sure anymore that I didn't use some Qt creator feature make the connection. However, I have no idea where to find such connections. For example, I have a QButton on the same main window. In the gui editor I right clicked it and then "show slots"->"clicked()"->"OK" and automatically a method called on_pushButton_clicked() is created, but I have no idea, where this is called / how the button's signal is connected to this method. On the other hand, I do not get the MyClickableLabel::clicked(QMouseEvent*) listed in the list of slots for my label, thus I don't think I created the connection this way...

463035818_is_not_an_ai
  • 109,796
  • 11
  • 89
  • 185
  • Not sure that it is related but strange they are not calling QLabel::mousePressEvent(event); in ClickableLabel::mousePressEvent before doing other actions (emitting signal in your case) – demonplus May 01 '15 at 11:24
  • Can you show us your reimplementation of `mousePressEvent()`? – jonspaceharper May 01 '15 at 13:08
  • @JonHarper Yes I can – 463035818_is_not_an_ai May 02 '15 at 07:18
  • Have you tried testing the signal without emitting `QMouseEvent *`? P.S. Regarding auto connecting signals-to-slots: only a private slot following the pattern "_q_on_[signal_name]" (IIRC) will connect automatically. There's more to this, but basically, slots don't connect themselves unless you're very specific about it. – jonspaceharper May 02 '15 at 12:14
  • @JonHarper The mainwinow`s slot is indeed private. I started with a new project (Qt Createor 3.3.2/ Qt 5.4.1) and this time I did not connect "manually" at all and the connection is made again, if the slot just hast the right name and signature. I still did not find any official documentation on this feature, but I found [this post](http://qtway.blogspot.de/2010/08/automatic-connections-using-qt-signals.html). – 463035818_is_not_an_ai May 03 '15 at 07:28
  • @tobi303: great info. Thank you. If you make the slot protected, this should no longer be an issue, or you can keep it private for the autoconnect. I'm definitely interested in using this. – jonspaceharper May 03 '15 at 14:38
  • @JonHarper Yes, it is pretty cool. I just do not like that the connection does not show up explicitly in my code, which can cause some confusion ;) – 463035818_is_not_an_ai May 04 '15 at 08:17

1 Answers1

0

I could fix it, but I do not really understand what is going on...

It was not the mousePressEvent that was fired twice, but my on_label_clicked slot recieved the event twice.

I removed the connect statement and now the on_label_clicked is called only once per click. It seems like, there is something going on under the hood. Maybe when the slot is called on_label_clicked it gets automatically ("qtmatically") connected to the mouse events emmited from the child called label ?

EDIT: Still didnt find the official docs, but this blog explains it quite nicely. In summary, one just needs to use the naming convention for the slot

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

to make use of the auto connect feature.

463035818_is_not_an_ai
  • 109,796
  • 11
  • 89
  • 185
  • There's no automatic connecting of slots. My guess would be that your connect() got called twice. If you connect the same signal twice to the same slot, the slot will we called twice when the signal is emitted once. – Frank Osterfeld May 01 '15 at 15:44
  • 1
    If @FrankOsterfeld is right, you could use [Qt::UniqueConnection](http://doc.qt.io/qt-5/qt.html#ConnectionType-enum) to prevent it. – Maxito May 01 '15 at 21:39
  • I saw automatic connection when your slot is named on_NAME_SIGNAL just like the designer names them. @tobi303 Try removing on_ , you should not get any signals anymore. Just look at the generated ui_*.h file. You should once see a connect there and once not. – fassl May 11 '15 at 23:09
  • @FrankOsterfeld quite old q/a, but you might be interested in the blog I found – 463035818_is_not_an_ai Mar 22 '17 at 20:26