当前位置: 首页 > news >正文

QT6实现软键盘的两种方法

一.概述

  在触摸屏设备上,软键盘是替代物理键盘的重要输入方式。一般简单的功能需要数字小键盘,复杂的需要全键盘。

二.QT6实现数字小键盘

1.numkeyboard.h

#ifndef NUMKEYBOARD_H

#define NUMKEYBOARD_H

#include <QDialog>

#include <QtDebug>

#include <QKeyEvent>

#include <QEvent>

#include <QLineEdit>

#include <QPushButton>

class NumKeyboard : public QDialog

{

    Q_OBJECT

public:

    explicit NumKeyboard(QWidget *parent = 0);

    ~NumKeyboard();

    bool valid;

    QLineEdit   *lineEdit;

    QPushButton *num1Button;

    QPushButton *num2Button;

    QPushButton *num3Button;

    QPushButton *num4Button;

    QPushButton *num5Button;

    QPushButton *num6Button;

    QPushButton *num7Button;

    QPushButton *num8Button;

    QPushButton *num9Button;

    QPushButton *num0Button;

    QPushButton *dotButton;//“.”

    QPushButton *delButton;//删除

    QPushButton *signButton;//+-

    QPushButton *clearButton;//清除

    QPushButton *cancelButton;

    QPushButton *okButton;

    void        setText(QString str);

    QString     getText();

    void        InitUI();

protected:

    void changeEvent(QEvent *e);

    bool eventFilter(QObject *obj, QEvent *event);

private slots:

    void on_num1Button_clicked();

    void on_num2Button_clicked();

    void on_num3Button_clicked();

    void on_num4Button_clicked();

    void on_num5Button_clicked();

    void on_num6Button_clicked();

    void on_num7Button_clicked();

    void on_num8Button_clicked();

    void on_num9Button_clicked();

    void on_num0Button_clicked();

    void on_dotButton_clicked();

    void on_signButton_clicked();

    void on_delButton_clicked();

    void on_cancelButton_clicked();

    void on_okButton_clicked();

    void on_clearButton_clicked();

private:

    QString strContent;

};

#endif // NUMKEYBOARD_H

2.numkeyboard.cpp

#include "numkeyboard.h"

#include <QDebug>

//#include "qtextcodec.h"

NumKeyboard::NumKeyboard(QWidget *parent) :

    QDialog(parent)

{

    setWindowTitle(tr("数字键盘"));

    setWindowFlags(Qt::CustomizeWindowHint | Qt::WindowTitleHint);

    InitUI();

    connect(num1Button,   SIGNAL(clicked()), this, SLOT(on_num1Button_clicked()));

    connect(num2Button,   SIGNAL(clicked()), this, SLOT(on_num2Button_clicked()));

    connect(num3Button,   SIGNAL(clicked()), this, SLOT(on_num3Button_clicked()));

    connect(num4Button,   SIGNAL(clicked()), this, SLOT(on_num4Button_clicked()));

    connect(num5Button,   SIGNAL(clicked()), this, SLOT(on_num5Button_clicked()));

    connect(num6Button,   SIGNAL(clicked()), this, SLOT(on_num6Button_clicked()));

    connect(num7Button,   SIGNAL(clicked()), this, SLOT(on_num7Button_clicked()));

    connect(num8Button,   SIGNAL(clicked()), this, SLOT(on_num8Button_clicked()));

    connect(num9Button,   SIGNAL(clicked()), this, SLOT(on_num9Button_clicked()));

    connect(num0Button,   SIGNAL(clicked()), this, SLOT(on_num0Button_clicked()));

    connect(dotButton,    SIGNAL(clicked()), this, SLOT(on_dotButton_clicked()));

    connect(cancelButton, SIGNAL(clicked()), this, SLOT(on_cancelButton_clicked()));

    connect(okButton,     SIGNAL(clicked()), this, SLOT(on_okButton_clicked()));

    connect(signButton,   SIGNAL(clicked()), this, SLOT(on_signButton_clicked()));

    connect(delButton,    SIGNAL(clicked()), this, SLOT(on_delButton_clicked()));

    connect(clearButton,  SIGNAL(clicked()), this, SLOT(on_clearButton_clicked()));

}

NumKeyboard::~NumKeyboard()

{

}

void NumKeyboard::InitUI()

