问题
I have one main Widget
and inside this main widget I have QListWidget
and two buttons. I have override the keyPressEvent
inside the main widget (inherited from QWidget
). I can receive the keyPress
events when focus is not on QListWidget
, but when focus is inside the QListWidget
I am unable to receive these keyPress
events. Below is the code I have used to achieve this:
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
this->setFocusPolicy(Qt::StrongFocus);
ui->listWidget->addItem(new QListWidgetItem("Item1"));
ui->listWidget->addItem(new QListWidgetItem("Item2"));
ui->listWidget->addItem(new QListWidgetItem("Item3"));
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::keyPressEvent(QKeyEvent *event)
{
qDebug() << "event->key(): " << event->key();
QWidget::keyPressEvent(event);
}
回答1:
In header:
protected:
bool eventFilter(QObject *obj, QEvent *event);
In constructor:
qApp->installEventFilter(this);
Filter:
bool MainWindow::eventFilter(QObject *obj, QEvent *event)
{
if (event->type() == QEvent::KeyPress)
{
QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
qDebug() << "key " << keyEvent->key() << "from" << obj;
}
return QObject::eventFilter(obj, event);
}
With this event filter you can catch all key press events and check who is emit event (obj
)
For example:
if ( obj == ui->listWidget )
//event from QListWidget
Accordingly to your comment:
bool MainWindow::eventFilter(QObject *obj, QEvent *event)
{
if (event->type() == QEvent::KeyPress)
{
if(obj == ui->listWidget)
{
QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
if(keyEvent->key() == Qt::Key_Up)
qDebug() << "Up";
if(keyEvent->key() == Qt::Key_Down)
qDebug() << "Down";
}
}
return QObject::eventFilter(obj, event);
}
回答2:
You need to use event filters.
Sometimes an object needs to look at, and possibly intercept, the events that are delivered to another object. For example, dialogs commonly want to filter key presses for some widgets; for example, to modify Return-key handling.
The QObject::installEventFilter() function enables this by setting up an event filter, causing a nominated filter object to receive the events for a target object in its QObject::eventFilter() function. An event filter gets to process events before the target object does, allowing it to inspect and discard the events as required. An existing event filter can be removed using the QObject::removeEventFilter() function.
来源:https://stackoverflow.com/questions/26368659/qwidget-how-to-receive-keypressevent-inside-child-widgets