12

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

jww
  • 97,681
  • 90
  • 411
  • 885
Nicholas
  • 147
  • 1
  • 2
  • 6
  • you have to subclass QLabel : look here https://wiki.qt.io/Clickable_QLabel – gengisdave Aug 14 '15 at 21:36
  • I would emit the signal on `mouseReleaseEvent` and not on `mousePressEvent`. The click is not complete until the mouse is released. – Bowdzone Aug 14 '15 at 21:53
  • 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. – jww Dec 18 '19 at 21:25

4 Answers4

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)));
kh25
  • 1,238
  • 1
  • 15
  • 33
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"
Kuba hasn't forgotten Monica
  • 95,931
  • 16
  • 151
  • 313
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

Amol Saindane
  • 1,568
  • 10
  • 19
  • Ok. But where is code , when I clicked on custom created label text, it sets to QLineEdit object ? – Nicholas Aug 15 '15 at 07:06
  • @Nicholas : You need to create QLineEdit object and share that pointer with QLable, anyways I made a quick project. Please check link in answer – Amol Saindane Aug 15 '15 at 08:48
  • And one question please: why need emit signal, when we can connect using Qt::connect ? What does emit keyword and when to use it ? – Nicholas Aug 15 '15 at 10:03
  • This link will explain you signal and slot : http://doc.qt.io/qt-4.8/signalsandslots.html – Amol Saindane Aug 15 '15 at 18:38
  • 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. – Toby Speight Aug 17 '15 at 14:04
  • Any chance to get an example in Python? The example at https://wiki.qt.io/Clickable_QLabel also uses C++ and I'm having a hard time finding the correct Python implementation. – Cirrocumulus Sep 26 '20 at 20:34
  • @Cirrocumulus 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 way – Swift - Friday Pie Oct 13 '21 at 14:40
0

In the above example the header needs Q_OBJECT:

class YourLabelClass : public QLabel{

Q_OBJECT

signals:

  • 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](/help/how-to-answer). – Community Feb 09 '22 at 09:25