【问题标题】:Handle mouse events in QListView在 QListView 中处理鼠标事件
【发布时间】:2025-12-13 06:25:01
【问题描述】:

Dialog 分别显示文件夹(在 treeView 中)和 文件(在 listView 中)。在 listView 中,doubleClick 信号由 Qt 创建的插槽处理,而我使用 Designer 和要实现的适当插槽。问题是我无法处理RIGHT MOUSE click。有解决办法吗?

附: 我已经搜索了一段时间来解决这个问题,似乎继承 QListView 和覆盖解决了这个问题。但就我而言,我已经使用 Designer 填充了 Qt 的标准 QListView

【问题讨论】:

    标签: qt qt4 qt5 qt4.8


    【解决方案1】:

    在我的例子中,当用户右键单击 QListView 中的一行时,我开始尝试捕获鼠标事件,但它们从未通过。然而,我真正想做的只是弹出一个上下文菜单,结果发现 contextMenuEvent 确实通过了!所以我不必继承 QListView,只需向包含 QListView 的小部件添加一个 contextMenuEvent()。

    这是 Qt3,所以你的里程肯定会有所不同。

    【讨论】:

      【解决方案2】:

      在这种情况下,您可以使用事件过滤器:

      bool MainWindow::eventFilter(QObject *obj, QEvent *event)
      {
      
          if (obj == ui->listView->viewport() && event->type() == QEvent::MouseButtonDblClick)
          {
              QMouseEvent *ev = static_cast<QMouseEvent *>(event);
              if (ev->buttons() & Qt::RightButton)
              {
                  qDebug()<< "double clicked" << ev->pos();
                  qDebug()<<  ui->listView->indexAt(ev->pos()).data();
              }
          }
          return QObject::eventFilter(obj, event);
      }
      

      要使用eventFilter,您还应该:

      protected:
          bool eventFilter(QObject *obj, QEvent *event);//in header
      

      qApp->installEventFilter(this);//in constructor
      

      可能会增加您的问题。如果您想在用户单击鼠标左键或右键时做不同的事情,您应该在过滤器中处理最少和右键单击,没有 doubleClick 信号(因为它在两种情况下都会发出信号)并且您的代码可以是这样的:

      QMouseEvent *ev = static_cast<QMouseEvent *>(event);
      if (ev->buttons() & Qt::RightButton)
      {
          qDebug()<< "RightButton double clicked";
          //do something
      }
      if (ev->buttons() & Qt::LeftButton)
      {
          qDebug()<< "LeftButton double clicked";
          //do something
      }
      

      【讨论】:

      • 感谢您的回答!这在 Dialog 中是否有效,因为我使用 QDialog 创建了项目?抱歉问了个小问题?
      • @elgolondrino 是的,只写 Dialog 而不是 MAinWindow,但为什么不能只使用 doubleClicked 信号?当用户单击鼠标右键或鼠标左键时,您想要不同的反应吗? void MainWindow::on_listView_doubleClicked(const QModelIndex &amp;index){qDebug() &lt;&lt; index.data();}
      • 因为我已经使用该插槽来打开listView 中的文件,并且不想打开right-double click 中的文件,而是仅在left 一个中打开文件! :)
      • 一个问题你能告诉我为什么我想在覆盖的方法中返回QObject::eventFilter(obj, event)
      • @elgolondrino 最好的答案在文档中:qt-project.org/doc/qt-4.8/eventsandfilters.html#event-filters