前言

软键盘在嵌入式平台开发中被广泛使用
本章代码功能:
1.支持中英双语输入法
2.同时支持QT4/QT5版本
3.支持linux/windows系统

源码地址

https://gitee.com/jiang_bin_yu/softkeyboard

软件功能预览

英文输入法
在这里插入图片描述中文输入法
在这里插入图片描述

键盘代码展示

一、设置窗口大小信息
在这里插入图片描述
二、加载中文
2.1初始化读取字库表

bool SoftKeyBoard::InitChinese()
{
    QFile file(":/keyboard/SoftKeyBoard/FontLibrary.txt");
    int i = 0;
    if(file.open(QIODevice::ReadOnly))
    {
        QString str;
        QString key;
        while (true)
        {
            str = file.readLine();
            if(str.size() < 4)
                break;
            key = str.mid(2,str.size() - 3).replace("\r","");
            m_map_[key].push_back(str.left(1));
            ++i;
        }
        file.close();
        return true;
    }
    return false;
}

2.2 查询中文字库表

void SoftKeyBoard::ShowChinese(QString str,int page,int pos)
{
    qDebug()<<"ShowChinese"<<str<<page<<pos<<"current"<<m_strPingying_<<m_currentPage_<<m_currentPos_;
    if(page < 0)
        page = 0;
    if(pos < 0 || pos > 11)
        pos = 0;
    std::map<QString,std::vector<QString> >::iterator it = m_map_.find(str);
    ui.lab_pinying_->setText(str);
    if(it != m_map_.end() && it->second.size() < page * 12)//没有下一页
        return;
    for(int i = 0;i < 12;++i)
    {
        qDebug() << (it != m_map_.end()) << m_map_.size();
        m_btns_[46 + i]->setText(it != m_map_.end() && it->second.size() > page * 12 + i ? it->second[page * 12 + i] : "");
        //qDebug()<<"on_btn_language__clicked"<<m_btns_[46 + i]->text()<<i;
    }
    if(m_btns_[46 + pos]->text().isEmpty())
        pos = m_currentPos_;
    m_strPingying_ = str;
    m_currentPage_ = page;
    m_currentPos_ = pos;
}

三、避免QLineEidt焦点丢失
3.1重写QLineEdit

void focusLineEdit::focusInEvent(QFocusEvent *e)
{
    QLineEdit::focusInEvent(e);
    this->setFocus();
    //qDebug() << "focusInEvent";
    emit focusIn();
}

3.2在键盘中connect绑定光标进入信号

	//设置光标进入 否则进入页面lineEdit 可能无法获取光标
    connect(ui.wordShow,SIGNAL(focusIn()),this,SLOT(OnfocusIn()));   

3.3在键盘中赋予lineEidt光标位置已经焦点

void SoftKeyBoard::OnfocusIn()
{
    qDebug() << "OnfocusIn";
    ui.wordShow->setCursorPosition(ui.wordShow->text().size());
    ui.wordShow->activateWindow();
    ui.wordShow->setFocus();
    // this->activateWindow();
}

四、键盘总在窗口底部显示

bool SoftKeyBoard::event(QEvent *e)
{
    switch (e->type())
    {
    case QEvent::WindowActivate:
        if (m_lastFocusedWidget_)
            m_lastFocusedWidget_->activateWindow();
        break;
    case QEvent::Show:
    {
        QDesktopWidget* desktop = QApplication::desktop(); // =qApp->desktop();也可以
        int centerHeight = (desktop->height() - FatherHeight)/2 + FatherHeight;
        this->move((desktop->width() - this->width())/2,m_bIsChinese_ ? centerHeight-KeyboardHeightChinese : centerHeight-KeyboardHeightEnglish);
        break;
    }
    default:
        break;
    }
    return QWidget::event(e);
}

五、中英文输入法切换时调整键盘大小以及显示位置

void SoftKeyBoard::on_btn_language__clicked()
{
    static bool bFirstInit = true;
    if(m_bIsUppercase_)
        on_btn_caplock__clicked();
    m_bIsChinese_ = !m_bIsChinese_;
    if( bFirstInit && m_bIsChinese_)
        qDebug()<<"on_btn_language__clicked"<<"open chinese.txt failed.";
    ui.btn_language_->setText(m_bIsChinese_ ? "中文/英文" : "英文/中文");
    m_bIsChinese_  ? ui.widget_chinese_->show() : ui.widget_chinese_->hide();
    //ui.widget_keyboard_->move(0,m_bIsChinese_ ? 100 : 2);
    resize(KeyboardWidth,m_bIsChinese_ ? KeyboardHeightChinese : KeyboardHeightEnglish);

    QDesktopWidget* desktop = QApplication::desktop(); // =qApp->desktop();也可以
    int centerHeight = (desktop->height() - FatherHeight)/2 + FatherHeight;
    this->move((desktop->width() - this->width())/2,m_bIsChinese_ ? centerHeight-KeyboardHeightChinese : centerHeight-KeyboardHeightEnglish);
}

使用键盘方法

参考文章:QT事件处理–notify()

一、利用notify函数捕获控件按下实际弹出输入框
捕获到按钮事件后判断被按下的对象名 如果对象的objectName包含lineEidt则判断需要弹出键盘

bool MyApplication::notify(QObject *receiver, QEvent *e)
{
    if(e->type() == QEvent::MouseButtonPress)  //receiver->parent() != NULL &&
    {
        QMouseEvent *mouseEvent=static_cast<QMouseEvent *>(e);

        if(receiver != NULL)
        {
            qDebug() << receiver->objectName();
            if(receiver->objectName().contains("lineEdit"))
            {
                if(static_cast<QLineEdit *>(receiver)->isEnabled())
                {
                    SoftKeyBoard keyBoard;
                    QString text = static_cast<QLineEdit *>(receiver)->text();
                    keyBoard.setValue(text);
                    int key = keyBoard.exec();
                    if(key == QMessageBox::Ok)
                    {
                        QString text = keyBoard.getValue();
                        static_cast<QLineEdit *>(receiver)->setText(text);
                    }
                    return QApplication::notify(receiver, e);
                }
            }
        }
    }
    return QApplication::notify(receiver, e);
}

二、利用控件槽函数弹出键盘

如QTextEdit控件可以监控selectionChanged信号

void MainWindow::on_textEdit_selectionChanged()
{
    qDebug() << "on_textEdit_selectionChanged";
    SoftKeyBoard keyBoard;
    int key = keyBoard.exec();
    if(key == QMessageBox::Ok)
    {
        QString text = keyBoard.getValue();
        ui->textEdit->append(text);
    }
}

如Tablewidget控件可以监控itemDoubleClicked信号即双击item时弹出键盘

void MainWindow::on_tableWidget_itemDoubleClicked(QTableWidgetItem *item)
{
    SoftKeyBoard keyBoard;
    QString text = item->text();
    keyBoard.setValue(text);
    int key = keyBoard.exec();
    if(key == QMessageBox::Ok)
    {
        QString text = keyBoard.getValue();
        item->setText(text);
    }
}

在这里插入图片描述

Logo

更多推荐