Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. QTableView/QStyledItemDelegate: Mark an *entire* row hovered over with the mouse
QtWS25 Last Chance

QTableView/QStyledItemDelegate: Mark an *entire* row hovered over with the mouse

Scheduled Pinned Locked Moved General and Desktop
13 Posts 2 Posters 8.3k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • T Offline
    T Offline
    thEClaw
    wrote on last edited by
    #2

    After getting quite annoyed with QTableView::paintEvent due to it claiming to be a function I could reimplement however I need (which is not the case since the original makes heavy use of QTableViewPrivate), I went back to the QStyledItemDelegate to try another idea. This is what I came up with:

    @void EnhancedItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
    {
    //...
    bool hovered = false;
    if(opt.state & QStyle::State_MouseOver)
    hovered = true;
    else
    {
    QAbstractItemView *t = qobject_cast<QAbstractItemView *>(this->parent());
    if(t)
    {
    QModelIndex hover = t->indexAt(t->viewport()->mapFromGlobal(QCursor::pos()));
    if(hover.row() == index.row())
    {
    hovered = true;
    t->update(hover);//this is important, otherwise the result is very messy
    }
    }
    }

    //...
    
    if(hovered)
    {
        QBrush background = opt.palette.highlight();
        QColor backColor = opt.palette.highlight().color();
        backColor.setAlpha(100);
        background.setColor(backColor);
    
        painter->fillRect(opt.rect, background);
        painter->setPen(opt.palette.text().color());
    }
    

    }@
    The order of coloring the background and drawing the other things is important (things may be overlayed with the background, if done wrong), but this seems to be a pretty solid solution overall. At least I have not found any drawbacks yet. Have to conduct some more testing, though.

    1 Reply Last reply
    0
    • SGaistS Offline
      SGaistS Offline
      SGaist
      Lifetime Qt Champion
      wrote on last edited by
      #3

      Hi,

      Your solution doesn't sound bad, you might however simplify things by creating a copy of the options and update state with QStyle::State_MouseOver, you can then let the base implementation do the painting

      Interested in AI ? www.idiap.ch
      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

      1 Reply Last reply
      0
      • T Offline
        T Offline
        thEClaw
        wrote on last edited by
        #4

        I need full control over the paint-function anyway, and I can't completely follow your thoughts. Are you talking about a fake MouseOver state I should trigger? The ItemDelegate only ever draws a single cell, as far as I know. And I wasn't able to manipulate the calling of that drawing, since it is done in non-reimplementable QTableView-functions.

        The solution wasn't too good, by the way. I had to make some small adjustments to it. It's still roughly the same, though.

        1 Reply Last reply
        0
        • SGaistS Offline
          SGaistS Offline
          SGaist
          Lifetime Qt Champion
          wrote on last edited by
          #5

          No, I was thinking: just add the QStyle::State_MouseOver flag to the option.state flags when needed.

          Interested in AI ? www.idiap.ch
          Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

          1 Reply Last reply
          0
          • T Offline
            T Offline
            thEClaw
            wrote on last edited by
            #6

            Well, since I am doing all the drawing by hand, and I still need to draw the MouseOver-state anyway (the item delegate doesn't have an option for that, right?), I am not sure if I would gain anything by that.

            1 Reply Last reply
            0
            • SGaistS Offline
              SGaistS Offline
              SGaist
              Lifetime Qt Champion
              wrote on last edited by
              #7

              Aren't you just painting a focus rectangle over the each item of the row ?

              Interested in AI ? www.idiap.ch
              Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

              1 Reply Last reply
              0
              • T Offline
                T Offline
                thEClaw
                wrote on last edited by
                #8

                You see what I'm painting in the code above (last block). Technically it doesn't have anything to do with focus. Would the item delegate be able to highlight the/a focused cell via its standard implementation of paint()?

                1 Reply Last reply
                0
                • SGaistS Offline
                  SGaistS Offline
                  SGaist
                  Lifetime Qt Champion
                  wrote on last edited by
                  #9

                  Sorry, my bad, I've mixed hovered and selected. But since you are painting the hovered state like the selected, the technic I proposed earlier (using an updated copy of the option) is still usable, you would only need to add the QStyle::State_Selected and then call QAbstractItemDelegate::paint with this new option. It should handle the drawing for you properly

                  Interested in AI ? www.idiap.ch
                  Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                  1 Reply Last reply
                  0
                  • T Offline
                    T Offline
                    thEClaw
                    wrote on last edited by
                    #10

                    But at which point am I supposed to set that option? "Copying" it would be meaningless inside the item delegates paint() function, since that one only draws a single cell, and I have to explicitly check for the hovered-state anyway.

                    If you are talking about manipulating the option before calling QStyledItemDelegate::paint() in my custom implementation, that's not possible. As I said: I completely rewrote that function, without any calls to the base class being made.

                    1 Reply Last reply
                    0
                    • SGaistS Offline
                      SGaistS Offline
                      SGaist
                      Lifetime Qt Champion
                      wrote on last edited by
                      #11

                      Ok, it wasn't clear that all the painting was custom. Then no need for my idea.

                      I just thought about something that may be of interest, what about QRubberBand ?

                      Interested in AI ? www.idiap.ch
                      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                      1 Reply Last reply
                      0
                      • T Offline
                        T Offline
                        thEClaw
                        wrote on last edited by
                        #12

                        That sounds interesting indeed. I have never used a QRubberBand before - what would happen to the text in the tableview? Would it still be readable?

                        When doing this in the item delegate, I can paint the background of the text before writing the text, so the hover-marking is cleanly realized (but it still has some minor flaws). An overlayed widget might wash out the text.

                        1 Reply Last reply
                        0
                        • SGaistS Offline
                          SGaistS Offline
                          SGaist
                          Lifetime Qt Champion
                          wrote on last edited by
                          #13

                          IIRC, the QRubberBand is translucent so you would only have to handle its size and position. You could do it directly in a custom view and wouldn't need your special delegate

                          Interested in AI ? www.idiap.ch
                          Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                          1 Reply Last reply
                          0

                          • Login

                          • Login or register to search.
                          • First post
                            Last post
                          0
                          • Categories
                          • Recent
                          • Tags
                          • Popular
                          • Users
                          • Groups
                          • Search
                          • Get Qt Extensions
                          • Unsolved