【QT】QT中的软键盘设计

QT的软键盘设计

QT中右键提升一个组件:作用就是把这个组件的类型变成提升之后的新类型,若程序员自己想要自定义实现某个控件的功能,就可用该功能

1.软键盘制作步骤

cpp 复制代码
第一步:在QT工程中新添加一个软键盘的ui(模板选择QWidget),并布局好软键盘的ui
         顺便把按钮的focusPolicy这个属性改成noFocus(没有鼠标焦点,鼠标光标不会在按钮上停留)
第二步:在你的主窗口中拖一个widget(等一会软键盘嵌套到这个widget中来显示的),右键点击widget,选择提升为刚才新建的软键盘类
第三步:实现软键盘的代码逻辑(让软键盘可以使用)
    思路一:使用传统的方法,信号与槽(很麻烦)
    思路二:使用QT中的按键事件来实现软键盘
    在QT工程新增一个mybutton的类继承QPushButton(按钮类),关联信号与槽函数,在槽函数中实现按键的逻辑
第四步:mybutton里面的槽函数代码如下
      //获取信号的发送者
      QPushButton *p=qobject_cast<QPushButton *>(sender());
      QString str=p->text(); // 获取按钮的字面值
      //按照事件产生的流程去写代码
      //自定义一个按键事件
      QKeyEvent *keyevent=new QKeyEvent(QEvent::KeyPress,str.toInt()-32,Qt::NoModifier,str);
      //把这个按键事件发送出去--》发送个鼠标光标聚集的组件
      QCoreApplication::postEvent(QApplication::focusWidget(),keyevent);

2.介绍有关函数的使用

cpp 复制代码
QKeyEvent::QKeyEvent(Type type, int key, Qt::KeyboardModifiers modifiers, const QString &text = QString())
            参数: type --》事件类型  QEvent::KeyPress
                  key --》按键的键值 
                                     摸索规律:字母按键(无论大小写)
                                               键值  A/a   65
                                                        B/b   66
                  modifiers --》你是否使用了某个组合键
                                Qt::NoModifier  //没有使用组合键
                                Qt::ShiftModifier  //使用了shift按键
                  text --》点击的按键的字面值
//把指定的事件发送出去
[static] void QCoreApplication::postEvent(QObject *receiver, QEvent *event)
            参数:receiver --》事件的接收者
                  event --》要发送的某种事件
//鼠标的光标停留在哪个组件上,该函数立马返回这个组件的地址
[static] QWidget *QApplication::focusWidget()  //返回鼠标光标聚集的组件

3.出现的编译错误及解决办法

cpp 复制代码
第一个:QObject::connect: No such slot QPushButton::fun() in ..\solfkeydemo\mybutton.cpp:6
     原因:你的mybutton这个类中使用了信号与槽,忘记添加Q_OBJECT这个宏定义了
     解决方法:在mybutton的头文件中把Q_OBJECT这个宏定义加上即可
