You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PyQt6中如何让指定输入控件分别使用系统键盘与QtVirtualKeyboard?

PyQt6:指定输入框使用Qt虚拟键盘,其余使用系统键盘

通用配置

通过以下步骤完成QtVirtualKeyboard安装:

python3 -m venv venv
venv/bin/pip install -U pip wheel PyQt6 aqtinstall
QT_PREFIX_PATH=$(venv/bin/python -c "from PyQt6.QtCore import QLibraryInfo; print(QLibraryInfo.path(QLibraryInfo.LibraryPath.PrefixPath), end=None)")
QT_VERSION_STR=$(venv/bin/python -c "from PyQt6.QtCore import QT_VERSION_STR; print(QT_VERSION_STR, end=None)")
QT_VERSION_STR=6.7.3
venv/bin/python -m aqt install-qt linux desktop $QT_VERSION_STR -m qtvirtualkeyboard --outputdir qt
cp -p qt/$QT_VERSION_STR/gcc_64/lib/libQt6VirtualKeyboard.so.$QT_VERSION_STR $QT_PREFIX_PATH/lib/libQt6VirtualKeyboard.so.6
cp -p qt/$QT_VERSION_STR/gcc_64/lib/libQt6VirtualKeyboardSettings.so.$QT_VERSION_STR $QT_PREFIX_PATH/lib/libQt6VirtualKeyboardSettings.so.6
mkdir -p $QT_PREFIX_PATH/plugins/platforminputcontexts
cp -p qt/$QT_VERSION_STR/gcc_64/plugins/platforminputcontexts/libqtvirtualkeyboardplugin.so $QT_PREFIX_PATH/plugins/platforminputcontexts
#cp -pr qt/$QT_VERSION_STR/gcc_64/plugins/virtualkeyboard $QT_PREFIX_PATH/plugins
cp -pr qt/$QT_VERSION_STR/gcc_64/qml/QtQuick/VirtualKeyboard $QT_PREFIX_PATH/qml/QtQuick
mkdir -p $QT_PREFIX_PATH/qml/Qt/labs
cp -pr qt/$QT_VERSION_STR/gcc_64/qml/Qt/labs/folderlistmodel $QT_PREFIX_PATH/qml/Qt/labs

注意:必须强制设置QT_VERSION_STR=6.7.3,因为通过Python脚本获取的6.7.1版本会导致运行时错误(提示找不到6.7.3文件)。

测试基础代码:

from PyQt6.QtWidgets import QApplication, QWidget, QMainWindow, QLineEdit, QVBoxLayout

import sys
import os
os.environ["QT_IM_MODULE"] = "qtvirtualkeyboard"

class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.line_edit = QLineEdit()
        self.line_edit2 = QLineEdit()
        self.layout = QVBoxLayout()
        self.main_widget = QWidget()
        self.main_widget.setLayout(self.layout)
        self.layout.addWidget(self.line_edit)
        self.layout.addWidget(self.line_edit2)
        self.setCentralWidget(self.main_widget)


app = QApplication(sys.argv)

window = MainWindow()
window.show()

app.exec()

启动命令:venv/bin/python test.py,当前所有QLineEdit聚焦时都会显示虚拟键盘。

核心需求

如何修改代码,让第一个QLineEdit使用系统常规键盘,第二个QLineEdit使用QtVirtualKeyboard虚拟键盘?需求背景是虚拟键盘需要使用特定区域设置。


解决方案

以下提供两种可行方案,按需选择:

方案1:焦点事件动态切换输入法模块

通过监听输入框的焦点状态,动态修改QT_IM_MODULE环境变量并重置输入上下文,实现输入法切换。

修改后的完整代码:

from PyQt6.QtWidgets import QApplication, QWidget, QMainWindow, QLineEdit, QVBoxLayout
from PyQt6.QtCore import QEvent

import sys
import os

# 默认使用系统输入法
os.environ["QT_IM_MODULE"] = ""