{

    QFont font;

    font.setPointSize(22);

    QFont font1;

    font1.setPointSize(16);

    num1Button = new QPushButton(this);

    num1Button->setText("1");

    num1Button->setGeometry(QRect(10, 70, 55, 50));

    num1Button->setFont(font);

    num1Button->setFocusPolicy(Qt::NoFocus);//去掉焦点

    num2Button = new QPushButton(this);

    num2Button->setText("2");

    num2Button->setGeometry(QRect(75, 70, 55, 50));

    num2Button->setFont(font);

    num2Button->setFocusPolicy(Qt::NoFocus);

    num3Button = new QPushButton(this);

    num3Button->setText("3");

    num3Button->setGeometry(QRect(140, 70, 55, 50));

    num3Button->setFont(font);

    num3Button->setFocusPolicy(Qt::NoFocus);

    cancelButton = new QPushButton(this);

    cancelButton->setText("Esc");

    cancelButton->setGeometry(QRect(205, 70, 95, 50));

    cancelButton->setFont(font1);

    cancelButton->setFocusPolicy(Qt::NoFocus);

    //-----------------------------------------------------------------------//

    num4Button = new QPushButton(this);

    num4Button->setText("4");

    num4Button->setGeometry(QRect(10, 130, 55, 50));

    num4Button->setFont(font);

    num4Button->setFocusPolicy(Qt::NoFocus);

    num5Button = new QPushButton(this);

    num5Button->setText("5");

    num5Button->setGeometry(QRect(75, 130, 55, 50));

    num5Button->setFont(font);

    num5Button->setFocusPolicy(Qt::NoFocus);

    num6Button = new QPushButton(this);

    num6Button->setText("6");

    num6Button->setGeometry(QRect(140, 130, 55, 50));

    num6Button->setFont(font);

    num6Button->setFocusPolicy(Qt::NoFocus);

    delButton = new QPushButton(this);

    delButton->setText(tr("←"));

    delButton->setGeometry(QRect(205, 130, 95, 50));

    delButton->setFont(font1);

    delButton->setFocusPolicy(Qt::NoFocus);

    //-----------------------------------------------------------------------//

    num7Button = new QPushButton(this);

    num7Button->setText("7");

    num7Button->setGeometry(QRect(10, 190, 55, 50));

    num7Button->setFont(font);

    num7Button->setFocusPolicy(Qt::NoFocus);

    num8Button = new QPushButton(this);

    num8Button->setText("8");

    num8Button->setGeometry(QRect(75, 190, 55, 50));

    num8Button->setFont(font);

    num8Button->setFocusPolicy(Qt::NoFocus);

    num9Button = new QPushButton(this);

    num9Button->setText("9");

    num9Button->setGeometry(QRect(140, 190, 55, 50));

    num9Button->setFont(font);

    num9Button->setFocusPolicy(Qt::NoFocus);

    clearButton = new QPushButton(this);

    clearButton->setText("C");

    clearButton->setGeometry(QRect(205, 190, 95, 50));

    clearButton->setFont(font1);

    clearButton->setFocusPolicy(Qt::NoFocus);

    //-----------------------------------------------------------------------//

    signButton = new QPushButton(this);

    signButton->setText(tr("±"));

    signButton->setGeometry(QRect(10, 250, 55, 50));

    signButton->setFont(font1);

    signButton->setFocusPolicy(Qt::NoFocus);

    num0Button = new QPushButton(this);

    num0Button->setText("0");

    num0Button->setGeometry(QRect(75, 250, 55, 50));

    num0Button->setFont(font);

    num0Button->setFocusPolicy(Qt::NoFocus);

    dotButton = new QPushButton(this);

    dotButton->setText(".");

    dotButton->setGeometry(QRect(140, 250, 55, 50));

    dotButton->setFont(font);

    dotButton->setFocusPolicy(Qt::NoFocus);

    okButton = new QPushButton(this);

    okButton->setText(tr("OK"));

    okButton->setGeometry(QRect(205, 250, 95, 50));

    okButton->setFont(font1);

    okButton->setFocusPolicy(Qt::NoFocus);

    //-----------------------------------------------------------------------//

    lineEdit = new QLineEdit(this);

    lineEdit->setGeometry(QRect(10, 10, 290, 50));

    QFont font3;

    font3.setPointSize(24);

    //font3.setWeight(50);

    lineEdit->setFont(font3);

    lineEdit->setText(QString());

    //lineEdit->installEventFilter(this);//创建事件过滤器,eventFilter函数才有效

}

