QMainWindow 没有收到 keyPressEvent,即使有事件过滤器

Posted

技术标签:

【中文标题】QMainWindow 没有收到 keyPressEvent,即使有事件过滤器【英文标题】:QMainWindow not receiving keyPressEvent, even with event filter 【发布时间】:2020-07-31 13:55:08 【问题描述】:

我正在尝试设计一个图像查看器应用程序,我在其中使用 QGraphicsView 来显示我的图像。我想让用户使用箭头键打开下一个/上一个图像,但我的 QGraphicsView 总是在消耗我的 keyPressEvent。我希望这些事件由我的 QMainWindow 类来处理。我意识到这是一个常见问题,显然我可以通过安装事件过滤器和/或确保我的 QMainWindow 可以获得焦点来解决它。这两件事我都做了,但到目前为止我唯一做的就是不让 QGraphicsView 获取事件,但它仍然没有传播到 QMainWindow。到目前为止,我已经在我的QMainWindow 类中实现了eventFilter 方法并将它安装在我的QGraphicsView 对象上。

QMainWindow 类

IVMainWindow::IVMainWindow(QWidget *parent)
    : QMainWindow(parent)

    setWindowTitle("ImageViewer++");
    setFocusPolicy(Qt::StrongFocus);  // Enabled the QMainWindow to get focus

    m_image_widget = new IVImageWidget();
    m_image_widget->installEventFilter(this);  // Install event filter on QGraphicsView
    setCentralWidget(m_image_widget);

    resize(QGuiApplication::primaryScreen()->availableSize() * 3 / 5);

    // For DEBUG purpose
    loadImage("res/image.png");

    createMenuBar();
    createToolBar();


/**
 * Filters out arrow key presses.
 */
bool IVMainWindow::eventFilter(QObject *obj, QEvent *event) 
    if (event->type() == QEvent::KeyPress) 
        auto *keyEvent = static_cast<QKeyEvent *>(event);
        int key = keyEvent->key();
        // Return true to reject the key-presses
        return (key == Qt::Key_Left || key == Qt::Key_Right || key == Qt::Key_Up || key == Qt::Key_Down);
     else 
        // standard event processing
        return QMainWindow::eventFilter(obj, event);
    


//Never gets to this point, unless I explicitly give it focus by clicking on some other widget than the QGraphicsView...
void IVMainWindow::keyPressEvent(QKeyEvent *event) 
    if (event->key() == Qt::RightArrow) 
        m_logger.Debug("Right arrow pressed.");
     else if (event->key() == Qt::LeftArrow) 
        m_logger.Debug("Left arrow pressed.");
    

【问题讨论】:

你的问题和this一样吗? (不过我知道它适用于 Qt4。) @JarMan 不确定。我尝试在视口和setFocusProxy(0) 上安装事件过滤器,但都没有成功。 【参考方案1】:

你需要在事件过滤器中处理事件,调用 QMainWindow::eventFilter 是可以的,但它没有 将事件作为传入事件处理,因此不会调用事件处理程序。

bool IVMainWindow::eventFilter(QObject *obj, QEvent *event) 
    if (event->type() == QEvent::KeyPress) 
        auto *keyEvent = static_cast<QKeyEvent *>(event);
        int key = keyEvent->key();
        // Return true to reject the key-presses
        if  (key == Qt::Key_Left || key == Qt::Key_Right || key == Qt::Key_Up || key == Qt::Key_Down)
        
            //process event here somehow, or instruct your class to do it later
            return true; //filter the event
        
     else 
        // standard event processing
        return QMainWindow::eventFilter(obj, event);
    


//This will only be called for the 'real' events, the ones that eventually are received by the main window
void IVMainWindow::keyPressEvent(QKeyEvent *event) 
    if (event->key() == Qt::RightArrow) 
        m_logger.Debug("Right arrow pressed.");
     else if (event->key() == Qt::LeftArrow) 
        m_logger.Debug("Left arrow pressed.");
    

【讨论】:

嗯,谢谢,这行得通!我以为我可以重定向事件,但显式调用 keyPressEvent 方法也可以。

以上是关于QMainWindow 没有收到 keyPressEvent,即使有事件过滤器的主要内容,如果未能解决你的问题,请参考以下文章

Qt关闭QMainWindow后如何防止崩溃?

BlackBerry - 模拟 KeyPress 事件

带有 Cmake 的简单 QtProject:QMainWindow:没有这样的文件或目录

当我按下一个键时没有调用 keyPressed() 方法?

OpenCV进程运行时QMainWindow没有响应

pyqt5,接收 AttributeError:“QMainWindow”对象没有属性“browseSlot”