Qt键盘输入法的开源方案

1. 官方方案

Qt Virtual Keyboard(推荐)

GitHubhttps://code.qt.io/cgit/qt/qtvirtualkeyboard.git/

cpp

// 启用方法 qputenv("QT_IM_MODULE", QByteArray("qtvirtualkeyboard")); // 或者在main.cpp中 #include <QtVirtualKeyboard> 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使用:

1. 基础配置和头文件

项目文件 (.pro)

pro

QT += core gui widgets virtualkeyboard # 启用虚拟键盘模块 DEFINES += QT_VIRTUALKEYBOARD_DEFAULT_STYLE=\"default\" CONFIG += c++17

主函数配置 (main.cpp)

cpp

#include <QApplication> #include <QWidget> #include <QLineEdit> #include <QTextEdit> #include <QVBoxLayout> #include <QtVirtualKeyboard> 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. 自定义虚拟键盘管理器

VirtualKeyboardManager.h

cpp

#ifndef VIRTUALKEYBOARDMANAGER_H #define VIRTUALKEYBOARDMANAGER_H #include <QObject> #include <QWidget> #include <QInputMethod> #include <QEvent> #include <QApplication> 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_H

VirtualKeyboardManager.cpp

cpp

#include "VirtualKeyboardManager.h" #include <QDebug> 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::FocusOut) { // 可选:失去焦点时隐藏键盘 // hideKeyboard(); } else if (event->type() == QEvent::Close) { hideKeyboard(); } return QObject::eventFilter(obj, event); }

3. 自定义输入控件

VirtualInputWidget.h

cpp

#ifndef VIRTUALINPUTWIDGET_H #define VIRTUALINPUTWIDGET_H #include <QLineEdit> #include <QFocusEvent> class VirtualInputWidget : public QLineEdit { Q_OBJECT public: explicit VirtualInputWidget(QWidget *parent = nullptr); protected: void focusInEvent(QFocusEvent *event) override; void mousePressEvent(QMouseEvent *event) override; signals: void inputActivated(); }; #endif // VIRTUALINPUTWIDGET_H

VirtualInputWidget.cpp

cpp

#include "VirtualInputWidget.h" #include "VirtualKeyboardManager.h" VirtualInputWidget::VirtualInputWidget(QWidget *parent) : QLineEdit(parent) { } void VirtualInputWidget::focusInEvent(QFocusEvent *event) { QLineEdit::focusInEvent(event); emit inputActivated(); // 通知键盘管理器显示键盘 VirtualKeyboardManager::instance().setInputFocusWidget(this); } void VirtualInputWidget::mousePressEvent(QMouseEvent *event) { QLineEdit::mousePressEvent(event); emit inputActivated(); VirtualKeyboardManager::instance().setInputFocusWidget(this); }

4. 增强的键盘控制器

EnhancedKeyboardController.h

cpp

#ifndef ENHANCEDKEYBOARDCONTROLLER_H #define ENHANCEDKEYBOARDCONTROLLER_H #include <QObject> #include <QWidget> #include <QInputMethod> #include <QTimer> class EnhancedKeyboardController : public QObject { Q_OBJECT public: explicit EnhancedKeyboardController(QWidget *parent = nullptr); ~EnhancedKeyboardController(); void enableAutoShow(bool enable = true); void setKeyboardTheme(const QString &theme); void setKeyboardLanguage(const QString &language); void showKeyboard(); void hideKeyboard(); void toggleKeyboard(); public slots: void onApplicationStateChanged(Qt::ApplicationState state); private slots: void checkFocus(); private: QInputMethod *m_inputMethod; QTimer *m_focusCheckTimer; bool m_autoShowEnabled; QWidget *m_lastFocusedWidget; }; #endif // ENHANCEDKEYBOARDCONTROLLER_H

EnhancedKeyboardController.cpp

cpp

