虚拟键盘——设计思路及event事件处理方法

来源:互联网 发布:linq高级编程 pdf下载 编辑:程序博客网 时间:2024/06/07 01:05

        前面谈及了虚拟键盘的设计方法,其设计内容及思路如下:

(1)    新建对话框类,在该对话框中有文本框若干、虚拟输入键盘一个。


(2)    在对话框类中定义虚拟键盘子对象、用于文本输入响应的槽函数;定义事件过滤器,安装在对话框上,当对话框接收到event事件时,如果需要则接收(例如用于文本框上下切换的两个按键),如果不需要则转发给键盘(例如用于键盘左右移动的两个按键,用于选择字符的确认键),如此进行事件分发。


(3)    当用户按下确认键选择字符时,会发送一个clicked信号,此信号经过signalMapper转发,将按键上的文本信息传送到(2)中所述的槽函数中,由此设定文本框的输入值。

       上述设计使用了QSignalMapper类,这个类还是很好用的,但是存在一个缺点:按键类使用在新的对话框时,每次都要在新的对话框类中,定义一个eventFilter,重写keyPressEvent,很麻烦。

       下面的改进办法就很好用,该设计方法将按键统一放在VirtualKeyboard类中处理,且在VirtualKeyboard类中定义eventFilter,这样模块复用时就更加简单。


bool VirtualKeyboard::eventFilter(QObject *obj, QEvent *event){    int forwardKey = 0;    Qt::KeyboardModifier modifier = Qt::NoModifier; // 用于焦点切换时,定义是否按下了shift键    QString text;     if(event->type() == QEvent::KeyPress || event->type() == QEvent::KeyRelease)    {        QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);        switch (keyEvent->key())        {            case GENERAL_PURPOSE_KNOB:                QApplication::sendEvent(this, event); // 旋动旋钮,则直接交给VirtualKeyboard的keypressEvent来处理                return true;            case GENERAL_PURPOSE_BUTTON:                forwardKey = button.at(currentChoice)->text().at(0).toLatin1();                text = button.at(currentChoice)->text();  // 取按键text,用于sendEvent                break;            case KEY_UP:                forwardKey = Qt::Key_Tab;                break;            case KEY_DOWN:                forwardKey = Qt::Key_Tab;                modifier = Qt::ShiftModifier;  // shift键按下                break;            case KEY_LEFT_FORWARD:                forwardKey = Qt::Key_Left;                break;            case KEY_RIGHT_FORWARD:                forwardKey = Qt::Key_Right;                break;            case KEY_BACKSPACE:                forwardKey = Qt::Key_Backspace;                break;            default:                break;        }    }    if (forwardKey != 0)    {        QWidget *widget = QApplication::focusWidget();        if (widget)        {            QKeyEvent e(event->type(), forwardKey, modifier, text); // 定义keyevent事件            QApplication::sendEvent(widget, &e);   // 发送给有焦点的QLineEdit,QLineEdit会自行处理这些事件            return true;        }    }    return QObject::eventFilter(obj, event);}
       这样用不得不说非常妙,因为QLineEdit可以自行处理上述的按键事件,就用不着再写槽函数了,且焦点可以自由的上下切换,对话框类也无需定义keypressEvent和eventFilter,该类的复用就非常方便。




0 0
原创粉丝点击