3

I need to capture the double click event on a QPlainTextEdit that is inside a QDockWidget.

In my actual code I have installed an event filter in the QDockWidget, to handle resize operations, and in the QPlainTextEdit, to handle the double click events:

// Resize eventfilter
this->installEventFilter(this);
ui->myPlainTextEdit->installEventFilter(this);

But, although it works for the QDockWidget I am unable to catch the double click event for the QPlainTextEdit:

bool MyDockWidget::eventFilter(QObject *obj, QEvent *event) {
  if (event->type() == QEvent::Resize && obj == this) {
      QResizeEvent *resizeEvent = static_cast<QResizeEvent*>(event);
      qDebug("Dock Resized (New Size) - Width: %d Height: %d",
             resizeEvent->size().width(),
             resizeEvent->size().height());

  } else if (obj == ui->myPlainTextEdit && event->type() == QMouseEvent::MouseButtonDblClick) {
      qDebug() << "Double click";
  }
  return QWidget::eventFilter(obj, event);
}

With this code the message "Double click" is never shown. Any idea what is wrong with the code?

hteso
  • 55
  • 2
  • 7
  • What happens if you remove the first `if`? Check if you receive any events about `ui->myPlainTextEdit` at all. Also, why does your object install an event filter on itself? This might be a problem. Just override `event()` instead. – sashoalm Jul 23 '15 at 08:06
  • I checked and I receive events about the QPlainTextEdit, it is the double click that doesn't shows up. Any example of "overriding `event()`? – hteso Jul 23 '15 at 08:14
  • Yes, see http://doc.qt.io/qt-5/qobject.html#event - this is the documentation. As for sample code, just google it. – sashoalm Jul 23 '15 at 08:19
  • Can you tell me what is the output you get by adding the below line of code and double clicking the center of the TextEdit!! `if (event->type() == QEvent::MouseButtonDblClick){qDebug() << obj->objectName();}` – techneaz Jul 23 '15 at 08:29
  • No debug output if I double click on the QPlainTextEdit, but if I double click on the QDockWidget it shows the dock widget name :) May be is due to QPlainTextEdit using `mouseDoubleClickEvent` instead of `MouseButtonDblClick` but I cant find how to use the first on the `if` as it is not part of `QEvent` http://doc.qt.io/qt-5/qplaintextedit.html#mouseDoubleClickEvent – hteso Jul 23 '15 at 08:34

1 Answers1

7
  1. QTextEdit inherits a QScrollView and when you double click on the viewport of the QTextEdit, the viewport receives the double click event. You can cross check your current code by double clicking on the edges of the text edit. It will capture the event.

  2. To solve this, add the event filter to the view port in addition to the current event filters you have installed as shown below:

    ui->myPlainTextEdit->viewport()->installEventFilter(this);
    
  3. Next, capture the event using this if statement:

       if ((obj == ui->myPlainTextEdit||obj==ui->myPlainTextEdit->viewport()) &&   
            event->type() == QEvent::MouseButtonDblClick) 
       {
            qDebug() << "Double click"<<obj->objectName();
       }
    
  4. You can capture the click position using QMouseEvent:

    QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event);
    qDebug()<<QString("Click location: (%1,%2)").arg(mouseEvent->x()).arg(mouseEvent->y());
    
Philip Allgaier
  • 3,505
  • 2
  • 26
  • 53
techneaz
  • 998
  • 6
  • 9
  • Thanks, that works perfect! Now I need to translate the event coordinates to a cursor position within the `QPlainTextEdit`. Unfortunately there is no `event->x` or `event->pos(`). Any idea how to translate this event to a line within the `QPlainTextEdit`? – hteso Jul 23 '15 at 09:28
  • 1
    Good advice about viewport. I can almost see myself spending hours trying to catch this event via `QPlainTextEdit` in a parallel universe. – Violet Giraffe Jul 21 '16 at 20:24