第二个:C:\Users\PC\Desktop\share\solfkeydemo\mybutton.cpp:3: error: undefined reference to `vtable for mybutton'
     解决方法:把编译产生的临时文件全部删除,重新打开工程,再次编译   

示例代码1:按键事件实现软键盘

当前目录结构:

cpp 复制代码
// widget.h
#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QDebug>

QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();

private:
    Ui::Widget *ui;
};
#endif // WIDGET_H

// widget.cpp
#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    qDebug()<<"Widget::Widget 构造";
}

Widget::~Widget()
{
    delete ui;
}
//=======================================================//
// soft_keyboard.h
#ifndef SOFT_KEYBOARD_H
#define SOFT_KEYBOARD_H

#include <QWidget>
#include <QDebug>

namespace Ui {
class soft_keyboard;
}

class soft_keyboard : public QWidget
{
    Q_OBJECT

public:
    explicit soft_keyboard(QWidget *parent = nullptr);
    ~soft_keyboard();

private:
    Ui::soft_keyboard *ui;
};

#endif // SOFT_KEYBOARD_H

// soft_keyboard.cpp
#include "soft_keyboard.h"
#include "ui_soft_keyboard.h"

soft_keyboard::soft_keyboard(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::soft_keyboard)
{
    ui->setupUi(this);
    qDebug()<<"soft_keyboard::soft_keyboard 构造";
}

soft_keyboard::~soft_keyboard()
{
    delete ui;
}
//=======================================================//
// custom_button.h
#ifndef CUSTOM_BUTTON_H
#define CUSTOM_BUTTON_H

#include <QPushButton>
#include <QDebug>
#include <QCoreApplication>
#include <QKeyEvent>
#include <QApplication>

class custom_button : public QPushButton
{
    Q_OBJECT
public:
    explicit custom_button(QWidget *parent = nullptr);

private slots:
    void func();
};

#endif // CUSTOM_BUTTON_H

// custom_button.cpp
#include "custom_button.h"

custom_button::custom_button(QWidget *parent) : QPushButton(parent)
{
    qDebug()<<"custom_button 构造";
    connect(this, &QPushButton::clicked, this, &custom_button::func);
//    connect(this, SIGNAL(clicked()), this, SLOT(func()));
}

void custom_button::func()
{
    //获取信号的发送者
    QPushButton *p=qobject_cast<QPushButton *>(sender());
    QString str=p->text(); // 获取按钮的字面值
#if 0
    if (!str.isEmpty()) {
        QChar ch = str.at(0);
        int key = ch.toUpper().unicode(); // 获取大写字符的键值
        QKeyEvent *keyevent = new QKeyEvent(
            QEvent::KeyPress,
            key,
            Qt::NoModifier,
            QString(ch)
        );
        QCoreApplication::postEvent(QApplication::focusWidget(), keyevent);
    }
#else
    //按照事件产生的流程写代码
    //自定义一个按键事件
    QKeyEvent *keyevent=new QKeyEvent(QEvent::KeyPress,str.toInt() - 32,Qt::NoModifier,str);
    //把这个按键事件发送出去--》发送给鼠标光标聚集的组件
    QCoreApplication::postEvent(QApplication::focusWidget(),keyevent);
#endif
}

现象:

示例代码2:按键事件实现软键盘(加特殊按键)

与示例代码1的差别是在槽函数中增加了特殊按键的判断

cpp 复制代码
// custom_button.h
#ifndef CUSTOM_BUTTON_H
#define CUSTOM_BUTTON_H

#include <QPushButton>
#include <QDebug>
#include <QCoreApplication>
#include <QKeyEvent>
#include <QApplication>

class custom_button : public QPushButton
{
    Q_OBJECT
public:
    explicit custom_button(QWidget *parent = nullptr);

private slots:
    void func();
};

#endif // CUSTOM_BUTTON_H

// custom_button.cpp
#include "custom_button.h"

custom_button::custom_button(QWidget *parent) : QPushButton(parent)
{
    qDebug()<<"custom_button 构造";
    connect(this, &QPushButton::clicked, this, &custom_button::func);
//    connect(this, SIGNAL(clicked()), this, SLOT(func()));
}

void custom_button::func()
{
    //获取信号的发送者
    QPushButton *p=qobject_cast<QPushButton *>(sender());
    QString str=p->text(); // 获取按钮的字面值
#if 0
    if (!str.isEmpty()) {
        QChar ch = str.at(0);
        int key = ch.toUpper().unicode(); // 获取大写字符的键值
        QKeyEvent *keyevent = new QKeyEvent(
            QEvent::KeyPress,
            key,
            Qt::NoModifier,
            QString(ch)
        );
        QCoreApplication::postEvent(QApplication::focusWidget(), keyevent);
    }
#else
    //按照事件产生的流程写代码
    QKeyEvent *keyevent;
    //判断特殊按键
    if(str=="Backspace") //退格键
    {
        //自定义一个按键事件
        keyevent=new QKeyEvent(QEvent::KeyPress,Qt::Key_Backspace,Qt::NoModifier,str);
    }
    else if(str=="Enter")
    {
        //自定义一个按键事件
        keyevent=new QKeyEvent(QEvent::KeyPress,Qt::Key_Enter,Qt::NoModifier,str);
    }
    else if(str=="")
    {
        //自定义一个按键事件
        keyevent=new QKeyEvent(QEvent::KeyPress,Qt::Key_Space,Qt::NoModifier," ");
    }
    else //字母按键
    {
        //自定义一个按键事件
        keyevent=new QKeyEvent(QEvent::KeyPress,str.toInt()-32,Qt::NoModifier,str);
    }
    //把这个按键事件发送出去--》发送给鼠标光标聚集的组件
    QCoreApplication::postEvent(QApplication::focusWidget(),keyevent);
#endif
}

现象:

软键盘移植到新的工程的步骤:

1.将已实现的功能代码copy到新工程目录下

2.在工程文件名下右键---》添加现有文件

3.选择第一步copy过去的文件进行添加

4.在新工程中设计界面,将widget类提升为自定义的软键盘类

5.编译后即可使用

自定义软键盘设计步骤:图示

1.先在主窗口设计好界面,此时可以看到widget的类为QWidget(这个widget就是用来存放软件的)

2.新建一个UI界面用来设计软键盘(添加新的设计师界面类)

3.右键widget控件,选择提升为...,将该widget提升为上一步自定义的软键盘界面类

4.填写提升的类名称,如下

5.此时可以看到已将widget提升为自定义的软键盘类

7.编译后也可以看到已经显示到主窗口

7.新建一个C++类,使其继承自QPushButton (用来实现软键盘的功能)

8.将软键盘界面的按钮类提升为新建的C++类,此时该软键盘界面使用的就是该类写好的功能

9.将焦点策略改为不聚焦,这样在点击按钮时,此时的焦点就不是是按钮,而是单行输入框,这样就可以根据新建的C++类写好的事件进行处理

9.在新建的custom_button类(这里是上边提到的新建的C++类)中关联信号与槽函数,在槽函数中实现按键的逻辑

cpp 复制代码
#include "custom_button.h"

custom_button::custom_button(QWidget *parent) : QPushButton(parent)
{
    qDebug()<<"custom_button 构造";
    connect(this, &QPushButton::clicked, this, &custom_button::func);
//    connect(this, SIGNAL(clicked()), this, SLOT(func()));
}

void custom_button::func()
{
    //获取信号的发送者
    QPushButton *p=qobject_cast<QPushButton *>(sender());
    QString str=p->text(); // 获取按钮的字面值
    qDebug()<<"str.toInt():"<<str.toInt();
    //按照事件产生的流程写代码
    //自定义一个按键事件  str.toInt()-32 :输入按钮字面值的ASCII 值 -32 如输入a:即键值是97-32
    QKeyEvent *keyevent=new QKeyEvent(QEvent::KeyPress,str.toInt() - 32,Qt::NoModifier,str);
    //把这个按键事件发送出去--》发送个鼠标光标聚集的组件
    QCoreApplication::postEvent(QApplication::focusWidget(),keyevent);
}

11.现象如下

相关推荐
Enti7c29 分钟前
JavaScript 实现输入框的撤销功能
开发语言·javascript·ecmascript
Miracle&1 小时前
Qt 显示QRegExp 和 QtXml 不存在问题
开发语言·qt
秋风&萧瑟2 小时前
【QT】QT中的事件
开发语言·qt
(・Д・)ノ2 小时前
python打卡day16
开发语言·python
泪光29293 小时前
科创大赛——知识点复习【c++】——第一篇
开发语言·c++
Hzhile3 小时前
攻防世界-php伪协议和文件包含
android·开发语言·安全·web安全·网络安全·php
程序员曼布4 小时前
ThreadLocal源码深度剖析:内存管理与哈希机制
java·开发语言·哈希算法
边疆.4 小时前
【C++】模板进阶
开发语言·c++·模板
o0向阳而生0o4 小时前
36、C#中的⽅法声明参数关键字params,ref,out的意义及⽤法
开发语言·c#·.net