*QT虚拟键盘的实现
:**
在QApplication a(argc, argv);之前加上
qputenv(“QT_IM_MODULE”, QByteArray(“qtvirtualkeyboard”));
即可实现简易的虚拟键盘(qt自带的):
main.cpp
#include "mainwindow.h"
#include <QApplication>
#include"lineedit.h"
#include <QtWidgets>
#include"QDebug"
#define W 1024
#define H 768
int main(int argc, char *argv[]) {
qputenv("QT_IM_MODULE", QByteArray("qtvirtualkeyboard"));
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
但是,会遮盖部分内容,挡住输入内容。
重写QLineEdit(防止虚拟键盘遮挡输入框)
lineedit.h
#ifndef LINEEDIT_H
#define LINEEDIT_H
#include"QLineEdit"
class LineEdit :public QLineEdit {
Q_OBJECT
public:
LineEdit(QWidget *parent = nullptr);
LineEdit(const QString&, QWidget *parent = nullptr);
protected:
bool event(QEvent*) override;
private:
bool _moved = false;
int _lastDiff = 0;
};
#endif // LINEEDIT_H
lineedit.cpp
#include "lineedit.h"
#include <QGuiApplication>
#include"QDebug"
LineEdit::LineEdit(QWidget *parent) :QLineEdit(parent) {
setAttribute(Qt::WA_InputMethodEnabled, true);
setInputMethodHints(inputMethodHints() | Qt::InputMethodHint::ImhPreferLowercase);
}
LineEdit::LineEdit(const QString& txt, QWidget *parent) : QLineEdit(txt, parent) {
//必须在创建自定义文本编辑小部件时设置。
//setAttribute如果on为真,则设置此小部件的属性属性;否则清除属性。void QWidget::setAttribute(Qt::WidgetAttribute attribute, bool on = true)
setAttribute(Qt::WA_InputMethodEnabled, true);
//ImhPreferLowercase小写字母优先(但不是必需)。
//如果设置了Qt::ImhFormattedNumbersOnly标志,输入法可能会改变其可视化组件,以反映只能输入数字。
setInputMethodHints(inputMethodHints() | Qt::InputMethodHint::ImhPreferLowercase);
}
bool LineEdit::event(QEvent* e) {
//keyboardRectangle虚拟键盘的几何图形在窗口坐标。 如果不可能知道键盘的几何形状,这可能是一个空矩形。
const auto keyboard_rect = QGuiApplication::inputMethod()->keyboardRectangle();
const auto keyboard_visible = QGuiApplication::inputMethod()->isVisible();
const auto global_y = QWidget::mapToGlobal(rect().topLeft()).y() + height();
const auto k_global_y = keyboard_rect.topLeft().y();
const auto diff = k_global_y - global_y;
const auto need_to_move = diff < 0;
/* move main widget */
if (keyboard_visible && !_moved && need_to_move) {
_moved = true;
_lastDiff = diff;
const auto g = parentWidget()->frameGeometry();
parentWidget()->move(g.x(), g.y() - qAbs(_lastDiff));
}
/* roll back */
if (!keyboard_visible && _moved) {
_moved = false;
const auto g = parentWidget()->frameGeometry();
parentWidget()->move(g.x(), g.y() + qAbs(_lastDiff));
}
return QLineEdit::event(e);
}
感谢参考文档:https://www.it1352.com/1822481.html