【QT】QT中的软键盘设计
QT的软键盘设计
- 1.软键盘制作步骤
- 2.介绍有关函数的使用
- 3.出现的编译错误及解决办法
- 示例代码1:按键事件实现软键盘
- 现象:
- 示例代码2:按键事件实现软键盘(加特殊按键)
- 现象:
- 软键盘移植到新的工程的步骤:
- 自定义软键盘设计步骤:图示
QT中右键提升一个组件:作用就是把这个组件的类型变成提升之后的新类型,若程序员自己想要自定义实现某个控件的功能,就可用该功能
1.软键盘制作步骤
第一步:在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.介绍有关函数的使用
QKeyEvent::QKeyEvent(Type type, int key, Qt::KeyboardModifiers modifiers, const QString &text = QString())参数: type --》事件类型 QEvent::KeyPresskey --》按键的键值 摸索规律:字母按键(无论大小写)键值 A/a 65B/b 66modifiers --》你是否使用了某个组合键Qt::NoModifier //没有使用组合键Qt::ShiftModifier //使用了shift按键text --》点击的按键的字面值
//把指定的事件发送出去
[static] void QCoreApplication::postEvent(QObject *receiver, QEvent *event)参数:receiver --》事件的接收者event --》要发送的某种事件
//鼠标的光标停留在哪个组件上,该函数立马返回这个组件的地址
[static] QWidget *QApplication::focusWidget() //返回鼠标光标聚集的组件
3.出现的编译错误及解决办法
第一个: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:按键事件实现软键盘
当前目录结构:
// widget.h
#ifndef WIDGET_H
#define WIDGET_H#include <QWidget>
#include <QDebug>QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACEclass Widget : public QWidget
{Q_OBJECTpublic: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_OBJECTpublic: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 0if (!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的差别是在槽函数中增加了特殊按键的判断
// 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 0if (!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++类)中关联信号与槽函数,在槽函数中实现按键的逻辑
#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-32QKeyEvent *keyevent=new QKeyEvent(QEvent::KeyPress,str.toInt() - 32,Qt::NoModifier,str);//把这个按键事件发送出去--》发送个鼠标光标聚集的组件QCoreApplication::postEvent(QApplication::focusWidget(),keyevent);
}
11.现象如下