跳到主要内容Qt 键盘输入法开源方案 | 极客日志C++
Qt 键盘输入法开源方案
总结了 Qt 平台下的多种键盘输入法开源方案,涵盖官方 Qt Virtual Keyboard、第三方框架(Maliit、Fcitx5、IBus)、特定 Qt 键盘库及自定义实现。内容包括环境配置、QML 与 QWidget 集成示例、自定义管理器代码及嵌入式场景建议,帮助开发者选择合适的输入方案。
蓝绿部署11K 浏览 1. 官方方案
Qt Virtual Keyboard(推荐)
GitHub: https://code.qt.io/cgit/qt/qtvirtualkeyboard.git/
启用方法
cpp
// 在 main.cpp 中设置环境变量
#include
int main(int argc, char *argv[]) {
qputenv("QT_IM_MODULE", QByteArray("qtvirtualkeyboard"));
QApplication app(argc, argv);
return app.exec();
}
QML 使用
qml
import QtQuick 2.15
import QtQuick.VirtualKeyboard 2.15
ApplicationWindow {
TextField {
id: textField
focus: true
}
InputPanel {
id: keyboard
y: parent.height - keyboard.height
}
}
QWidget 使用
项目文件 (.pro)
pro
QT += core gui widgets virtualkeyboard
DEFINES += QT_VIRTUALKEYBOARD_DEFAULT_STYLE="default"
CONFIG += c++17
主函数配置 (main.cpp)
cpp
#include
#include
#include
#include
#include
#include
int main(int argc, char *argv[]) {
qputenv("QT_IM_MODULE", QByteArray("qtvirtualkeyboard"));
QApplication app(argc, argv);
QWidget window
QVBoxLayout *layout = new QVBoxLayout(&window)
QLineEdit *lineEdit = new QLineEdit()
lineEdit->setPlaceholderText("点击这里显示虚拟键盘")
QTextEdit *textEdit = new QTextEdit()
textEdit->setPlaceholderText("多行文本编辑框")
layout->addWidget(lineEdit)
layout->addWidget(textEdit)
window.resize(400, 300)
window.show()
return app.exec()
2. 自定义虚拟键盘管理器
通过继承 QObject 并监听焦点事件来控制键盘显示。
VirtualKeyboardManager.h
cpp
#ifndef VIRTUALKEYBOARDMANAGER_H
#define VIRTUALKEYBOARDMANAGER_H
#include
#include
#include
#include
#include
class VirtualKeyboardManager : public QObject {
Q_OBJECT
public:
static VirtualKeyboardManager& instance();
void showKeyboard();
void hideKeyboard();
bool isVisible() const;
void setKeyboardParent(QWidget *parent);
void setInputFocusWidget(QWidget *widget);
protected:
bool eventFilter(QObject *obj, QEvent *event) override;
private:
VirtualKeyboardManager(QObject *parent = nullptr);
~VirtualKeyboardManager() = default;
QInputMethod *m_inputMethod;
QWidget *m_focusWidget;
QWidget *m_keyboardParent;
};
#endif
VirtualKeyboardManager.cpp
cpp
#include "VirtualKeyboardManager.h"
#include
VirtualKeyboardManager::VirtualKeyboardManager(QObject *parent)
: QObject(parent), m_inputMethod(nullptr), m_focusWidget(nullptr), m_keyboardParent(nullptr) {
m_inputMethod = QGuiApplication::inputMethod();
qApp->installEventFilter(this);
}
VirtualKeyboardManager& VirtualKeyboardManager::instance() {
static VirtualKeyboardManager instance;
return instance;
}
void VirtualKeyboardManager::showKeyboard() {
if (m_inputMethod) {
m_inputMethod->show();
qDebug() << "Virtual keyboard shown";
}
}
void VirtualKeyboardManager::hideKeyboard() {
if (m_inputMethod) {
m_inputMethod->hide();
qDebug() << "Virtual keyboard hidden";
}
}
bool VirtualKeyboardManager::isVisible() const {
return m_inputMethod ? m_inputMethod->isVisible() : false;
}
void VirtualKeyboardManager::setKeyboardParent(QWidget *parent) {
m_keyboardParent = parent;
}
void VirtualKeyboardManager::setInputFocusWidget(QWidget *widget) {
m_focusWidget = widget;
if (widget) {
widget->setFocus();
showKeyboard();
}
}
bool VirtualKeyboardManager::eventFilter(QObject *obj, QEvent *event) {
if (event->type() == QEvent::FocusIn) {
if (QWidget widget = qobject_cast<QWidget>(obj)) {
if (widget->inherits("QLineEdit") || widget->inherits("QTextEdit") ||
widget->inherits("QPlainTextEdit") || widget->inherits("QComboBox")) {
m_focusWidget = widget;
showKeyboard();
qDebug() << "Focus gained by:" << widget->metaObject()->className();
}
}
} else if (event->type() == QEvent::Close) {
hideKeyboard();
}
return QObject::eventFilter(obj, event);
}
3. 第三方开源输入法框架
Maliit 框架
Ubuntu 安装
sudo apt install maliit-framework-server maliit-inputmethod-context
在 Qt 中使用
qputenv("QT_IM_MODULE", QByteArray("maliit"));
Fcitx5 框架
IBus 框架
4. 专门为 Qt 设计的开源虚拟键盘
QVirtualKeyboard
Rectangle {
width: 800
height: 600
TextInput {
id: textInput
width: 200
height: 30
}
Keyboard {
target: textInput
anchors.bottom: parent.bottom
}
}
QtOnScreenKeyboard
QmlKeyboard
ApplicationWindow {
TextField { id: textField }
Keyboard {
target: textField
anchors.bottom: parent.bottom
}
}
5. 嵌入式设备专用方案
T9 拼音输入法 for Qt
Qt5ChineseInputMethod
6. 自定义实现的完整示例
简单虚拟键盘实现
keyboardwidget.h
cpp
#ifndef KEYBOARDWIDGET_H
#define KEYBOARDWIDGET_H
#include
#include
#include
#include
class KeyboardWidget : public QWidget {
Q_OBJECT
public:
explicit KeyboardWidget(QWidget *parent = nullptr);
void setTargetWidget(QWidget *target);
private slots:
void onKeyClicked();
void onBackspaceClicked();
void onEnterClicked();
void onSpaceClicked();
private:
void setupUI();
QWidget *targetWidget;
QGridLayout *mainLayout;
};
#endif
keyboardwidget.cpp
cpp
#include "keyboardwidget.h"
#include
KeyboardWidget::KeyboardWidget(QWidget *parent)
: QWidget(parent), targetWidget(nullptr) {
setupUI();
setWindowFlags(Qt::Tool | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint);
}
void KeyboardWidget::setupUI() {
mainLayout = new QGridLayout(this);
// 第一行:数字
QStringList row1 = {"1", "2", "3", "4", "5", "6", "7", "8", "9", "0"};
for (int i = 0; i < row1.size(); ++i) {
QPushButton *btn = new QPushButton(row1[i]);
connect(btn, &QPushButton::clicked, this, &KeyboardWidget::onKeyClicked);
mainLayout->addWidget(btn, 0, i);
}
// 第二行:字母
QStringList row2 = {"Q", "W", "E", "R", "T", "Y", "U", "I", "O", "P"};
for (int i = 0; i < row2.size(); ++i) {
QPushButton *btn = new QPushButton(row2[i]);
connect(btn, &QPushButton::clicked, this, &KeyboardWidget::onKeyClicked);
mainLayout->addWidget(btn, 1, i);
}
// 功能键
QPushButton *backspaceBtn = new QPushButton("←");
QPushButton *spaceBtn = new QPushButton("Space");
QPushButton *enterBtn = new QPushButton("Enter");
connect(backspaceBtn, &QPushButton::clicked, this, &KeyboardWidget::onBackspaceClicked);
connect(spaceBtn, &QPushButton::clicked, this, &KeyboardWidget::onSpaceClicked);
connect(enterBtn, &QPushButton::clicked, this, &KeyboardWidget::onEnterClicked);
mainLayout->addWidget(backspaceBtn, 2, 0, 1, 2);
mainLayout->addWidget(spaceBtn, 2, 2, 1, 6);
mainLayout->addWidget(enterBtn, 2, 8, 1, 2);
}
void KeyboardWidget::setTargetWidget(QWidget *target) {
targetWidget = target;
}
void KeyboardWidget::onKeyClicked() {
if (!targetWidget) return;
QPushButton btn = qobject_cast<QPushButton>(sender());
if (btn) {
QString text = btn->text();
if (QLineEdit lineEdit = qobject_cast<QLineEdit>(targetWidget)) {
lineEdit->insert(text);
}
}
}
void KeyboardWidget::onBackspaceClicked() {
if (!targetWidget) return;
if (QLineEdit lineEdit = qobject_cast<QLineEdit>(targetWidget)) {
lineEdit->backspace();
}
}
void KeyboardWidget::onSpaceClicked() {
if (targetWidget && qobject_cast<QLineEdit*>(targetWidget)) {
qobject_cast<QLineEdit*>(targetWidget)->insert(" ");
}
}
void KeyboardWidget::onEnterClicked() {
hide();
}
7. 使用建议
环境配置
检查可用的输入法模块
ls /usr/lib/x86_64-linux-gnu/qt5/plugins/platforminputcontexts/
设置环境变量
export QT_IM_MODULE=qtvirtualkeyboard
项目配置(.pro 文件)
如果使用 Qt Virtual Keyboard
或者手动链接
LIBS += -lqtvirtualkeyboard
平台特定说明
- Linux: 支持最好,多种框架可选
- Windows: 推荐使用 Qt Virtual Keyboard
- 嵌入式 Linux: 考虑性能,选择轻量级方案
- Android/iOS: 通常使用系统自带键盘
根据你的具体需求(中文输入、嵌入式设备、桌面应用等)选择合适的方案。对于大多数情况,Qt Virtual Keyboard是最稳定和功能最全的选择。
微信扫一扫,关注极客日志
微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog
相关免费在线工具
- Base64 字符串编码/解码
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
- Base64 文件转换器
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online
- Markdown转HTML
将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online
- HTML转Markdown
将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online
- JSON 压缩
通过删除不必要的空白来缩小和压缩JSON。 在线工具,JSON 压缩在线工具,online
- JSON美化和格式化
将JSON字符串修饰为友好的可读格式。 在线工具,JSON美化和格式化在线工具,online