QLabel click event using Qt?
Asked Answered
H

4

13

I'm new in Qt and have a question.

I have QLabel and QLineEdit objects, and when QLabel text is clicked on, I want to set this text in QLineEdit.

Also I have read that QLabel has not clicked signal.

Can you explain how can I do this and write code for me ?!

Holmgren answered 14/8, 2015 at 21:31 Comment(3)
you have to subclass QLabel : look here wiki.qt.io/Clickable_QLabelIdealist
I would emit the signal on mouseReleaseEvent and not on mousePressEvent. The click is not complete until the mouse is released.Adam
Some random thoughts since I am having a similar problem with a LCD touch screen and tap events... It might be easier to use a QButton rather than a QLabel since the button already knows a click/tap event. Set the button to flat or 2D without a border. Then, handle the button's click/tap event as usual.Inspection
D
8

Either style another type of QWidget such as a specific QPushButton to look like a QLabel and use its clicked() signal or inherit QLabel yourself and emit your own clicked() signal.

See this example: https://wiki.qt.io/Clickable_QLabel

If you choose the latter option you can pass the text in the signal. Then connect the necessary signals/slots up between the QLabel and the QLineEdit like so:

QObject::connect(&label, SIGNAL(clicked(const QString& text)),
                 &lineEdit, SLOT(setText(const QString& text)));
Dulcia answered 17/8, 2015 at 13:29 Comment(0)
O
7

A simple way to accomplish that, without a need for any subclassing, is a signal source that monitors the events on some object and emits relevant signals:

// main.cpp - this is a single-file example
#include <QtWidgets>

class MouseButtonSignaler : public QObject {
  Q_OBJECT
  bool eventFilter(QObject * obj, QEvent * ev) Q_DECL_OVERRIDE {
    if ((ev->type() == QEvent::MouseButtonPress
        || ev->type() == QEvent::MouseButtonRelease
        || ev->type() == QEvent::MouseButtonDblClick)
        && obj->isWidgetType())
      emit mouseButtonEvent(static_cast<QWidget*>(obj), 
                            static_cast<QMouseEvent*>(ev));
    return false;
  }
public:
  Q_SIGNAL void mouseButtonEvent(QWidget *, QMouseEvent *);
  MouseButtonSignaler(QObject * parent = 0) : QObject(parent) {}
  void installOn(QWidget * widget) {
    widget->installEventFilter(this);
  }
};

The emit keyword is an empty macro, Qt defines it as follows:

#define emit

It is for use by humans as a documentation aid prefix only, the compiler and moc ignore it. As a documentation aid, it means: the following method call is a signal emission. The signals are simply methods whose implementation is generated for you by moc - that's why we have to #include "main.moc" below to include all the implementations that moc has generated for the object class(es) in this file. There's otherwise nothing special or magical to a signal. In this example, you could look in the build folder for a file called main.moc and see the implementation (definition) of void MouseButtonSignaler::mouseButtonEvent( .. ).

You can then install such a signaler on any number of widgets, such as a QLabel:

int main(int argc, char ** argv) {
  QApplication app(argc, argv);
  MouseButtonSignaler signaler;
  QWidget w;
  QVBoxLayout layout(&w);
  QLabel label("text");
  QLineEdit edit;
  layout.addWidget(&label);
  layout.addWidget(&edit);
  signaler.installOn(&label);
  QObject::connect(&signaler, &MouseButtonSignaler::mouseButtonEvent, 
    [&label, &edit](QWidget*, QMouseEvent * event) {
    if (event->type() == QEvent::MouseButtonPress)
      edit.setText(label.text());
  });
  w.show();
  return app.exec();
}

#include "main.moc"
Outline answered 15/8, 2015 at 16:55 Comment(0)
S
2

You need to create one Custom Label class, which will inherit QLabel. Then you can use MouseButtonRelease event to check clicking of Label and emit your custom signal and catch in one SLOT.

Your .h file will be as below:

class YourLabelClass : public QLabel{

signals:
    void myLabelClicked();       // Signal to emit 

public slots:
    void slotLabelClicked();    // Slot which will consume signal 

protected:
    bool event(QEvent *myEvent); // This method will give all kind of events on Label Widget    
};

In your .cpp file, your constructor will connect signal & slot as below :

YourLabelClass :: YourLabelClass(QWidget* parent) : QLabel(parent) {
   connect(this, SIGNAL(myLabelClicked()), this, SLOT(slotLabelClicked()));
}

Remaining event method and SLOT method will be implemented as below:

bool YourLabelClass :: event(QEvent *myEvent)  
{
    switch(myEvent->type())
    {        
        case(QEvent :: MouseButtonRelease):   // Identify Mouse press Event
        {
            qDebug() << "Got Mouse Event";
            emit myLabelClicked();
            break;
        }
    }
    return QWidget::event(myEvent);
}

void YourLabelClass  :: slotLabelClicked()   // Implementation of Slot which will consume signal
{
    qDebug() << "Clicked Label";
}

For Changing a Text on QLineEdit, you need to create a Custom Class and share object pointer with custom QLabel Class. Please check test code at this link

Svensen answered 15/8, 2015 at 6:5 Comment(7)
Ok. But where is code , when I clicked on custom created label text, it sets to QLineEdit object ?Holmgren
@Holmgren : You need to create QLineEdit object and share that pointer with QLable, anyways I made a quick project. Please check link in answerSvensen
And one question please: why need emit signal, when we can connect using Qt::connect ? What does emit keyword and when to use it ?Holmgren
This link will explain you signal and slot : doc.qt.io/qt-4.8/signalsandslots.htmlSvensen
If you make the myLabelClicked() signal pass a QString parameter, that can simply be connected to the setText() slot of the QLineEdit. No need to pass a pointer.Inland
Any chance to get an example in Python? The example at wiki.qt.io/Clickable_QLabel also uses C++ and I'm having a hard time finding the correct Python implementation.Radarman
@Radarman I don't think you can subclass C++ class in Python because ther you just have a wrapper library PyQt, can you? event filters or qpushbutton setStyleSheet are the wayZymase
I
1

In the above example the header needs Q_OBJECT:

class YourLabelClass : public QLabel{

Q_OBJECT

signals:

Inanition answered 8/2, 2022 at 23:59 Comment(1)
Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.Piste

© 2022 - 2024 — McMap. All rights reserved.