class VirtualKeyLineEdit(QLineEdit):
    def focusInEvent(self, event):
        # 获得焦点时切换为虚拟键盘
        os.environ["QT_IM_MODULE"] = "qtvirtualkeyboard"
        QApplication.instance().inputContext().reset()
        super().focusInEvent(event)
    
    def focusOutEvent(self, event):
        # 失去焦点时恢复为系统输入法
        os.environ["QT_IM_MODULE"] = ""
        QApplication.instance().inputContext().reset()
        super().focusOutEvent(event)

class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.line_edit = QLineEdit()  # 使用系统键盘
        self.line_edit2 = VirtualKeyLineEdit()  # 使用虚拟键盘
        
        # 可选:为虚拟键盘设置特定区域布局
        # os.environ["QT_VIRTUALKEYBOARD_LAYOUT"] = "zh_CN"
        
        self.layout = QVBoxLayout()
        self.main_widget = QWidget()
        self.main_widget.setLayout(self.layout)
        self.layout.addWidget(self.line_edit)
        self.layout.addWidget(self.line_edit2)
        self.setCentralWidget(self.main_widget)


app = QApplication(sys.argv)
window = MainWindow()
window.show()
app.exec()

方案2:自定义输入上下文(更稳定)

直接加载虚拟键盘插件,为目标输入框指定专属输入上下文,避免全局环境变量切换的潜在问题。

修改后的完整代码:

from PyQt6.QtWidgets import QApplication, QWidget, QMainWindow, QLineEdit, QVBoxLayout
from PyQt6.QtGui import QInputContext
from PyQt6.QtCore import QPluginLoader, QEvent
from PyQt6.QtCore import QLibraryInfo

import sys
import os

class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.line_edit = QLineEdit()  # 使用系统键盘
        self.line_edit2 = QLineEdit()  # 使用虚拟键盘
        
        # 获取Qt插件路径
        qt_prefix = QLibraryInfo.path(QLibraryInfo.LibraryPath.PrefixPath)
        plugin_path = os.path.join(qt_prefix, "plugins", "platforminputcontexts", "libqtvirtualkeyboardplugin.so")
        
        # 加载虚拟键盘输入上下文插件
        loader = QPluginLoader(plugin_path)
        self.virtual_input_ctx = loader.instance()
        
        # 为第二个输入框安装事件过滤器
        self.line_edit2.installEventFilter(self)
        
        # 可选:设置虚拟键盘区域布局
        # os.environ["QT_VIRTUALKEYBOARD_LAYOUT"] = "zh_CN"
        
        self.layout = QVBoxLayout()
        self.main_widget = QWidget()
        self.main_widget.setLayout(self.layout)
        self.layout.addWidget(self.line_edit)
        self.layout.addWidget(self.line_edit2)
        self.setCentralWidget(self.main_widget)
    
    def eventFilter(self, obj, event):
        if obj == self.line_edit2:
            if event.type() == QEvent.Type.FocusIn:
                # 切换为虚拟键盘输入上下文
                QApplication.instance().setInputContext(self.virtual_input_ctx)
            elif event.type() == QEvent.Type.FocusOut:
                # 恢复默认系统输入上下文
                QApplication.instance().setInputContext(QInputContext())
        return super().eventFilter(obj, event)

if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = MainWindow()
    window.show()
    app.exec()

关键说明

  1. 方案1实现简单,适合大多数场景;方案2更稳定,适合对输入法切换精度要求高的场景。
  2. 设置虚拟键盘区域布局时,需确保QtVirtualKeyboard支持对应的布局(比如zh_CN、en_US等)。
  3. 方案2中的插件路径需根据你的实际Qt安装路径调整,虚拟环境下通常为venv/lib/pythonX.X/site-packages/PyQt6/plugins/platforminputcontexts/libqtvirtualkeyboardplugin.so。

内容的提问来源于stack exchange,提问作者ZioByte

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 17:32:05