#include "EnhancedKeyboardController.h" #include <QGuiApplication> #include <QDebug> #include <QWidget> EnhancedKeyboardController::EnhancedKeyboardController(QWidget *parent) : QObject(parent), m_inputMethod(nullptr), m_autoShowEnabled(true), m_lastFocusedWidget(nullptr) { m_inputMethod = QGuiApplication::inputMethod(); // 创建焦点检查定时器 m_focusCheckTimer = new QTimer(this); m_focusCheckTimer->setInterval(100); connect(m_focusCheckTimer, &QTimer::timeout, this, &EnhancedKeyboardController::checkFocus); m_focusCheckTimer->start(); // 监听应用状态变化 connect(qApp, &QApplication::applicationStateChanged, this, &EnhancedKeyboardController::onApplicationStateChanged); } EnhancedKeyboardController::~EnhancedKeyboardController() { m_focusCheckTimer->stop(); } void EnhancedKeyboardController::enableAutoShow(bool enable) { m_autoShowEnabled = enable; } void EnhancedKeyboardController::setKeyboardTheme(const QString &theme) { qputenv("QT_QUICK_CONTROLS_STYLE", theme.toUtf8()); } void EnhancedKeyboardController::setKeyboardLanguage(const QString &language) { // 设置键盘语言环境 qputenv("QT_VIRTUALKEYBOARD_DEFAULT_LANG", language.toUtf8()); } void EnhancedKeyboardController::showKeyboard() { if (m_inputMethod && !m_inputMethod->isVisible()) { m_inputMethod->show(); qDebug() << "Keyboard shown programmatically"; } } void EnhancedKeyboardController::hideKeyboard() { if (m_inputMethod && m_inputMethod->isVisible()) { m_inputMethod->hide(); qDebug() << "Keyboard hidden programmatically"; } } void EnhancedKeyboardController::toggleKeyboard() { if (m_inputMethod->isVisible()) { hideKeyboard(); } else { showKeyboard(); } } void EnhancedKeyboardController::onApplicationStateChanged(Qt::ApplicationState state) { if (state != Qt::ApplicationActive) { hideKeyboard(); } } void EnhancedKeyboardController::checkFocus() { if (!m_autoShowEnabled) return; QWidget *focusedWidget = QApplication::focusWidget(); if (focusedWidget && focusedWidget != m_lastFocusedWidget) { m_lastFocusedWidget = focusedWidget; // 检查是否是文本输入控件 if (focusedWidget->inherits("QLineEdit") || focusedWidget->inherits("QTextEdit") || focusedWidget->inherits("QPlainTextEdit") || focusedWidget->inherits("QComboBox")) { showKeyboard(); } else { hideKeyboard(); } } }

2. 第三方开源输入法框架

Maliit 框架

GitHubhttps://github.com/maliit/framework

bash

# Ubuntu安装 sudo apt install maliit-framework-server maliit-inputmethod-context # 在Qt中使用 qputenv("QT_IM_MODULE", QByteArray("maliit"));

Fcitx5 框架

GitHubhttps://github.com/fcitx/fcitx5

cpp

// 支持Qt的输入法框架 qputenv("QT_IM_MODULE", QByteArray("fcitx"));

IBus 框架

GitHubhttps://github.com/ibus/ibus

cpp

qputenv("QT_IM_MODULE", QByteArray("ibus"));

3. 专门为Qt设计的开源虚拟键盘

QVirtualKeyboard

GitHubhttps://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

GitHubhttps://github.com/mbasaglia/QtOnScreenKeyboard

cpp

#include "keyboardwidget.h" // 在需要的地方显示键盘 KeyboardWidget *keyboard = new KeyboardWidget(this); keyboard->setTargetWidget(yourTextEdit); keyboard->show();

QmlKeyboard

GitHubhttps://github.com/kanryu/qmlkeyboard

qml

import QtQuick 2.0 import QmlKeyboard 1.0 ApplicationWindow { TextField { id: textField } Keyboard { target: textField anchors.bottom: parent.bottom } }

4. 嵌入式设备专用方案

T9拼音输入法 for Qt

GitHubhttps://github.com/supertable/t9qt

cpp

#include "t9inputmethod.h" T9InputMethod *t9 = new T9InputMethod(this); t9->setInputField(yourLineEdit); t9->show();

