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 框架
GitHub: https://github.com/maliit/framework bash
Ubuntu 安装
sudo apt install maliit-framework-server maliit-inputmethod-context
在 Qt 中使用
qputenv("QT_IM_MODULE", QByteArray("maliit"));
Fcitx5 框架
GitHub: https://github.com/fcitx/fcitx5 cpp // 支持 Qt 的输入法框架 qputenv("QT_IM_MODULE", QByteArray("fcitx"));
IBus 框架
GitHub: https://github.com/ibus/ibus cpp qputenv("QT_IM_MODULE", QByteArray("ibus"));
4. 专门为 Qt 设计的开源虚拟键盘
QVirtualKeyboard
GitHub: https://github.com/kanryu/quickvirtualkeyboard qml import QtQuick 2.0 import QuickVirtualKeyboard 1.0
Rectangle { width: 800 height: 600 TextInput { id: textInput width: 200 height: 30 } Keyboard { target: textInput anchors.bottom: parent.bottom } }
QtOnScreenKeyboard
GitHub: https://github.com/mbasaglia/QtOnScreenKeyboard cpp #include "keyboardwidget.h" // 在需要的地方显示键盘 KeyboardWidget *keyboard = new KeyboardWidget(this); keyboard->setTargetWidget(yourTextEdit); keyboard->show();
QmlKeyboard
GitHub: https://github.com/kanryu/qmlkeyboard qml import QtQuick 2.0 import QmlKeyboard 1.0
ApplicationWindow { TextField { id: textField } Keyboard { target: textField anchors.bottom: parent.bottom } }
5. 嵌入式设备专用方案
T9 拼音输入法 for Qt
GitHub: https://github.com/supertable/t9qt cpp #include "t9inputmethod.h" T9InputMethod *t9 = new T9InputMethod(this); t9->setInputField(yourLineEdit); t9->show();
Qt5ChineseInputMethod
GitHub: https://github.com/CodeZry/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. 使用建议
环境配置
bash
检查可用的输入法模块
ls /usr/lib/x86_64-linux-gnu/qt5/plugins/platforminputcontexts/
设置环境变量
export QT_IM_MODULE=qtvirtualkeyboard
项目配置(.pro 文件)
pro
如果使用 Qt Virtual Keyboard
QT += virtualkeyboard
或者手动链接
LIBS += -lqtvirtualkeyboard
平台特定说明
- Linux: 支持最好,多种框架可选
- Windows: 推荐使用 Qt Virtual Keyboard
- 嵌入式 Linux: 考虑性能,选择轻量级方案
- Android/iOS: 通常使用系统自带键盘
根据你的具体需求(中文输入、嵌入式设备、桌面应用等)选择合适的方案。对于大多数情况,Qt Virtual Keyboard是最稳定和功能最全的选择。
