Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

QTableView navigation with TAB



  • Hello, when hitting TAB key in a QTableView, cursor goes toward right side. I would like the cursor to move down instead of right. I tried to build a code which works not so bad but when I have cells which are spanned, cursor disappears. Do you have an idea to improve this behavior ? Thanks in advance !

    void customTableView::searchNextIndex() {
        int row = currentIndex().row();
        int col = currentIndex().column();
        // Following cell
        row++;
        if(row>=model()->rowCount()) {
            row = 0;
            col++;
        }
        if(col>=model()->columnCount()) {
            col = 0;
        }
        // Loop while following cell is not selectable (or a complete loop has been done)
        unsigned int counter = 0;
        unsigned int maxCounter = model()->rowCount()*model()->columnCount()-1;
        Qt::ItemFlags currentFlag = model()->flags(model()->index(row, col));
        while(counter<maxCounter && !currentFlag.testFlag(Qt::ItemIsSelectable)) {
            row++;
            if(row>=model()->rowCount()) {
                row = 0;
                col++;
            }
            if(col>=model()->columnCount()) {
                col = 0;
            }
            currentFlag = model()->flags(model()->index(row, col));
            counter++;
        }
        setCurrentIndex(model()->index(row, col));
        scrollTo(model()->index(row, col));
    }
    


  • class CustomTableView : public QTableView{
        Q_OBJECT
        Q_DISABLE_COPY(CustomTableView)
    public:
        explicit CustomTableView(QWidget *parent = Q_NULLPTR)
            :QTableView(parent)
        {}
    protected:
        void keyPressEvent(QKeyEvent *event) Q_DECL_OVERRIDE
        {
            if(event->key() == Qt::Key_Tab || event->key() == Qt::Key_Backtab){
                QKeyEvent newEvent(event->type(), event->key() == Qt::Key_Tab ? Qt::Key_Down : Qt::Key_Up, event->modifiers(), event->nativeScanCode(), event->nativeModifiers(), event->text(), event->isAutoRepeat(), event->count());
                event->accept();
                QTableView::keyPressEvent(&newEvent);
                return;
            }
            QTableView::keyPressEvent(event);
        }
    };
    


  • Thanks vRonin, this is a smart and efficient way to do it. The only missing part is that when I am at the end (last row) of the table, I would like to go back to the first line in the following column.

    For example, let's consider (x = borders) :
    xxxxxxxxxxxxxxxxxxxxxxx
    x............................................x
    xxxxxxxxxxxxxxxxxxxxxxx
    x............x.................x...........x
    xxxxxxxxxxxxxxxxxxxxxxx

    I would like to highlight col 0, row 0 => TAB => col 0, row 1 => TAB => col 1, row 0 but since spanned, corresponding to range col 0, row 0 to col 1, row 0 => TAB => col 1, row 1 => TAB => col 2, row 0 to col 2, row 0 (spanned cell) => TAB => col2, row 1 => col 0, row 0...

    I have tested something like :

    void keyPressEvent(QKeyEvent *event) Q_DECL_OVERRIDE
        {
            else if(event->key()==Qt::Key_Tab) {
                if(currentIndex().row()>=model()->rowCount()-1) {
                    if(currentIndex().column()>=model()->columnCount()-1) {
                        setCurrentIndex(model()->index(0, 0));
                    }
                    else {
                        QKeyEvent newEvent(event->type(), Qt::Key_Right, event->modifiers(), event->nativeScanCode(), event->nativeVirtualKey(), event->nativeModifiers(), event->text(), event->isAutoRepeat(), event->count());
                        event->accept();
                        QTableView::keyPressEvent(&newEvent);
                        setCurrentIndex(model()->index(0, currentIndex().column()));
                    }
                }
                else {
                    QKeyEvent newEvent(event->type(), Qt::Key_Down, event->modifiers(), event->nativeScanCode(), event->nativeVirtualKey(), event->nativeModifiers(), event->text(), event->isAutoRepeat(), event->count());
                    event->accept();
                    QTableView::keyPressEvent(&newEvent);
                }
                return;
            }
            QTableView::keyPressEvent(event);
        }
    

    That's not as clean as your code. I would appreciate if you have suggestions to obtain a better code.


Log in to reply