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 Right Mouse Button selects

QTableView Right Mouse Button selects

Scheduled Pinned Locked Moved Unsolved General and Desktop
4 Posts 3 Posters 905 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.
  • P Offline
    P Offline
    Perdrix
    wrote on 3 May 2023, 00:05 last edited by
    #1

    I have a table view that is set up with ExtendedSelection and SelectRows.

    My problem is that right clicking on the table selects the row which I believe it should not do. Certainly for most similar controls of which I am aware, RMB only raises the context menu for the row in question. It is my firm belief that this behaviour is incorrect, but accept that the Qt development team may consider otherwise.

    This might seem trivial, but in the case in question, selection of a row results in actions which can potentially be quite time consuming, so I would very much like that RMB doesn't select.

    Is there any way to change the behaviour so that RMB only results in the customContextMenuRequested(const QPoint&) signal being emitted without sub-classing QTableView?

    If I need to subclass is it just the mousePressEvent handler I need to override?

    Thank you,
    David

    1 Reply Last reply
    0
    • C Offline
      C Offline
      CPPUIX
      wrote on 3 May 2023, 08:45 last edited by
      #2

      Hi!

      There's a work-around using an eventFilter, it basically works as a switch.

      • if RMB-> do no select
      • else -> select

      Here's how:

      #ifndef MYEVENTFILTER_H
      #define MYEVENTFILTER_H
      
      #include <QObject>
      #include <QDebug>
      #include <QEvent>
      #include <QMouseEvent>
      #include <QTableWidget>
      
      class myEventFilter : public QObject
      {
          Q_OBJECT
      
      public:
          myEventFilter (QObject *parent = nullptr) {}
      
      protected:
          bool eventFilter(QObject * obj, QEvent * event) override
          {
              //qDebug()<<obj<<event->type();
      
              if(event->type() == QEvent::MouseButtonPress)
              {
                  QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event);
      
                  //eventFilter is installed on table viewport, because mousePressEvents are not captured if the eventFilter is installed on the table directly
                  //The table could be accessed using viewport->parent()
                  QTableWidget *tableWidget = static_cast<QTableWidget*>(obj->parent());
      
                  //if it's an RMB event, disable selection
                  if(mouseEvent->button() == Qt::RightButton)
                  {
                      tableWidget->setSelectionMode(QAbstractItemView::NoSelection);
                  }
                  //else, get it back to normal
                  else
                  {
                      tableWidget->setSelectionMode(QAbstractItemView::ExtendedSelection);
                  }
              }
      
              return QObject::eventFilter(obj, event);
          }
      };
      
      #endif // MYEVENTFILTER_H
      
      

      I hope this helps.

      J 1 Reply Last reply 3 May 2023, 09:06
      0
      • C CPPUIX
        3 May 2023, 08:45

        Hi!

        There's a work-around using an eventFilter, it basically works as a switch.

        • if RMB-> do no select
        • else -> select

        Here's how:

        #ifndef MYEVENTFILTER_H
        #define MYEVENTFILTER_H
        
        #include <QObject>
        #include <QDebug>
        #include <QEvent>
        #include <QMouseEvent>
        #include <QTableWidget>
        
        class myEventFilter : public QObject
        {
            Q_OBJECT
        
        public:
            myEventFilter (QObject *parent = nullptr) {}
        
        protected:
            bool eventFilter(QObject * obj, QEvent * event) override
            {
                //qDebug()<<obj<<event->type();
        
                if(event->type() == QEvent::MouseButtonPress)
                {
                    QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event);
        
                    //eventFilter is installed on table viewport, because mousePressEvents are not captured if the eventFilter is installed on the table directly
                    //The table could be accessed using viewport->parent()
                    QTableWidget *tableWidget = static_cast<QTableWidget*>(obj->parent());
        
                    //if it's an RMB event, disable selection
                    if(mouseEvent->button() == Qt::RightButton)
                    {
                        tableWidget->setSelectionMode(QAbstractItemView::NoSelection);
                    }
                    //else, get it back to normal
                    else
                    {
                        tableWidget->setSelectionMode(QAbstractItemView::ExtendedSelection);
                    }
                }
        
                return QObject::eventFilter(obj, event);
            }
        };
        
        #endif // MYEVENTFILTER_H
        
        

        I hope this helps.

        J Offline
        J Offline
        JonB
        wrote on 3 May 2023, 09:06 last edited by JonB 5 Mar 2023, 09:12
        #3

        @Abderrahmene_Rayene
        This is a reasonable/clever solution. However, you leave the table in NoSelection state upon any right mouse click, and only restore it to previous mode on next (non-right) click. This may not be acceptable, e.g. after right-click the keyboard selection keys will no longer work

        Note that the above table assumes that the selection mode allows the operations. For instance, you cannot select items if the selection mode is QAbstractItemView::NoSelection.

        till next click is done.

        What we really want is only temporary disablement of selection on this click. Maybe your right-click evet filter could handle the content menu without passing the click onto the underlying system which will select? But I am not offering code for this :) Or, maybe when right-click after setting NoSelection one could do a QTimer::singleShot(0) (or other small number) which will restore the ExtendedSelection?

        C 1 Reply Last reply 3 May 2023, 09:44
        2
        • J JonB
          3 May 2023, 09:06

          @Abderrahmene_Rayene
          This is a reasonable/clever solution. However, you leave the table in NoSelection state upon any right mouse click, and only restore it to previous mode on next (non-right) click. This may not be acceptable, e.g. after right-click the keyboard selection keys will no longer work

          Note that the above table assumes that the selection mode allows the operations. For instance, you cannot select items if the selection mode is QAbstractItemView::NoSelection.

          till next click is done.

          What we really want is only temporary disablement of selection on this click. Maybe your right-click evet filter could handle the content menu without passing the click onto the underlying system which will select? But I am not offering code for this :) Or, maybe when right-click after setting NoSelection one could do a QTimer::singleShot(0) (or other small number) which will restore the ExtendedSelection?

          C Offline
          C Offline
          CPPUIX
          wrote on 3 May 2023, 09:44 last edited by CPPUIX 5 Mar 2023, 09:45
          #4

          @JonB Thank you! That is a serious problem which I had not noticed.

          and I made a quick fix , here it is:

          bool eventFilter(QObject * obj, QEvent * event) override
              {
                  qDebug()<<obj<<event->type();
          
                  if(event->type() == QEvent::ContextMenu)
                  {
                      QTableWidget *tableWidget = static_cast<QTableWidget*>(obj->parent());
                     //restore selection when contextMenu is called
                      tableWidget->setSelectionMode(QAbstractItemView::ExtendedSelection);
                  }
          
                  if(event->type() == QEvent::MouseButtonPress)
                  {
                      QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event);
          
                      //eventFilter is installed on table viewport, because mousePressEvents are not captured...
                      //...if the eventFilter is installed on the table directly
                      //The table could be accessed using viewport->parent()
                      QTableWidget *tableWidget = static_cast<QTableWidget*>(obj->parent());
          
                      //if it's an RMB event, disable selection
                      if(mouseEvent->button() == Qt::RightButton)
                      {
                          tableWidget->setSelectionMode(QAbstractItemView::NoSelection);
                      }
          
                  }
          
                  return QObject::eventFilter(obj, event);
              }
          

          Thank you for you feedback! any further feedback is appreciated!

          1 Reply Last reply
          2

          1/4

          3 May 2023, 00:05

          • Login

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