按键事件过滤器出现问题

时间:2019-07-15 20:17:31

标签: c++ qt qkeyevent

我正在尝试学习如何使用QtCreator使用GUI制作软件。我之前已经做过一些编程,但从未涉及任何内容。到目前为止,我已经制作了一个包含5个项目的窗口:2个标签,1个按钮,1个LineEdit和1个listWidget。

我的目标是能够在lineEdit中输入文本并将其显示在listWidget中。如果您用鼠标单击该按钮,则效果很好。

我还希望能够使用键盘上的Enter / Return键来激活按钮。这是我需要帮助的部分。

我创建了一个用于处理按键事件的新类,称为KeyboardFilter。

我已经在主窗口对象上安装了事件过滤器。 eventFilter函数应该接收任何事件,检查它是否是键事件,然后检查是否是回车按钮。如果是,那么我要激活该按钮。

我无法确定我为eventFilter编写的任何内容是否真的有效。

// == keyboardfilter.h =======================================================

#ifndef KEYBOARDFILTER_H
#define KEYBOARDFILTER_H

#include <QApplication>
#include <QLineEdit>
#include <QKeyEvent>

class KeyboardFilter : public QObject
{
public:
    KeyboardFilter( QObject *parent = nullptr ) : QObject( parent ) {}

//protected:
public:
    bool eventFilter( QObject *target, QEvent *event );
};

#endif // KEYBOARDFILTER_H


// == mainwindow.h ===========================================================

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private:
    Ui::MainWindow *ui;

// handles clicking the enter button with the mouse
//private slots:
public slots:
    void EnterPressed();

// supposed to handle key presses. doesn't actually work
//protected:
public:
    void KeyPressEvent(QKeyEvent *event);
    void KeyReleaseEvent(QKeyEvent *event);
    bool EventFilter(QEvent *event);
};

#endif // MAINWINDOW_H


// == keyboardfilter.cpp =====================================================

#include "keyboardfilter.h"

bool KeyboardFilter::eventFilter(QObject *target, QEvent *event)
{
    if(event->type() == QEvent::KeyPress)
    {
        QKeyEvent *keyEvent = static_cast<QKeyEvent*>(event);
        if(keyEvent->key() == Qt::Key_Return || keyEvent->key() == Qt::Key_Enter){
            return true;
        }
    }
    if(event->type() == QEvent::KeyRelease){
        QKeyEvent *keyEvent = static_cast<QKeyEvent*>(event);
        if(keyEvent->key() == Qt::Key_Return || keyEvent->key() == Qt::Key_Enter){
            return true;
        }
    }
    return false;
}


// == mainwindow.cpp =========================================================

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "QDebug"
#include <QKeyEvent>
#include <iostream>

QString stack[10];

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    stack[1] = "stack";
    ui->Display->addItem(stack[1]);

    connect(ui->Enter, SIGNAL(released()), this, SLOT(EnterPressed()));
}

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

//qDebug() << "Debug Message";
//QDebug("text");

void MainWindow::EnterPressed(){
    //ui->Input->setText(QString("text"));

    ui->Display->clear();

    QString input = ui->Input->text();
    ui->Input->clear();

    ui->Display->addItem(input);
}

// -- keyboardfilter.cpp

#include "keyboardfilter.h"

bool KeyboardFilter::eventFilter(QObject *target, QEvent *event)
{
    if(event->type() == QEvent::KeyPress)
    {
        QKeyEvent *keyEvent = static_cast<QKeyEvent*>(event);
        if(keyEvent->key() == Qt::Key_Return || keyEvent->key() == Qt::Key_Enter){
            return true;
        }
    }
    if(event->type() == QEvent::KeyRelease){
        QKeyEvent *keyEvent = static_cast<QKeyEvent*>(event);
        if(keyEvent->key() == Qt::Key_Return || keyEvent->key() == Qt::Key_Enter){
            return true;
        }
    }
    return false;
}

// == main.cpp ===============================================================

#include "mainwindow.h"
#include "keyboardfilter.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();

    //    KeyboardFilter filter;
    //    a.installEventFilter(&filter);

    KeyboardFilter* key = new KeyboardFilter();
    w.installEventFilter(key);

    if(key){
        w.EnterPressed();
    }
    return a.exec();
}

运行此代码时,将弹出窗口,并且可以在lineEdit中输入文本。如果我用鼠标单击该按钮,则文本将根据需要移动到listWidget。如果我输入文字,然后按“ Enter”,则什么也不会发生。

我试图在按Enter之前先点击Tab键将焦点移到lineEdit,listWidget和按钮上,但是并没有帮助。

2 个答案:

答案 0 :(得分:0)

一种全局捕获Enter / Return键的简单方法是使用QShortcut,然后将触发事件连接到按钮单击。

QWidget *widget = new QWidget(this); //The main window central widget

QLineEdit *edit = new QLineEdit(this); //Your edit

QPushButton *button = new QPushButton("Accept", this); //Your button

QLabel *label = new QLabel(this); //Your label

QHBoxLayout *layout = new QHBoxLayout(widget); //Arrange items horizontally
layout->addWidget(edit);
layout->addWidget(button);
layout->addWidget(label);

connect(button, &QPushButton::clicked, this, [=](bool checked){ //The button clicked event
    Q_UNUSED(checked)

    label->setText(edit->text());
    edit->clear();
});

QShortcut *shortcut_return = new QShortcut(Qt::Key_Return, this); //The return shortcut event
connect(shortcut_return, &QShortcut::activated, button, &QPushButton::click);
QShortcut *shortcut_enter = new QShortcut(Qt::Key_Enter, this); //The enter shortcut event
connect(shortcut_enter, &QShortcut::activated, button, &QPushButton::click);

button->setDefault(true); //Set the button as default

setCentralWidget(widget);

答案 1 :(得分:0)

也许installEventFilter的Qt文档不是很清楚,您需要将事件过滤器安装到要过滤的事件的对象上。在您的情况下,它是QLineEdit(Input?)而不是MainWindow。同样,您实际上不需要事件过滤器的额外类。您可以覆盖MainWindow的eventFilte并将其安装在QLineEdit上。如果您不想停止处理事件,只需确保返回 false

这是看起来如何:

main.cpp

#include "mainwindow.h"
#include <QApplication>

    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
        MainWindow w;
        w.show();
        return a.exec();
    }

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QLineEdit>
#include <QKeyEvent>

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = nullptr);
    ~MainWindow() override;

private:
    Ui::MainWindow *ui;

public slots:
    void EnterPressed();
    bool eventFilter(QObject *target, QEvent *event) override;
};

#endif // MAINWINDOW_H

mainwindow.cpp

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

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    //... your code here

    this->ui->Input->installEventFilter(this);
}

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

void MainWindow::EnterPressed(){
    //.... your code here
}

bool MainWindow::eventFilter(QObject *target, QEvent *event)
{
    if(target != this->ui->Input)return false;

    if(event->type() == QEvent::KeyPress)
    {
        QKeyEvent *keyEvent = static_cast<QKeyEvent*>(event);
        if(keyEvent->key() == Qt::Key_Return || keyEvent->key() == Qt::Key_Enter){
            qDebug() << "eventFilter Enter pressed";
            this->EnterPressed(); // call your slot 
            return true;
        }
    }
    if(event->type() == QEvent::KeyRelease){
        QKeyEvent *keyEvent = static_cast<QKeyEvent*>(event);
        if(keyEvent->key() == Qt::Key_Return || keyEvent->key() == Qt::Key_Enter){
            qDebug() << "eventFilter Enter pressed released";
            return true;
        }
    }
    return false;
}