void NumKeyboard::changeEvent(QEvent *e)

{

    QDialog::changeEvent(e);

    switch (e->type()) {

    case QEvent::LanguageChange:

        break;

    default:

        break;

    }

}

bool NumKeyboard::eventFilter(QObject *obj, QEvent *event)

{

    if (event->type() == QEvent::KeyPress)

    {

            QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);

            if (obj == lineEdit)

            {

                if(keyEvent->key() >= 0x20 && keyEvent->key()<= 0x0ff)  //屏蔽所有按键输入

                    return true;

                else

                    return false;

            }

            else

            {

                return false;

            }

    }

    else

    {

            // standard event processing

        return QObject::eventFilter(obj, event);

    }

}

//***********************按键*****************************//

void NumKeyboard::on_num1Button_clicked()       //1

{

    int idx = lineEdit->cursorPosition();  //根据光标的位置索引

    if(strContent.left(idx) == "0")       //除了小数外,第一个数不为0

    {

        lineEdit->setCursorPosition(idx);

        lineEdit->setFocus();

        return;

    }

   //  字符串的存储有引用计数,当一个 QString 对象被复制为另一个 QString 对象时,它们实际上指向相同的存储空间,仅仅是增加一个引用计数

    strContent.insert(idx, '1');  //插入字符串str在给定的索引位置对这个字符串,并返回一个引用。 //数据存入strContent

    lineEdit->setText(strContent); //strContent中的内容显示在lineEdit

    lineEdit->setCursorPosition(idx+1); //设置光标的位置 ??不设置好像也可以使用设定光标的位置

    lineEdit->setFocus();  //存在光标

    qDebug()<<"strContent"<<strContent;

    qDebug()<<"idx"<<idx;

}

void NumKeyboard::on_num2Button_clicked()       //2

{

    int idx = lineEdit->cursorPosition();

    if(strContent.left(idx) == "0")

    {

        lineEdit->setCursorPosition(idx);

        lineEdit->setFocus();

        return;

    }

    strContent.insert(idx, '2');

    lineEdit->setText(strContent);

    lineEdit->setCursorPosition(idx+1);

    lineEdit->setFocus();

}

void NumKeyboard::on_num3Button_clicked()       //3

{

    int idx = lineEdit->cursorPosition();

    if(strContent.left(idx) == "0")

    {

        lineEdit->setCursorPosition(idx);

        lineEdit->setFocus();

        return;

    }

    strContent.insert(idx, '3');

    lineEdit->setText(strContent);

    lineEdit->setCursorPosition(idx+1);

    lineEdit->setFocus();

}

void NumKeyboard::on_num4Button_clicked()       //4

{

    int idx = lineEdit->cursorPosition();

    if(strContent.left(idx) == "0")

    {

        lineEdit->setCursorPosition(idx);

        lineEdit->setFocus();

        return;

    }

    strContent.insert(idx, '4');

    lineEdit->setText(strContent);

    lineEdit->setCursorPosition(idx+1);

    lineEdit->setFocus();

}

void NumKeyboard::on_num5Button_clicked()       //5

{

    int idx = lineEdit->cursorPosition();

    if(strContent.left(idx) == "0")

    {

        lineEdit->setCursorPosition(idx);

        lineEdit->setFocus();

        return;

    }

    strContent.insert(idx, '5');

    lineEdit->setText(strContent);

    lineEdit->setCursorPosition(idx+1);

    lineEdit->setFocus();

}

void NumKeyboard::on_num6Button_clicked()       //6

{

    int idx = lineEdit->cursorPosition();

    if(strContent.left(idx) == "0")

    {

        lineEdit->setCursorPosition(idx);

        lineEdit->setFocus();

        return;

    }

    strContent.insert(idx, '6');

    lineEdit->setText(strContent);

    lineEdit->setCursorPosition(idx+1);

    lineEdit->setFocus();

}

void NumKeyboard::on_num7Button_clicked()       //7

{

    int idx = lineEdit->cursorPosition();

    if(strContent.left(idx) == "0")

    {

        lineEdit->setCursorPosition(idx);

        lineEdit->setFocus();

        return;

    }

    strContent.insert(idx, '7');

    lineEdit->setText(strContent);

    lineEdit->setCursorPosition(idx+1);

    lineEdit->setFocus();

}

