Search code examples
c++qtkeypressqtableview

Failure to detect "Keypress" on QTableView?


I'm using QTableView to visualize some particular images. The user may click on the images of the TableView and that image will be magnified in another bigger window of QLabel type. I'm able to make this possible using the mouse clicks on the TableView, but I'd like to enable it for keyboard buttons "up" and "down". What I mean is that, once the user click on one of the images listed on the TableView, if the user changes to other images using keyboard buttons "up" and "down", I want to detect key press and connect it to the QLabel which magnifies that particular selected image.

So, what I mean is I actually want to detect keypress on the QTableView. Until now I haven't managed to do it. I'm installing an eventfilteron the viewPort of the QTableView, and in the eventfilter function I can detect the mousebuttonpress, but I cannot detect the keypress.

To show you how I'm approaching the implementation I have made simple program for testing with QTableView andKeypress. Below, I have given the code of the mainWindow implementation of that simple program.

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QStandardItemModel>
#include <QDebug>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    ui->numberTable->viewport()->installEventFilter(this);
    connect(ui->FillUp, SIGNAL(clicked()), this, SLOT(fillUp()));
}

void MainWindow::fillUp()
{
    model = new QStandardItemModel(3, 3, this);
    int counter = 0;
    for(int i = 0; i < 3; i++)
    {
        for(int j = 0; j < 3; j++)
        {
            QStandardItem * itm = new QStandardItem;
            counter++;
            itm->setText(QString::number(counter));
            model->setItem(i, j, itm);
        }
    }
    ui->numberTable->setModel(model);
    ui->numberTable->show();
}

bool MainWindow::eventFilter(QObject * obj, QEvent * ev)
{
    if(obj == ui->numberTable->viewport())
    {
        if(ev->type() == QEvent::MouseButtonPress)
        {
            qDebug()<<"Mouse button pressed!\n";
        }
        else if(ev->type() == QEvent::KeyPress)
        {
            qDebug()<<"Key button pressed\n";
        }
    }
    return QObject::eventFilter(obj, ev);
}

MainWindow::~MainWindow()
{
    delete ui;
}

The programs does output "Mouse button pressed", but no output for keyboard pressing. Could you please let me know where I am doing the error?

Thanks


Solution

  • I have the same trouble. Using your idea, if print the type of event I get: "Paint widget" (12) instead "KeyPress" (6).

    bool AR_Principal::eventFilter(QObject * obj, QEvent * ev){
        qDebug() << ev->type();
        if(obj == ui->tableView->viewport())
        {
            if(ev->type() == QEvent::MouseButtonPress)
            {
                qDebug()<<"Mouse button pressed";
            }
            else if(ev->type() == QEvent::KeyPress)
            {
                qDebug()<<"Key button pressed";
            }
            else if(ev->type() == QEvent::Paint)
            {
                qDebug()<<"Paint widget" ;
            }
        }
        return QObject::eventFilter(obj, ev);
    }
    

    If use QEvent::Paint event this works. Or like the other answer says add:

    ui->tableView->installEventFilter(this);
    

    And dont use the condition:

    if(obj == ui->tableView->viewport())
    

    But a more efficient solution its:

    connect(ui->tableView->selectionModel(), SIGNAL(currentChanged (const QModelIndex & , const QModelIndex & )), SLOT(selectedItem(const QModelIndex &)));
    

    Where selectedItem(const QModelIndex &) its a private slot function where you can do anything with selected data (using their index)