Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

QLabel click event using Qt?

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 ?!

like image 925
Nicholas Avatar asked Aug 14 '15 21:08

Nicholas


People also ask

Can QLabel respond to events?

There is no click signal for QLabel. If you need one then you need to reimplement its mousePressEvent or mouseReleaseEvent functions and then from it emit your custom signal. You can get the click position by QMouseEvent::pos ().


3 Answers

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"
like image 143
Kuba hasn't forgotten Monica Avatar answered Oct 06 '22 23:10

Kuba hasn't forgotten Monica


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)));
like image 28
kh25 Avatar answered Oct 06 '22 22:10

kh25


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

like image 39
Amol Saindane Avatar answered Oct 06 '22 23:10

Amol Saindane