前言
可能有小伙伴已经注意到,Qt for WebAssembly无法输入中文。笔者提供两种解决方法,有兴趣的小伙伴可以测试下
在开始本节前,请注意,需要提前导入中文字体,否则中文无法显示,可能显示成方块,具体可参考下文Qt添加自定义字体_꧁白杨树下꧂的博客-CSDN博客
一、使用系统剪切板
在最新的Qt版本中,Qt的复制和粘贴已经支持到操作系统的剪切板,可以直接使用快捷键Ctrl+C和Ctrl+V的。所以可以从本机复制后,再粘贴到需要的位置就可以了。
有可能不少小伙伴会说,Qt官方在骗人,复制和粘贴只限本网页内。笔者在这解释下,WebAssembly是运行在沙盒中的。若访问前端页面时,不是一个可信的安全连接,沙盒会阻止程序访问本地操作系统的剪切板,也就是只在网页内复制和粘贴。解决方法也不难,笔者提供如下两种:
1.安装可信证书
不少小伙伴使用的自签名证书,使用时要注意服务器地址要与证书一致
若自签名证书,使用https访问,一开始忽略错证书了,也是无法正常访问本地操作系统剪切板的
2.将服务器的网址添加证书例外
这个就不解释了
笔者在测试中发现,FireFox浏览器无需设置,可以直接访问系统剪切板,感兴趣的小伙伴可以测试下
二、使用js接口
既然Qt中无法正常输入,可以使用html里的获取文本对话框,使用方法如下:
1.新建一个JS调用的类,用于获取文本
通过emsdk,可以直接调用JS,定义一个C的调用函数,弹出html的文本获取对话框
#include <emscripten.h>
#include <emscripten/html5.h>
//定义JS的一个调用函数
EM_JS(const char*, getInput, (const char *str), {
const text = UTF8ToString(str);
val = prompt("", text);
if(val == null)
{
val = ""
}
var jstring = val;
var lengthBytes = lengthBytesUTF8(jstring)+1;
var stringOnWasmHeap = _malloc(lengthBytes);
stringToUTF8(jstring, stringOnWasmHeap, lengthBytes);
return stringOnWasmHeap;
})
然后添加一个类函数,用于调用C的函数,并返回获取的文本
class Manager : public QObject
{
Q_OBJECT
public:
explicit Manager(QObject *parent = nullptr);
Q_INVOKABLE QString getUserInput(QString currentText)
{
QString input = "";
#ifdef Q_OS_WASM
input = getInput(currentText.toUtf8().data());
#else
#endif
return input;
}
};
2.将类注册到qml中
qmlRegisterType<Manager>("com.xdqd.classes", 1, 0, "Manager");
3.在qml中调用
Manager{
id: manager
}
TextField {
id: textField
MouseArea{
anchors.fill: parent
visible: Qt.platform.os == "wasm"
onClicked: {
//从html的文本框中,获取输入文本
textField.text = manager.getUserInput(textField.text);
}
}
}
代码比较简单,笔都就不解释了
运行结果如下
只要一点TextField框,就会弹出一个文本获取对话框
对话框是可以输入中文的,点击确定后,文本就可以填入Qt的文本输入框了
笔者使用的测试源码
后记
因为沙盒限制,当前wasm好多东西受限,但从长远来看,官方应该会逐渐解决这些问题。因此笔者不建议读者,在通用问题上,不要花费太多时间,应该多专注下功能实现