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. Mousehover entire row selection in QTableView
QtWS25 Last Chance

Mousehover entire row selection in QTableView

Scheduled Pinned Locked Moved General and Desktop
13 Posts 4 Posters 19.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.
  • N Offline
    N Offline
    neel2818
    wrote on last edited by
    #1

    Hi All,

    I want to know that how to do the row selection of QTableView on Mousehover event.
    I am able to do the itemhover selection in QTableView through stylesheet
    QTableView::item:hover{
    }

    But i am not able to do the entire row selection based on Mousehover event in QTableView.
    Can anyone tell me how to do that ?

    Thanks,
    Neel

    1 Reply Last reply
    0
    • N Offline
      N Offline
      neel2818
      wrote on last edited by
      #2

      I have written following delegate to display the mouse hover effect for item.

      @#include <QtGui>

      class Delegate : public QItemDelegate {
      public:
      Delegate(QObject *parent=0) : QItemDelegate(parent){}
      void paint ( QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index ) const {
      if(option.state & QStyle::State_MouseOver){
      painter->fillRect(option.rect, Qt::red);
      }
      QItemDelegate::paint(painter, option, index);
      }
      };

      int main(int argc, char **argv){
      QApplication app(argc, argv);
      QTableView tv;
      tv.viewport()->setAttribute(Qt::WA_Hover);
      QStandardItemModel model(8,8);
      tv.setModel(&model);
      tv.setItemDelegate(new Delegate(&tv));
      tv.show();
      return app.exec();
      }
      @

      I want the chage in above code that will select the entire row on mouse over.
      Any suggestion ?

      Thanks,
      Neel

      1 Reply Last reply
      0
      • S Offline
        S Offline
        stima_ua
        wrote on last edited by
        #3

        Delegate is responsible for the cell only, so you need to report to highlight the view that the entire row.
        You can do this in many ways ( for example )

        @
        class IView {
        public:
        virtual void setMouseOver(bool flag, const QModelIndex& index) = 0;
        }

        class MyView : public QTreeView, public IView {
        public:
        void setMouseOver(bool flag, const QModelIndex& index){
        int row = index.row();

                for ( int col = 0; i < columnCount(); col++ ) {
                    QStandartItem *item = model->item(row, col);
        
                    if (flag ) item->setBackground(QBrush(QCloro("red")));
                    else item->setBackground(QBrush(QCloro("red")));
                }
            }
        

        };

        class Delegate : public QSyledItemDelegate {
        IView *view;

        void paint ( QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index ) const {
                    bool isOver = option.state & QStyle::State_MouseOver;
        
                    view->setMouseOver(isOver, index);
        }
        

        };
        @

        or something like this

        @
        class Delegate : public QSyledItemDelegate {
        private:
        int hoveredRow;

           void paint ( QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index ) const {
                    if(option.state & QStyle::State_MouseOver) {
                             hoveredRow = index.row();
                    }
        
                    if ( hoveredRow == index.row(); ) {
                             ///
                    } else {
        
                    }
        
                    QSyledItemDelegate::paint(painter, option, index);
                     
            }
        

        };

        @

        1 Reply Last reply
        0
        • N Offline
          N Offline
          neel2818
          wrote on last edited by
          #4

          Thanks for your reply.

          As i have checked that in QTreeView we are able to see the mousehover effect of the row.
          But in QTableView we are not able to do row selection based on mousehover.

          Can you please give me some idea for how to do in QTableView ?

          1 Reply Last reply
          0
          • S Offline
            S Offline
            stima_ua
            wrote on last edited by
            #5

            hm...puts you code with table view here.

            1 Reply Last reply
            0
            • N Offline
              N Offline
              neel2818
              wrote on last edited by
              #6

              Above i have already given my code. I have tried with sample given by you it gives some compiler warning but i have resolved some of t and tried but not able to see the expected output.

              Can you please change my above code and give some inputs ?

              1 Reply Last reply
              0
              • S Offline
                S Offline
                stima_ua
                wrote on last edited by
                #7

                @
                #include <QtGui/QApplication>

                #include "TableView.h"
                #include <QStandardItem>
                #include <QStandardItemModel>

                int main(int argc, char *argv[])
                {
                QApplication a(argc, argv);

                QStandardItemModel model;
                
                for ( int col = 0; col < 3; col++ )
                {
                    QList<QStandardItem*> list;
                    for ( int row = 0; row < 5; row++ )
                    {
                        list.append(new QStandardItem);
                    }
                    model.appendColumn(list);
                }
                
                TableView view;
                
                view.setModel(&model);
                view.show();
                
                return a.exec&#40;&#41;;
                

                }
                @

                @
                #ifndef IVIEW_H
                #define IVIEW_H

                class IView {

                public:
                virtual void setMouseOver(const int) =0;
                };

                #endif // IVIEW_H

                #ifndef TABLEVIEW_H
                #define TABLEVIEW_H

                #include <QTableView>
                #include <QMouseEvent>
                #include <QStandardItem>

                #include "IView.h"
                #include "Delegate.h"

                class TableView : public QTableView, public IView {
                Q_OBJECT

                private:
                int currHovered;

                void mouseMoveEvent(QMouseEvent *event&#41;;
                void disableMouseOver();
                

                public:
                TableView(QWidget *parent = 0);

                void setMouseOver(const int);
                

                };

                #endif // TABLEVIEW_H

                #include "TableView.h"

                #include <QDebug>

                TableView::TableView(QWidget *parent) : QTableView(parent), currHovered(-1)
                {
                Delegate *delegate = new Delegate;
                delegate->setView(this);

                setItemDelegate(delegate);
                setMouseTracking(true);
                

                }

                void TableView::setMouseOver(const int row)
                {
                if ( row == currHovered) return;

                QStandardItemModel *_model = static_cast<QStandardItemModel*>(model());
                for ( int col = 0; col < _model->columnCount(); col++ )
                {
                    QStandardItem *item = _model->item(row, col);
                
                    item->setBackground(QBrush(QColor("red")));
                }
                
                if ( currHovered != -1 )
                {
                    disableMouseOver();
                }
                
                currHovered = row;
                

                }

                void TableView::disableMouseOver()
                {
                QStandardItemModel _model = static_cast<QStandardItemModel>(model());
                for ( int col = 0; col < _model->columnCount(); col++ )
                {
                QStandardItem *item = _model->item(currHovered, col);

                    item->setBackground(QBrush(QColor("white")));
                }
                

                }

                void TableView::mouseMoveEvent(QMouseEvent *event)
                {

                // TODO: you need know when mouse are not in table rect
                // then you need disable over
                
                QTableView::mouseMoveEvent(event);
                

                }
                @

                @
                #ifndef DELEGATE_H
                #define DELEGATE_H

                #include <QStyledItemDelegate>

                #include "IView.h"

                class Delegate : public QStyledItemDelegate {

                private:
                IView *view;

                public:
                void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;

                void setView(IView *view) { this->view = view; }
                

                };

                #endif // DELEGATE_H

                #include "Delegate.h"

                #include <QDebug>

                void Delegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
                {
                QStyleOptionViewItemV4 o = option;
                initStyleOption(&o, index);

                if ( o.state & QStyle::State_MouseOver )
                {
                    view->setMouseOver(index.row());
                }
                
                o.state &= ~QStyle::State_MouseOver;
                
                QStyledItemDelegate::paint(painter, o, index);
                

                }
                @

                p.s. I don't put this in the archive because it's very popular question.
                p.s.s about previous code it was just idea ... not a full implementation.
                p.s.s.s About this code, I'm sure it's not perfect (yes working, but not perfect), you can find a different idea or change the implementation.

                1 Reply Last reply
                0
                • N Offline
                  N Offline
                  neel2818
                  wrote on last edited by
                  #8

                  Thanks a lot stima ..... i have checked above given code and it is working as expected ..
                  Again thanks a lot ....

                  Thanks,
                  Neel

                  1 Reply Last reply
                  0
                  • N Offline
                    N Offline
                    neel2818
                    wrote on last edited by
                    #9

                    Hi Stima,

                    As mousehover is done but if i want selection and mousehover then how can we achieve this. As in Folder structure in windows 7 we can do selection (select one of the folder) and also mousehover we can do. How to achieve selection as well as mousehover ?

                    Thanks,
                    Neel

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

                      Hi everyone, I have a problem with if ( o.state & QStyle::State_MouseOver ) ...
                      When mouse leaves a widget, it is still true...
                      I mean if we take a look on source code of QTableView, we can find there that a method drawCell
                      and two lines
                      @ if (index == hover)
                      opt.state |= QStyle::State_MouseOver;
                      @

                      so it only sets the state up and not sets it down other hand, is it a BUG ?
                      And what can i do to not write a horrible scrap something like
                      @
                      void setHoveredIndex( QModelIndex index )
                      @

                      into soure of my delegate

                      1 Reply Last reply
                      0
                      • A Offline
                        A Offline
                        andre
                        wrote on last edited by
                        #11

                        The state is not kept between drawing calls, so that's not a problem. If your mouse leaving the widget doesn't trigger a redraw, then that seems to be the issue to me.

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

                          Hi Andre, thank you for quick reply.
                          So as you sad state is not keeping between drawing calls, but when mouse is leaving the widget it does not refresh the state, even if I call repaint after leaveEvent.
                          For example if we create a simple QComboBox, the behaviour on it's "popup-list" is absolutely the same, when mouse is leaving, it's still keeping last hovered index selected...

                          1 Reply Last reply
                          0
                          • A Offline
                            A Offline
                            andre
                            wrote on last edited by
                            #13

                            You are right, it is. Interesting issue then. I have no idea how the item view keeps the "hover" state for items that are not actually hovered anymore, and less so how to reset this state.

                            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