【问题标题】:QLabel click event using Qt?使用Qt的QLabel点击事件?
【发布时间】:2015-08-14 21:31:28
【问题描述】:

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

我有QLabelQLineEdit对象,当点击QLabel文本时,我想在QLineEdit中设置这个文本。

我还读到QLabel 没有点击信号。

你能解释一下我该怎么做并为我写代码吗?!

【问题讨论】:

  • 你必须继承 QLabel :看这里wiki.qt.io/Clickable_QLabel
  • 我会在mouseReleaseEvent而不是mousePressEvent上发出信号。直到松开鼠标,点击才完成。
  • 一些随机的想法,因为我在 LCD 触摸屏和点击事件方面遇到了类似的问题......使用 QButton 而不是 QLabel 可能更容易,因为按钮已经知道点击/点击事件。将按钮设置为平面或 2D 无边框。然后,像往常一样处理按钮的点击/点击事件。

标签: qt signals-slots qlabel


【解决方案1】:

要么将另一种类型的 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)));

【讨论】:

    【解决方案2】:

    实现这一点的一种简单方法,不需要任何子类化,是一个信号源,它监视某个对象上的事件并发出相关信号:

    // 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" 中包含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"
    

    【讨论】:

      【解决方案3】:

      您需要创建一个自定义标签类,它将继承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 类共享对象指针。请在this link查看测试代码

      【讨论】:

      • 好的。但是代码在哪里,当我点击自定义创建的标签文本时,它设置为 QLineEdit 对象?
      • @Nicholas :您需要创建 QLineEdit 对象并与 QLable 共享该指针,无论如何我做了一个快速项目。请检查答案中的链接
      • 还有一个问题:当我们可以使用 Qt::connect 连接时,为什么需要发出信号?什么是 emit 关键字以及何时使用它?
      • 这个链接会解释你的信号和槽:doc.qt.io/qt-4.8/signalsandslots.html
      • 如果让myLabelClicked() 信号传递QString 参数,则可以简单地连接到QLineEditsetText() 插槽。无需传递指针。
      【解决方案4】:

      在上面的例子中,header需要Q_OBJECT:

      class YourLabelClass : public QLabel{

      Q_OBJECT

      信号:

      【讨论】:

      • 您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-01-16
      • 2017-12-10
      • 2019-08-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多