使用Qt如何实现QLabel的点击事件?

13

我是Qt的新手,有一个问题。

我有QLabelQLineEdit对象,当单击QLabel文本时,我想将此文本设置在QLineEdit中。

另外我已经阅读到QLabel没有点击信号。

你能解释一下我该如何做,并为我编写代码吗?!


你需要子类化QLabel:请看这里https://wiki.qt.io/Clickable_QLabel - gengisdave
我会在 mouseReleaseEvent 上发出信号,而不是在 mousePressEvent 上。只有当鼠标释放时,点击才算完成。 - Bowdzone
1
由于我遇到了与LCD触摸屏和点击事件类似的问题,这里分享一些随机想法...使用QButton可能比使用QLabel更容易,因为按钮已经知道如何处理点击/触摸事件。将按钮设置为平面或2D样式,没有边框。然后像往常一样处理按钮的点击/触摸事件即可。 - jww
4个回答

8

要么将另一种类型的QWidget(例如一个特定的QPushButton)样式化为QLabel并使用其clicked()信号,要么继承QLabel自己并发射您自己的clicked()信号。

参考此示例:https://wiki.qt.io/Clickable_QLabel

如果选择后一种选项,则可以通过信号传递文本。然后按以下方式连接QLabel和QLineEdit之间所需的信号/槽:

QObject::connect(&label, SIGNAL(clicked(const QString& text)),
                 &lineEdit, SLOT(setText(const QString& text)));

7
一种简单的实现方法,不需要任何子类化,就是创建一个信号源,监控某个对象上的事件并发出相关信号:
// 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);
  }
};
emit 关键字是一个空宏,Qt 将其定义如下:
#define emit

这只是作为文档辅助前缀供人使用,编译器和moc会忽略它。作为文档辅助,它的意思是:以下方法调用是一个信号发射。信号只是一些方法,其实现是由moc为您生成的 - 这就是为什么我们必须在下面包含#include "main.moc"以包含此文件中对象类别的所有实现的原因。信号本身没有任何特殊或神奇之处。在此示例中,您可以在构建文件夹中查找名为main.moc的文件,并查看void MouseButtonSignaler::mouseButtonEvent( .. )的实现(定义)。

然后,您可以将这样的信号器安装在任意数量的小部件上,例如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"

2

您需要创建一个自定义标签类,该类将继承QLabel。然后,您可以使用MouseButtonRelease事件来检查单击标签,并emit您的自定义信号,并在一个SLOT中捕获。

您的.h文件如下:

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    
};

在你的 .cpp 文件中,你的构造函数将会像下面这样连接信号和槽:

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

下面将实现剩余的event方法和SLOT方法:

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";
}

要更改QLineEdit上的文本,您需要创建一个自定义类,并与自定义QLabel类共享对象指针。请在此链接中检查测试代码。


好的,但是当我点击自定义标签文本时,代码在哪里?它会设置到QLineEdit对象中吗? - Nicholas
@Nicholas:你需要创建QLineEdit对象并将指针与QLable共享,无论如何我已经制作了一个快速项目。请在答案中检查链接。 - Amol Saindane
还有一个问题:为什么需要使用emit信号,当我们可以使用Qt::connect连接时?emit关键字是什么意思,何时使用它? - Nicholas
有没有可能提供一个Python示例?https://wiki.qt.io/Clickable_QLabel上的示例还使用了C++,我很难找到正确的Python实现。 - Cirrocumulus
@Cirrocumulus 我认为你不能在Python中子类化C++类,因为那里只有一个包装库PyQt,对吧?事件过滤器或qpushbutton setStyleSheet是方法。 - Swift - Friday Pie
显示剩余2条评论

0
在上面的例子中,头文件需要 Q_OBJECT:
class YourLabelClass : public QLabel{
Q_OBJECT
signals:

你的回答可以通过提供更多支持信息来改进。请编辑以添加进一步的细节,例如引用或文档,以便他人可以确认你的答案是正确的。您可以在帮助中心中找到有关如何编写良好答案的更多信息。 - Community

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接