void NumKeyboard::on_num8Button_clicked()       //8

{

    int idx = lineEdit->cursorPosition();

    if(strContent.left(idx) == "0")

    {

        lineEdit->setCursorPosition(idx);

        lineEdit->setFocus();

        return;

    }

    strContent.insert(idx, '8');

    lineEdit->setText(strContent);

    lineEdit->setCursorPosition(idx+1);

    lineEdit->setFocus();

}

void NumKeyboard::on_num9Button_clicked()       //9

{

    int idx = lineEdit->cursorPosition();

    if(strContent.left(idx) == "0")

    {

        lineEdit->setCursorPosition(idx);

        lineEdit->setFocus();

        return;

    }

    strContent.insert(idx, '9');

    lineEdit->setText(strContent);

    lineEdit->setCursorPosition(idx+1);

    lineEdit->setFocus();

}

void NumKeyboard::on_dotButton_clicked()        //.

{

    int idx = lineEdit->cursorPosition();

    // if(idx==0 || strContent.contains('.'))

    // {

    //     lineEdit->setCursorPosition(idx);

    //     lineEdit->setFocus();

    //     return;

    // }

    strContent.insert(idx, '.');

    lineEdit->setText(strContent);

    lineEdit->setCursorPosition(idx+1);

    lineEdit->setFocus();

}

void NumKeyboard::on_num0Button_clicked()       //0

{

    int idx = lineEdit->cursorPosition();

    if(strContent.left(idx) == "0" || (idx==0 &&strContent!=""))

    {

        lineEdit->setCursorPosition(idx);

        qDebug()<<"idx"<<idx;

        lineEdit->setFocus();

        return;

    }

    strContent.insert(idx, '0');

    lineEdit->setText(strContent);

    lineEdit->setCursorPosition(idx+1);

    lineEdit->setFocus();

}

void NumKeyboard::on_signButton_clicked()       //±

{

    int idx = lineEdit->cursorPosition();

    if(strContent.left(1) == "-")

    {

        strContent.remove(0, 1);

        lineEdit->setText(strContent);

        lineEdit->setCursorPosition(idx-1);

        lineEdit->setFocus();

    }

    else

    {

        if(strContent=="0" /*|| strContent==""*/)

        {

            lineEdit->setCursorPosition(idx);

            lineEdit->setFocus();

        }

        else

        {

            strContent.insert(0, '-');

            lineEdit->setText(strContent);

            lineEdit->setCursorPosition(idx+1);

            lineEdit->setFocus();

        }

    }

}

 void NumKeyboard::on_clearButton_clicked()            //清除

 {

     int idx = lineEdit->cursorPosition();

     if(idx == 0)

     {

         lineEdit->setCursorPosition(idx);

         lineEdit->setFocus();

         return;

     }

     //strContent.remove(0,idx);

     strContent.clear();

     lineEdit->setText(strContent);

     lineEdit->setCursorPosition(0);

     lineEdit->setFocus();

 }

void NumKeyboard::on_delButton_clicked()      //删除

{

    int idx = lineEdit->cursorPosition();

    if(idx == 0)

    {

        lineEdit->setCursorPosition(idx);

        lineEdit->setFocus();

        return;

    }

    strContent.remove(idx-1,1);

    lineEdit->setText(strContent);

    lineEdit->setCursorPosition(idx-1);

    lineEdit->setFocus();

}

void NumKeyboard::on_cancelButton_clicked()     //cancel

{

    this->close();

    valid = false;

}

void NumKeyboard::on_okButton_clicked()         //ok

{

    this->close();

    valid = true;

}

void NumKeyboard::setText(QString str)      //设置文本内容

{

    strContent = str;

    lineEdit->setText(strContent);

    lineEdit->setFocus();

}

QString NumKeyboard::getText()              //获取内容

{

    return strContent;

}

3.测试代码

#include "widget.h"

#include "ui_widget.h"

#include <QTime>

#include <QCoreApplication>

#include <QMessageBox>

#include "QListView"

Widget::Widget(QWidget *parent) :

    QWidget(parent),

    ui(new Ui::Widget)

{

    ui->setupUi(this);

    ui->lineEdit_freq->installEventFilter(this); // 确保这行代码存在

    numkeyboard = new NumKeyboard();      //数字键盘

}

Widget::~Widget()

{

    qDebug()<<">>>>~Widget()";

    delete ui;

}

