大家都知道在Windows系统下进行软件开发,需要处理各种各样的消息,其中处理按键消息是经常会碰到的。Qt同时也可以处理键盘的按键消息,在对应的界面重写按键处理函数即可:
void keyPressEvent(QKeyEvent *event)
void keyReleaseEvent(QKeyEvent *event)
但是这样同时会有一个问题,以上函数只有在当前界面是被激活的情况下返回被调用,一旦界面隐藏或者最小化后,就不会在处理案件消息了,但是此时还是需要我们处理这个界面的按键消息,该怎么办呢?
无论如何主程序是可以接收到键盘消息的,可以通过主键盘接收到的消息,然后分发给各个需要处理的界面就可以了。
定义处理接口:
#pragma once
class QKeyEvent;
class IKeyEvent {
public:
IKeyEvent();
~IKeyEvent();
virtual void keyPress(QKeyEvent *event);
virtual void keyRelease(QKeyEvent *event);
private:
bool _useKeyEvent = false;//是否处理按键消息
};
#include "IKeyEvent.h"
IKeyEvent::IKeyEvent() {
}
IKeyEvent::~IKeyEvent() {
}
void IKeyEvent::keyPress(QKeyEvent *event) {
}
void IKeyEvent::keyRelease(QKeyEvent *event) {
}
接口管理:
#pragma once
#include <QVector>
class IKeyEvent;
class QKeyEvent;
#define KeyEventMgr() (KeyEventManager::getInstance())
class KeyEventManager {
private:
KeyEventManager();
static KeyEventManager* _instance;
public:
~KeyEventManager();
static KeyEventManager* getInstance();
void addKeyEvent(IKeyEvent* keyEvent);
void keyPress(QKeyEvent *event);
void keyRelease(QKeyEvent *event);
private:
QVector<IKeyEvent*> _keyEventList;
};
#include "KeyEventManager.h"
#include "IKeyEvent.h"
#include <QKeyEvent>
KeyEventManager* KeyEventManager::_instance = new KeyEventManager;
KeyEventManager::KeyEventManager() {
}
KeyEventManager::~KeyEventManager() {
}
KeyEventManager* KeyEventManager::getInstance() {
return _instance;
}
void KeyEventManager::addKeyEvent(IKeyEvent* keyEvent) {
_keyEventList.push_back(keyEvent);
}
void KeyEventManager::keyPress(QKeyEvent *event) {
auto it = _keyEventList.begin();
for (it; it != _keyEventList.end(); it++) {
(*it)->keyPress(event);
}
}
void KeyEventManager::keyRelease(QKeyEvent *event) {
auto it = _keyEventList.begin();
for (it; it != _keyEventList.end(); it++) {
(*it)->keyRelease(event);
}
}
主程序界面;
#pragma once
#include <QtWidgets/QMainWindow>
#include "ui_QtTest.h"
class QKeyEvent;
class QtGuiVideo;
class QtTest : public QMainWindow {
Q_OBJECT
public:
QtTest(QWidget *parent = Q_NULLPTR);
void keyPressEvent(QKeyEvent *event)override;
void keyReleaseEvent(QKeyEvent *event)override;
private slots:
void slotTest();
private:
Ui::QtTestClass ui;
QtGuiVideo* _guiVideo = nullptr;
};
#include "QtTest.h"
#include "KeyEventManager.h"
#include "QtGuiVideo.h"
QtTest::QtTest(QWidget *parent)
: QMainWindow(parent) {
ui.setupUi(this);
connect(ui.pushButton, SIGNAL(clicked()), this, SLOT(slotTest()));
_guiVideo = new QtGuiVideo;
}
void QtTest::keyPressEvent(QKeyEvent *event) {
KeyEventMgr()->keyPress(event);
}
void QtTest::keyReleaseEvent(QKeyEvent *event) {
KeyEventMgr()->keyRelease(event);
}
void QtTest::slotTest() {
_guiVideo->show();
}
需要接受消息的界面:
#pragma once
#include <QWidget>
#include "ui_QtGuiVideo.h"
#include "IKeyEvent.h"
class QtGuiVideo : public QWidget,public IKeyEvent {
Q_OBJECT
public:
QtGuiVideo(QWidget *parent = Q_NULLPTR);
~QtGuiVideo();
virtual void keyPress(QKeyEvent *event)override;
virtual void keyRelease(QKeyEvent *event)override;
private:
Ui::QtGuiVideo ui;
};
#include <QDebug>
#include <QKeyEvent>
#include "QtGuiVideo.h"
#include "KeyEventManager.h"
QtGuiVideo::QtGuiVideo(QWidget *parent)
: QWidget(parent) {
ui.setupUi(this);
KeyEventMgr()->addKeyEvent(this);
}
QtGuiVideo::~QtGuiVideo() {
}
void QtGuiVideo::keyPress(QKeyEvent *event) {
qDebug() << QStringLiteral("键盘按下:") << event->key();
}
void QtGuiVideo::keyRelease(QKeyEvent *event) {
qDebug() << QStringLiteral("键盘松开:") << event->key();
}
运行一下,输出结果:
"键盘按下:" 71
"键盘松开:" 71
"键盘按下:" 72
"键盘松开:" 72
当界面及时隐藏或者未激活的情况下同样也可以接收带按键消息!
aaa