Qt5ChineseInputMethod

GitHubhttps://github.com/CodeZry/Qt5ChineseInputMethod

支持拼音、五笔等中文输入法。

5. 自定义实现的完整示例

简单虚拟键盘实现

keyboardwidget.h:

cpp

#ifndef KEYBOARDWIDGET_H #define KEYBOARDWIDGET_H #include <QWidget> #include <QPushButton> #include <QGridLayout> #include <QLineEdit> 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 <QApplication> 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(); // 输入完成隐藏键盘 }

6. 使用建议

环境配置

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是最稳定和功能最全的选择。

Read more

[特殊字符] Python在CentOS系统执行深度指南

[特殊字符] Python在CentOS系统执行深度指南

文章目录 * 1 Python环境安装与配置问题 * 1.1 系统自带Python的限制 * 1.2 安装Python 3的常见问题及解决方案 * 1.3 SSL模块问题解决方案 * 1.4 环境变量配置与管理 * 1.5 软件集合(SCL)替代方案 * 2 包管理与虚拟环境问题 * 2.1 pip包管理器问题与解决方案 * 2.2 虚拟环境的最佳实践 * 2.3 依赖兼容性问题解决 * 2.4 虚拟环境目录结构理解 * 3 模块导入与路径问题 * 3.1 Python模块搜索路径机制 * 3.2 常见模块导入错误与解决 * 3.3 路径配置最佳实践 * 3.4 特殊模块问题处理 * 3.

By Ne0inhk

ezdxf库终极指南:Python CAD自动化从入门到精通

ezdxf库终极指南:Python CAD自动化从入门到精通 【免费下载链接】ezdxfPython interface to DXF 项目地址: https://gitcode.com/gh_mirrors/ez/ezdxf 想要用Python操控CAD图纸却不知从何入手?ezdxf库为你打开了通往CAD自动化世界的大门。这个纯Python实现的DXF文件处理工具,让你无需安装任何CAD软件就能轻松读写、编辑和生成图纸文件。无论你是机械工程师、建筑设计师,还是数据可视化开发者,掌握ezdxf都将让你的工作效率倍增。 快速入门:5分钟上手ezdxf 安装与环境配置 安装ezdxf库只需一行命令,简单到让人难以置信: pip install ezdxf 验证安装是否成功: import ezdxf print(f"ezdxf版本: {ezdxf.__version__}") 你的第一个DXF文件 让我们从一个简单的例子开始,感受ezdxf的强大之处: import ezdxf # 创建新图纸 -

By Ne0inhk
在 macOS 下升级 Python 几种常见的方法

在 macOS 下升级 Python 几种常见的方法

在 macOS 下升级 Python 有几种常见的方法,具体取决于你最初是如何安装 Python 的。了解你的安装方式是关键。 首先,你需要知道你当前 Python 版本以及它的安装路径。 1. 检查 Python 版本: python --version# 可能指向 Python 2.x python3 --version# 通常指向 Python 3.x 2. 检查 Python 路径: which python which python3 根据你 which 命令的输出,我们可以推断出安装方式。常见的安装方式有: * macOS 系统自带 Python: 通常在 /usr/bin/python。不建议直接修改或升级系统自带的

By Ne0inhk
【Python篇】PyQt5 超详细教程——由入门到精通(序篇)

【Python篇】PyQt5 超详细教程——由入门到精通(序篇)

文章目录 * PyQt5 超详细入门级教程 * 前言 * 序篇:1-3部分:PyQt5基础与常用控件 * 第1部分:初识 PyQt5 和安装 * 1.1 什么是 PyQt5? * 1.2 在 PyCharm 中安装 PyQt5 * 1.3 在 PyCharm 中编写第一个 PyQt5 应用程序 * 1.4 代码详细解释 * 1.5 在 PyCharm 中运行程序 * 1.6 常见问题排查 * 1.7 总结 * 第2部分:创建 PyQt5 应用程序与布局管理 * 2.1 PyQt5 的基本窗口结构

By Ne0inhk