bool Widget::eventFilter(QObject *watched, QEvent *event)

{

    if(watched == ui->lineEdit_freq && event->type()==QEvent::MouseButtonPress)

    {

        numkeyboard->setText(ui->lineEdit_freq->text());  //当前的文本框的内容,this->指向的是SoftKeyLineEdit

        numkeyboard->exec();

        if(numkeyboard->valid)

        {

            ui->lineEdit_freq->setText(numkeyboard->getText());  //此处的setText是继承QLineEdit的,numkeyboard->setTex是自定义的,目的是获取当前的文本

        }

        return true; // 表示已处理该事件

    }

    return QWidget::eventFilter(watched, event); // 其他事件交基类处理

}

4.效果图

三.调用windows的自带软键盘osk.exe

1.代码

#include "mainwindow.h"

#include "ui_mainwindow.h"

#include <qmessagebox.h>

#include <QProcess>

#include <qdebug.h>

#include <qdesktopservices.h>

#include <QUrl>

#include <windows.h>

#pragma comment(lib,"user32.lib")

MainWindow::MainWindow(QWidget *parent)

    : QMainWindow(parent)

    , ui(new Ui::MainWindow)

{

    ui->setupUi(this);

    ui->lineEdit->clear();

    ui->lineEdit_2->clear();

    ui->lineEdit->installEventFilter(this);

    ui->lineEdit_2->installEventFilter(this);

}

MainWindow::~MainWindow()

{

    delete ui;

}

void MainWindow::on_pushButton_clicked()

{

    PVOID Oldvalue = nullptr;

    BOOL bRet = Wow64DisableWow64FsRedirection(&Oldvalue);

    QString csprocess = "C:\\Windows\\System32\\osk.exe";

    QString param = "";

    ShellExecute(nullptr,L"open",(LPCWSTR)csprocess.utf16(),(LPCWSTR)param.utf16(),nullptr,SW_SHOWNORMAL);

    if(bRet)

    {

        Wow64RevertWow64FsRedirection(Oldvalue);

    }

//发现及设置键盘大小 2025.6.24+

    // 尝试查找屏幕键盘窗口

    m_hOskWnd = FindWindowW(L"OSKMainClass", nullptr);

    // 设置窗口尺寸 (宽度x高度)

    int newWidth = 300;  // 设置所需宽度

    int newHeight = 300; // 设置所需高度

    // 获取屏幕尺寸以居中窗口

    int screenWidth = GetSystemMetrics(SM_CXSCREEN);

    int screenHeight = GetSystemMetrics(SM_CYSCREEN);

    int xPos = (screenWidth - newWidth) / 2;

    int yPos = (screenHeight - newHeight) * 2 / 4; // 底部2/4处

    // 调整窗口大小和位置

    SetWindowPos(m_hOskWnd, nullptr,

                 xPos, yPos,

                 newWidth, newHeight,

                 SWP_NOZORDER | SWP_NOACTIVATE);

    qDebug() << "On-screen keyboard resized to"

             << newWidth << "x" << newHeight;

}

2.效果图

相关文章:

  • 腾讯混元API调用优化实战:用API网关实现流量控制+缓存+监控
  • 2-深度学习挖短线股-3-训练数据计算
  • 【windows处理技巧】如何缩小PDF
  • 鸿蒙边缘智能计算架构实战:多线程图像采集与高可靠缓冲设计
  • LeetCode 2311.小于等于 K 的最长二进制子序列:贪心(先选0再选1)-好像还是比灵神写的清晰些
  • VUE3入门很简单(3)--- watch
  • SpringBoot项目快速开发框架JeecgBoot——Web处理!
  • [AI]从0到1通过神经网络训练模型
  • Docker 入门教程(一):从概念到第一个容器
  • 【C++】ATM机模拟系统 :完整窗口实现
  • 【论文】云原生事件驱动架构在智能风控系统中的实践与思考
  • 抖音图文带货和短视频带货有什么区别
  • 玄机抽奖Spring Web项目
  • 9. 回文数
  • linux网络编程socket套接字
  • 与 AI 聊天更顺畅:cat_code.py
  • MySQL5.7和8.0 破解root密码
  • C++ STL ——string的使用讲解及其底层实现
  • react-嵌套路由 二级路由
  • 128K 长文本处理实战:腾讯混元 + 云函数 SCF 构建 PDF 摘要生成器