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

Qt6+CMake下自定义虚拟键盘移植问题及简易示例请求

Qt6 自定义虚拟键盘简易示例(CMake环境)

核心变更说明

Qt6 中移除了 QPlatformInputContext,改用 QInputMethod 作为输入方法的核心类,文本输入依赖 QInputMethodEvent 和 QKeyEvent 完成交互。

最简实现步骤

1. CMakeLists.txt 配置

确保项目启用必要的 Qt 模块:

cmake_minimum_required(VERSION 3.16)
project(CustomVirtualKeyboard)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_INCLUDE_CURRENT_DIR ON)

find_package(Qt6 REQUIRED COMPONENTS Core Widgets Gui)

qt_standard_project_setup()

add_executable(CustomVirtualKeyboard
    main.cpp
    mainwindow.cpp
    virtualkeyboard.cpp
)

target_link_libraries(CustomVirtualKeyboard PRIVATE Qt6::Core Qt6::Widgets Qt6::Gui)

2. 虚拟键盘UI实现(virtualkeyboard.h/.cpp)

创建带按键的键盘窗口,点击按键时向输入框架发送事件:

// virtualkeyboard.h
#ifndef VIRTUALKEYBOARD_H
#define VIRTUALKEYBOARD_H

#include <QWidget>
#include <QGridLayout>
#include <QPushButton>

class VirtualKeyboard : public QWidget
{
    Q_OBJECT
public:
    explicit VirtualKeyboard(QWidget *parent = nullptr);

private slots:
    void onKeyPressed();

private:
    void createKeys();
};

#endif // VIRTUALKEYBOARD_H
// virtualkeyboard.cpp
#include "virtualkeyboard.h"
#include <QInputMethod>
#include <QGuiApplication>
#include <QInputMethodEvent>

VirtualKeyboard::VirtualKeyboard(QWidget *parent) : QWidget(parent)
{
    setWindowFlags(Qt::Tool | Qt::WindowStaysOnBottomHint);
    setFixedHeight(200);
    createKeys();
}

void VirtualKeyboard::createKeys()
{
    QGridLayout *layout = new QGridLayout(this);
    QStringList keys = {"1","2","3","4","5","6","7","8","9","0",
                        "Q","W","E","R","T","Y","U","I","O","P",
                        "A","S","D","F","G","H","J","K","L",
                        "Z","X","C","V","B","N","M","Backspace","Space"};

    int row = 0, col = 0;
    for(const QString &key : keys){
        QPushButton *btn = new QPushButton(key);
        connect(btn, &QPushButton::clicked, this, &VirtualKeyboard::onKeyPressed);
        layout->addWidget(btn, row, col);
        col++;
        if(col >= 10){
            col = 0;
            row++;
        }
    }
    setLayout(layout);
}

void VirtualKeyboard::onKeyPressed()
{
    QPushButton *btn = qobject_cast<QPushButton*>(sender());
    if(!btn) return;

    QString keyText = btn->text();
    QInputMethod *inputMethod = QGuiApplication::inputMethod();
    if(!inputMethod) return;

    if(keyText == "Backspace"){
        inputMethod->invokeAction(QInputMethod::Backspace);
    } else if(keyText == "Space"){
        QInputMethodEvent event;
        event.setCommitString(" ");
        inputMethod->sendEvent(event);
    } else {
        QInputMethodEvent event;
        event.setCommitString(keyText);
        inputMethod->sendEvent(event);
    }
}

3. 主窗口整合(mainwindow.h/.cpp)

主窗口添加输入框,根据焦点状态显示/隐藏键盘:

// mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QLineEdit>
#include "virtualkeyboard.h"

class MainWindow : public QMainWindow
{
    Q_OBJECT
public:
    MainWindow(QWidget *parent = nullptr);

private slots:
    void onInputFocusChanged(QWidget *old, QWidget *now);

private:
    QLineEdit *m_inputEdit;
    VirtualKeyboard *m_keyboard;
};

#endif // MAINWINDOW_H
// mainwindow.cpp
#include "mainwindow.h"
#include <QVBoxLayout>
#include <QWidget>

MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent)
{
    QWidget *centralWidget = new QWidget(this);
    QVBoxLayout *layout = new QVBoxLayout(centralWidget);

    m_inputEdit = new QLineEdit;
    m_inputEdit->setPlaceholderText("点击输入,弹出键盘");
    layout->addWidget(m_inputEdit);

    setCentralWidget(centralWidget);

    m_keyboard = new VirtualKeyboard;
    connect(qApp, &QApplication::focusChanged, this, &MainWindow::onInputFocusChanged);
}

void MainWindow::onInputFocusChanged(QWidget *old, QWidget *now)
{
    if(now == m_inputEdit){
        m_keyboard->show();
    } else {
        m_keyboard->hide();
    }
}

4. 主函数(main.cpp)

#include "mainwindow.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();
    return a.exec();
}

关键注意点

  • Qt6 无需自定义 InputContext,直接通过 QInputMethod 与系统输入框架交互
  • 若需复杂功能(候选词、多语言),可基于 QInputMethod 扩展,或使用 Qt6 官方的 QVirtualKeyboard 模块
  • CMake 必须链接 Qt6::Gui,QInputMethod 属于该模块

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 04:50:10