Uploaded image for project: 'Qt'
  1. Qt
  2. QTBUG-78726

QAbstractItemView does not honor dataChanged for Qt::ToolTipRole

    XMLWordPrintable

Details

    • All
    • c27123d7435e9451f3e44d9e823734e605279d0a (qt/qtbase/5.14)

    Description

      While trying to implement a delay load for tooltip images (since they're stored in a db and loading them all during the initial setup of the model would take too much time) I found out that dataChanged(... Qt::ToolTipRole) does not work as expected. This is due the fact that the QToolTip is handled differently from the rest of the view since it is triggered by QApplication / QEvent::ToolTip. Therefore we have to fake such an event inside QAIV:::dataChanged() in a similar way like this:

      bool viewportEvent(QEvent *event) override
      {
          bool ret = QTableView::viewportEvent(event);
          if (event->type() == QEvent::ToolTip) {
              if (!ret) {
                  QHelpEvent *he = static_cast<QHelpEvent*>(event);
                  m_toolTipPos = he->pos();
              }
              else
                  m_toolTipPos = QPoint();
          }
          return ret;
      }
      void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight,
                       const QVector<int> &roles) override
      {
          QTableView::dataChanged(topLeft, bottomRight, roles);
          if (!m_toolTipPos.isNull() && (roles.isEmpty() || roles.contains(Qt::ToolTipRole))) {
              if (viewport()->mapToGlobal(m_toolTipPos) != QCursor::pos()) {
                  m_toolTipPos = QPoint();
                  return;
              }
              const QModelIndex index = indexAt(m_toolTipPos);
              if (index.row() >= topLeft.row() && index.row() <= bottomRight.row() &&
                      index.column() >= topLeft.column() && index.column() <= bottomRight.column()) {
      
                  QHelpEvent he(QEvent::ToolTip, m_toolTipPos, viewport()->mapToGlobal(m_toolTipPos));                
                  QTableView::viewportEvent(&he);
                  m_toolTipPos = QPoint();
              }
          }
      }
      

      When the help event was not accepted we assume that it may come later during a dataChanged() signal. Therefore we remember the current cursor position (which should not cost that much, esp. since it's only stored when the event type matches) and once dataChanged() is triggered we check if the cursor moved. If this is not the case we fake a help event.

      I'm not sure if this behavior is wanted by Qt though.

       

      I've attached the complete testcase.

      Attachments

        No reviews matched the request. Check your Options in the drop-down menu of this sections header.

        Activity

          People

            qt.team.quick.subscriptions Qt Quick and Widgets Team
            chehrlic Christian Ehrlicher
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved:

              Gerrit Reviews

                There are no open Gerrit changes