QtVirtualKeyboard 使用平台 WebGL 冻结 QML 应用程序,但桌面工作正常。如何解冻它或解决它?
QtVirtualKeyboard freezes QML application with platform WebGL, but desktop works fine. How to unfreeze it or work around it?
长版
我正在 运行使用 WebGL 作为平台在浏览器中安装 QML 应用程序。在我尝试集成 QtVirtualKeyboard 以填充一些文本字段和可编辑的 ComboBox 之前,一切都运行良好。 运行在浏览器中打开项目时,收到的第一条消息是:
This plugin does not support dynamic OpenGL loading!
虽然我怀疑此错误 message/warning 与虚拟键盘 (VK) 无关,因为删除 VK 的所有痕迹不会使消息消失。浏览器的屏幕截图window可以在下面查看。
单击文本输入字段会出现下一条消息:
This plugin does not support setting window masks
一半的屏幕保持黑色 - 这是刷新时 VK 所在的区域。再次 - 下面的屏幕截图。
刷新后,又出现了三条消息。我将省略前两个,因为它们基本上是在说“您按下了 Alt 键和 F5 键”。第三条消息是:
requestActivate() called for QtVirtualKeyboard::InputView(0x4a16590) which has Qt::WindowDoesNotAcceptFocus set.
现在键盘是可见的,但是每次在 VK 上敲击一个键时,都会出现新消息,同时没有文本写入文本字段:
This plugin does not support setting window masks
This plugin does not support setting window masks
qt.virtualkeyboard: InputContext::sendKeyClick(): no focus to send key click - QGuiApplication::focusWindow() is: QtVirtualKeyboard::InputView(0x4a16590)
This plugin does not support setting window masks
除此之外,一旦项目处于这种状态,我的键盘输入似乎就会被忽略。硬重置(关闭程序并重新启动)将功能恢复到被调用的 VK,刷新页面不会触发任何文本出现在文本字段中。我得到的最终视图如下所示:
我创建了一个最小的示例来说明问题。它是由 Qt Creator 4.13.2 创建的一个略微修改的空 QML 项目。
运行 它在桌面上应该可以工作,如果项目收到命令行参数 -platform webgl:port=80
,就会出现问题行为。我正在使用 MSVC2019 32 位和 Qt 5.15.1。该问题在 Microsoft Edge 44.18362.387.0 和 Firefox 68.5.0esr(32 位)中重现。
Chrome 版本 86.0.4240.111(64 位)有点不同,不过:虽然输入未直接显示,但刷新网页后输入内容。但是,最小化键盘不起作用,所以这不是解决方案。
# TestVirtualKeyboard.pro (autogenerated by QtCreator)
QT += quick virtualkeyboard
CONFIG += c++11
# You can make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
SOURCES += \
main.cpp
RESOURCES += qml.qrc
# Additional import path used to resolve QML modules in Qt Creator's code model
QML_IMPORT_PATH =
# Additional import path used to resolve QML modules just for Qt Quick Designer
QML_DESIGNER_IMPORT_PATH =
# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
// main.cpp
#include <QGuiApplication>
#include <QQmlApplicationEngine>
int main(int argc, char *argv[])
{
qputenv("QSG_RENDER_LOOP", "threaded"); // Addendum for Windows, does not change the problematic behavior
qputenv("QT_IM_MODULE", QByteArray("qtvirtualkeyboard"));
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
const QUrl url(QStringLiteral("qrc:/main.qml"));
QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
&app, [url](QObject *obj, const QUrl &objUrl) {
if (!obj && url == objUrl)
QCoreApplication::exit(-1);
}, Qt::QueuedConnection);
engine.load(url);
return app.exec();
}
// main.qml
import QtQuick 2.15
import QtQuick.Window 2.15
import QtQuick.VirtualKeyboard 2.15
import QtQuick.Controls 2.5
Window {
id: window
width: 640
height: 480
visible: true
title: qsTr("Hello World")
color: "grey"
TextInput {
anchors.horizontalCenter: parent.horizontalCenter
anchors.top: parent.top
width: 320
height: 30
Rectangle {
anchors.centerIn: parent
width: parent.width + 4
height: parent.height + 4
color: "white"
border.color: "black"
border.width: 1
radius: 2
z: -1
}
}
}
TL,DR:
如果 运行 在桌面应用程序中 QtVirtualKeyboard 工作,但如果平台是 WebGL 并且选择了可编辑的文本元素,则冻结应用程序。
问题:
有没有办法让 Qt/WebGL 应用程序中的 QtVirtualKeyboard 达到 运行,或者是否有另一个 way/tool 可用于通过 Qt/WebGL 应用程序在触摸设备上获得键盘功能?
无需编写自己的键盘元素的奖励积分。
目前我尝试过的:
- 我搜索了一些流行的搜索引擎,但没有搜索到。
- 多个浏览器,没有令人满意的成功。
- 发现了一些与 Unity 相关的问题,这将交叉发布到另一个论坛。这些似乎不适用于我的问题,因为我怀疑 Qt/QML/WebGL 和 Unity/WebGL 会有很大的不同,而且我没有使用 Unity 的经验。
- 我不确定这个问题是如何关联的:QT WebGL-stream, virtualKeyboard and touch screen problem
在 Qt 支持的帮助下,我让它工作了。我这样做的方式是,调用 Qt 虚拟键盘导致应用程序试图使键盘成为应用程序顶部的顶级 window。这也是 Desktop 机箱的处理方式,但它确实有效。
为了避免这种行为,必须将键盘嵌入 QML window。为此,可以将 InputPanel
添加到 QML window 中,如下所示:
import QtQuick 2.15
import QtQuick.Window 2.15
import QtQuick.VirtualKeyboard 2.15
import QtQuick.Controls 2.5
Window {
id: window
width: 640
height: 480
visible: true
title: qsTr("Hello World")
color: "grey"
TextInput {
anchors.horizontalCenter: parent.horizontalCenter
anchors.top: parent.top
width: 320
height: 30
Rectangle {
anchors.centerIn: parent
width: parent.width + 4
height: parent.height + 4
color: "white"
border.color: "black"
border.width: 1
radius: 2
z: -1
}
}
InputPanel {
width: window.width
y: window.height - height
visible: active
}
}
这对我有用。
长版
我正在 运行使用 WebGL 作为平台在浏览器中安装 QML 应用程序。在我尝试集成 QtVirtualKeyboard 以填充一些文本字段和可编辑的 ComboBox 之前,一切都运行良好。 运行在浏览器中打开项目时,收到的第一条消息是:
This plugin does not support dynamic OpenGL loading!
虽然我怀疑此错误 message/warning 与虚拟键盘 (VK) 无关,因为删除 VK 的所有痕迹不会使消息消失。浏览器的屏幕截图window可以在下面查看。
单击文本输入字段会出现下一条消息:
This plugin does not support setting window masks
一半的屏幕保持黑色 - 这是刷新时 VK 所在的区域。再次 - 下面的屏幕截图。
刷新后,又出现了三条消息。我将省略前两个,因为它们基本上是在说“您按下了 Alt 键和 F5 键”。第三条消息是:
requestActivate() called for QtVirtualKeyboard::InputView(0x4a16590) which has Qt::WindowDoesNotAcceptFocus set.
现在键盘是可见的,但是每次在 VK 上敲击一个键时,都会出现新消息,同时没有文本写入文本字段:
This plugin does not support setting window masks
This plugin does not support setting window masks
qt.virtualkeyboard: InputContext::sendKeyClick(): no focus to send key click - QGuiApplication::focusWindow() is: QtVirtualKeyboard::InputView(0x4a16590)
This plugin does not support setting window masks
除此之外,一旦项目处于这种状态,我的键盘输入似乎就会被忽略。硬重置(关闭程序并重新启动)将功能恢复到被调用的 VK,刷新页面不会触发任何文本出现在文本字段中。我得到的最终视图如下所示:
我创建了一个最小的示例来说明问题。它是由 Qt Creator 4.13.2 创建的一个略微修改的空 QML 项目。
运行 它在桌面上应该可以工作,如果项目收到命令行参数 -platform webgl:port=80
,就会出现问题行为。我正在使用 MSVC2019 32 位和 Qt 5.15.1。该问题在 Microsoft Edge 44.18362.387.0 和 Firefox 68.5.0esr(32 位)中重现。
Chrome 版本 86.0.4240.111(64 位)有点不同,不过:虽然输入未直接显示,但刷新网页后输入内容。但是,最小化键盘不起作用,所以这不是解决方案。
# TestVirtualKeyboard.pro (autogenerated by QtCreator)
QT += quick virtualkeyboard
CONFIG += c++11
# You can make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
SOURCES += \
main.cpp
RESOURCES += qml.qrc
# Additional import path used to resolve QML modules in Qt Creator's code model
QML_IMPORT_PATH =
# Additional import path used to resolve QML modules just for Qt Quick Designer
QML_DESIGNER_IMPORT_PATH =
# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
// main.cpp
#include <QGuiApplication>
#include <QQmlApplicationEngine>
int main(int argc, char *argv[])
{
qputenv("QSG_RENDER_LOOP", "threaded"); // Addendum for Windows, does not change the problematic behavior
qputenv("QT_IM_MODULE", QByteArray("qtvirtualkeyboard"));
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
const QUrl url(QStringLiteral("qrc:/main.qml"));
QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
&app, [url](QObject *obj, const QUrl &objUrl) {
if (!obj && url == objUrl)
QCoreApplication::exit(-1);
}, Qt::QueuedConnection);
engine.load(url);
return app.exec();
}
// main.qml
import QtQuick 2.15
import QtQuick.Window 2.15
import QtQuick.VirtualKeyboard 2.15
import QtQuick.Controls 2.5
Window {
id: window
width: 640
height: 480
visible: true
title: qsTr("Hello World")
color: "grey"
TextInput {
anchors.horizontalCenter: parent.horizontalCenter
anchors.top: parent.top
width: 320
height: 30
Rectangle {
anchors.centerIn: parent
width: parent.width + 4
height: parent.height + 4
color: "white"
border.color: "black"
border.width: 1
radius: 2
z: -1
}
}
}
TL,DR: 如果 运行 在桌面应用程序中 QtVirtualKeyboard 工作,但如果平台是 WebGL 并且选择了可编辑的文本元素,则冻结应用程序。
问题: 有没有办法让 Qt/WebGL 应用程序中的 QtVirtualKeyboard 达到 运行,或者是否有另一个 way/tool 可用于通过 Qt/WebGL 应用程序在触摸设备上获得键盘功能? 无需编写自己的键盘元素的奖励积分。
目前我尝试过的:
- 我搜索了一些流行的搜索引擎,但没有搜索到。
- 多个浏览器,没有令人满意的成功。
- 发现了一些与 Unity 相关的问题,这将交叉发布到另一个论坛。这些似乎不适用于我的问题,因为我怀疑 Qt/QML/WebGL 和 Unity/WebGL 会有很大的不同,而且我没有使用 Unity 的经验。
- 我不确定这个问题是如何关联的:QT WebGL-stream, virtualKeyboard and touch screen problem
在 Qt 支持的帮助下,我让它工作了。我这样做的方式是,调用 Qt 虚拟键盘导致应用程序试图使键盘成为应用程序顶部的顶级 window。这也是 Desktop 机箱的处理方式,但它确实有效。
为了避免这种行为,必须将键盘嵌入 QML window。为此,可以将 InputPanel
添加到 QML window 中,如下所示:
import QtQuick 2.15
import QtQuick.Window 2.15
import QtQuick.VirtualKeyboard 2.15
import QtQuick.Controls 2.5
Window {
id: window
width: 640
height: 480
visible: true
title: qsTr("Hello World")
color: "grey"
TextInput {
anchors.horizontalCenter: parent.horizontalCenter
anchors.top: parent.top
width: 320
height: 30
Rectangle {
anchors.centerIn: parent
width: parent.width + 4
height: parent.height + 4
color: "white"
border.color: "black"
border.width: 1
radius: 2
z: -1
}
}
InputPanel {
width: window.width
y: window.height - height
visible: active
}
}
这对我有用。