Qt 项目之虚拟键盘 V1.0

最近做了一个虚拟键盘的小Demo,分享给大家。

 

一般我在做一个东西之前会上网查找资料,看下有几种实现的方式。在Qt下开发虚拟键盘总体上可分为两种方式——进程内部和进程外部。

在进程内部,虚拟键盘可以是一个QWidget小部件,显示键盘按钮,对用户按下的按键生成键盘事件,之后让具有焦点的可输入的部件响应键盘事件。

在进程外部,虚拟键盘则可以被其他应用程序使用,不过这需要进程间通信。Qt上使用DBus作为IPC通讯方式,虚拟键盘被开发完成则是一个插件,需要放到Qt指定的目录下,Qt应用程序在使用虚拟键盘前需要注册一下,关于虚拟键盘和插件以后我们有机会会介绍的。今天展示的是在进程内部开发虚拟键盘的方式。

 

我最终想要实现的是点击任何可输入部件键盘都可以弹出来,但是开发的过程中发现可输入部件没有在被点击后发出信号或事件,最后只好用窗体的鼠标事件来替代。

提几个项目中会遇到的问题:

①像键盘这种有众多按钮的窗体,如何创建按钮及其信号和槽

②响应按钮后如何转换为键盘事件,事件的接收者是谁

③希望键盘随着窗体焦点移动而移动

 

有些问题我是没有解决的,这次和大家分享的是虚拟键盘的初版,以后会有更新。使用插件开发键盘上面考虑的问题插件都预留了接口,不用像自己开发这样要考虑诸多问题,不过同样也知道了很多知识。

 

程序平台:ubuntu  Qt 5.5.1

 

一、 KeyBoard 类

1. 该类继承QWidget,是键盘窗体的实现类,有以下几个对外接口

    void showKeyboard(int globalX, int globalY);	
    void hideKeyboard();	

	
    void setFocusWidget(QWidget *focusWidget);

分别是键盘的显示、隐藏以及生成键盘事件的接收对象。

 

2. 众多键盘按钮的布局,主要使用QSignalMapper。为方便阅读,使用的数据结构没有列出

KeyBoard::KeyBoard(QWidget *parent) : QWidget(parent)	
{	
    QGridLayout *gridLayout = new QGridLayout(this);	

	
    QSignalMapper *mapper = new QSignalMapper(this);	
    connect(mapper, SIGNAL(mapped(int)), SLOT(buttonClicked(int)));	

	
    m_focusWidget = parent;	
    this->setStyle("#E4E4E4", "#A2A2A2", "#DCDCDC", "#000000");	

	
    int row = 0;	
    int column = 0;	

	
    for (int i = 0; i < layoutSize; ++i) {	
        if (keyboardLayout[i].key == NEXT_ROW_MARKER)	
        {	
            row++;	
            column = 0;	
            continue;	
        }	

	
        QPushButton *button = new QPushButton;	
        button->setFixedWidth(40);	
        button->setText(QString::fromLatin1(keyboardLayout[i].label));	

	
        mapper->setMapping(button, keyboardLayout[i].key);	
        connect(button, SIGNAL(clicked()), mapper, SLOT(map()));	

	
        gridLayout->addWidget(button, row, column);	
        column++;	
    }	
}

3. 生成键盘事件

void KeyBoard::buttonClicked(int key)	
{	
    QKeyEvent *keyPressEvent = NULL;	

	
    if ((key == Qt::Key_Enter) || (key == Qt::Key_Backspace))	
        keyPressEvent = new QKeyEvent(QEvent::KeyPress, key,	
                                      Qt::NoModifier);	
    else	
        keyPressEvent = new QKeyEvent(QEvent::KeyPress, key,	
                                      Qt::NoModifier, keyToCharacter(key));	

	
    if (keyPressEvent != NULL)	
    {	
        QGuiApplication::postEvent(m_focusWidget, keyPressEvent);	
    }	
}

二、 用户界面调用

 

主要重新实现了鼠标点击事件,将位置发送给键盘显示函数

void Widget::mousePressEvent(QMouseEvent *event)	
{	
    if( event->type()== QEvent::MouseButtonPress )	
    {	
        qDebug()<<"LeftButton";	
        if(event->pos().x()<= pos().x())	
        {	
            m_keyboard->showKeyboard(this->pos().x(),this->y() +	
                                     this->frameGeometry().height());	
        }	
    }	
}

总结:

①没有找到获取当前编辑框焦点的方法,QWidget中有焦点改变的信号,还有事件过滤  器,接下来会从这两方面入手。

②QLineEdit等编辑框没有响应鼠标点击的信号或事件,需要重新继承实现。

 

最后效果如图:

640?wx_fmt=png

                        需要参考的小伙伴可在公众号后台留下联系方式。

640?wx_fmt=png

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值