本文共 3289 字,大约阅读时间需要 10 分钟。
最近需要在一个嵌入式设备上使用物理按键跟Qt界面交互操作,
在这种没有鼠标的情况下,写Qt程序就要小心了,有些东东能用,
有些东东不能用,一定提前得有所考虑。
简单的交互最好只使用按钮,复杂点的,因为涉及到焦点的切换。
复杂点的,如果屏幕还要弹出输入法来,就更加麻烦一些了。
上图吧。
使用事件过滤器,将窗体所有部件的事件都集中在父窗体的事件处理函数中来处理,来决定下一个焦点切换到谁身上。
为了方便在上、下、左、右四个方向进行切换,所以使用了QGridLayout.
#ifndef ZPAGE1_H
#define ZPAGE1_H #include <QWidget> #include <QKeyEvent> #include <QDebug> #include <QGridLayout> #include <QToolButton> class ZPage1 : public QWidget { Q_OBJECT public: ZPage1(QWidget *parent = 0); ~ZPage1(); protected: bool eventFilter(QObject *obj, QEvent *event); private slots: void ZSlotBtnClicked(); private: QGridLayout *m_gridLayout; QToolButton *m_btnArray[20]; }; #endif // ZPAGE1_H#include "zpage1.h"
ZPage1::ZPage1(QWidget *parent) : QWidget(parent) { this->setStyleSheet("QToolButton{width:50px;height:30px;}"); this->m_gridLayout=new QGridLayout; qint32 tX=0; qint32 tY=0; for(qint32 i=0;i<20;i++) { this->m_btnArray[i]=new QToolButton; this->m_btnArray[i]->installEventFilter(this); this->m_btnArray[i]->setText(QString("%1").arg(i+1)); this->m_gridLayout->addWidget(this->m_btnArray[i],tX,tY); if(tX++>=5) { tY++; tX=0; } connect(this->m_btnArray[i],SIGNAL(clicked()),this,SLOT(ZSlotBtnClicked())); } this->setLayout(this->m_gridLayout); } ZPage1::~ZPage1() { for(qint32 i=0;i<20;i++) { delete this->m_btnArray[i]; } delete this->m_gridLayout; } void ZPage1::ZSlotBtnClicked() { QToolButton *btn=qobject_cast<QToolButton*>(sender()); if(btn) { qDebug()<<"Button Clicked:"<<btn->text(); } } bool ZPage1::eventFilter(QObject *obj, QEvent *event) { if(event->type()==QEvent::KeyPress) { qint32 tCurFocusX; qint32 tCurFocusY; for(qint32 i=0;i<this->m_gridLayout->rowCount();i++) { bool bFindIt=false; for(qint32 j=0;j<this->m_gridLayout->columnCount();j++) { QLayoutItem *tItem=this->m_gridLayout->itemAtPosition(i,j); if(!tItem) { continue; } QWidget *tFocusWidget=tItem->widget(); if(tFocusWidget && tFocusWidget==this->focusWidget()) { qDebug()<<"oldPos:"<<i<<j; tCurFocusX=i; tCurFocusY=j; bFindIt=true; break; } } if(bFindIt) { break; } } QKeyEvent *tKeyEvent=static_cast<QKeyEvent*>(event); switch(tKeyEvent->key()) { //"Return" is the left area Enter key,"Enter" is the right digital area Enter key. //they are different. //case Qt::Key_Enter: case Qt::Key_Return: { qDebug()<<"return"; QLayoutItem *tNewItem=this->m_gridLayout->itemAtPosition(tCurFocusX,tCurFocusY); if(tNewItem) { QToolButton *tBtn=qobject_cast<QToolButton*>(tNewItem->widget()); if(tBtn) { emit tBtn->click(); return true; } } } case Qt::Key_Up: qDebug()<<"up"; if(tCurFocusX>0) { tCurFocusX--; } break; case Qt::Key_Down: qDebug()<<"down"; if(tCurFocusX<this->m_gridLayout->rowCount()-1) { tCurFocusX++; } break; case Qt::Key_Left: qDebug()<<"left"; if(tCurFocusY>0) { tCurFocusY--; } break; case Qt::Key_Right: qDebug()<<"right"; if(tCurFocusY<this->m_gridLayout->columnCount()-1) { tCurFocusY++; } break; default: break; } qDebug()<<"newPos:"<<tCurFocusX<<tCurFocusY; QLayoutItem *tNewItem=this->m_gridLayout->itemAtPosition(tCurFocusX,tCurFocusY); if(tNewItem) { tNewItem->widget()->setFocus(); } //we already handle this event,so return false. //this cause qt do not call other event handler. return true; } return false; } 慢慢看吧,亲们,不过有个小问题要注意,就是PC兼容的键盘上有2个回车键,左边常用区域叫Return,右边数字区域叫Enter,没错,Qt5是这样编码的。
好了,剩下的工作就是开始我的嵌入式GUI规则了。包括功能实现,以及与按键互动。