javascript - Qt5-QML:如何通过 JavaScript 处理 QML 中的组合框
问题描述
我正在使用第三方路由器通过 wi-fi 访问我自己的机器人。我写了一个小应用程序,它可以自动登录到路由器,通过tab
路由器界面导航,所有这些都在应用程序JavaScript
内部QML
使用。我遇到的一个小问题是我必须触发一个继电器来打开/关闭机器人,并且在路由器 GUI 内部我需要触发一个combobox
,如下面的打印屏幕所示。点击I/O
选项卡后,路由器页面的地址为https://123.456.789.123:7878/admin/ACEmanagerX.html#
:
对应html
的也如下图:
编辑
现在,为了复制这个问题,我部署了一个非常小的网站https://comboboxtest.netlify.com/,它只包含一个我试图触发的具有相同名称和相同选择的组合框。
问题是我找不到触发继电器开启或关闭的简单方法。
预期的行为将是:如果它是OFF
(值 0),则放置它ON
(值 1,即 Drive Active Low),反之亦然。
如果您复制/粘贴下面的代码并运行它,它将自动打开网站,但不幸的是,它不会将组合框从OFF
位置更改为Drive Active Low
,反之亦然。
import QtQuick 2.13
import QtQuick.Controls 2.13
import QtWebEngine 1.9
ApplicationWindow{
id: root
width: 1940
height: 1100
visible: true
property string cBox: "https://comboboxtest.netlify.com"
QtObject {
// Below property triggers the combo box of the relays evaluating the normally closed (NC) or
// normally opened (NO) circuit
property string get_normallyClosed_or_normallyOpened_comboBox: "
var comboBox = document.getElementsByName('859-2-2')[0];
comboBox.addEventListener('change', function (e) {
comboBox.options[0].selected = true;
if ('createEvent' in document) {
var evt = document.createEvent('HTMLEvents');
evt.initEvent('change', false, true);
sel.dispatchEvent(evt);
}
else {
sel.fireEvent('onchange');
}
});
sel.addEventListener('change', function (e) {
alert('changed');
});
".arg(cBox)
}
Timer {
id: timer
interval: 1000; repeat: false
onTriggered: view.runJavaScript(internals.get_normallyClosed_or_normallyOpened_comboBox)
}
WebEngineView {
id: view
anchors.fill: parent
onUrlChanged: {
console.log(url)
if(url === Qt.resolvedUrl("https://comboboxtest.netlify.com/"))
timer.running = true
}
onCertificateError: function(error) {
error.ignoreCertificateError();
}
Component.onCompleted: view.url = "https://comboboxtest.netlify.com"
}
}
到目前为止我尝试了什么
1)看完这篇文章后,我发现给http
请求启动时间是非常重要的。这就是我interval: 20000
在输入I/O选项卡后添加的原因。但是,这没有用,也没有触发组合框。
2)我使用这个源来帮助我弄清楚如何触发组合框JavaScript
,这正是我应用的,但我没有看到组合框中的任何值发生变化。
3)我发现这篇文章与我正在做的非常接近,不同之处在于它在这里也被用来Button
触发组合框。但就我而言,我没有按钮。
我知道我已经接近让它工作了,但是我缺少一些东西。感谢您为解决问题而阐明此事
解决方案
我为你想出了一个可行的例子。这里真的没有什么棘手的,只是精确的语法,学习 JavaScript,特别注意 Qt 在运行时产生的警告消息。我对后者的压力再怎么强调也不为过——如果你看不到控制台的输出,那么它甚至不值得测试。即使是最新清理的 MRE 也会生成控制台警告,这些警告很容易解决,之后真正的问题变得更加明显。
有两个主要变化。首先测试
if (url === Qt.resolvedUrl("https://comboboxtest.netlify.com/"))
从来没有true
。非常基本,很容易用console.log()
. 将 URL 与字符串进行比较的好方法是使用url.toString()
.
另一个重大变化是在 Web 视图/浏览器中运行的脚本。我试着注释一下。希望我正确理解了目的——将组合框中的选择切换到与当前选择相反的位置,然后触发change
事件。我不完全确定原始脚本代码试图做什么(或者为什么索引更改在偶数侦听器内部......它永远不会那样改变?)。无论如何,这就是我的版本的样子。
import QtQuick 2.13
import QtQuick.Controls 2.13
import QtWebEngine 1.9
ApplicationWindow{
id: root
width: 320
height: 200
visible: true
property string url: "https://comboboxtest.netlify.com/"
QtObject {
id: internals
// Below property triggers the combo box of the relays evaluating the normally closed (NC) or
// normally opened (NO) circuit
property string get_normallyClosed_or_normallyOpened_comboBox: "
var comboBox = document.getElementsByName('859-2-2')[0];
// Check that we found a target element.
if (comboBox) {
// Add event listener to verify that combo change event gets fired.
comboBox.addEventListener('change', function (e) {
console.log('Change event detected:', e);
});
// Get new option index by flipping the current selected index
var newIdx = (comboBox.selectedIndex + 1) % 2;
console.log(comboBox, comboBox.selectedIndex, newIdx); // debug
// set the new index
comboBox.selectedIndex = newIdx;
// fire change event
comboBox.dispatchEvent(new Event('change'));
}
else {
console.error('comboBox not found!');
}
";
}
Timer {
id: timer
interval: 1000; repeat: false
onTriggered: {
console.log("Triggered timer with ", view.url);
view.runJavaScript(internals.get_normallyClosed_or_normallyOpened_comboBox);
}
}
WebEngineView {
id: view
anchors.fill: parent
onUrlChanged: {
if (url.toString() === root.url)
timer.running = true
}
onCertificateError: function(error) {
error.ignoreCertificateError();
}
Component.onCompleted: view.url = root.url
}
}
推荐阅读
- python - Python Dataframe 块列索引不正确
- msbuild - 如何通过 makefile 覆盖 Visual Studio 2019 的 MSBuildExtensionsPath 属性?
- excel - 用于特定研究的 XLSM 函数或宏
- pandas - 如果值包含 3d 数组,如何重塑数据框中的数据
- c# - Range.Find 返回 null 并且无法识别 Count 方法
- internationalization - i18n 是否可以隐藏没有翻译的页面?
- .net - 几个小时的空闲时间后,用户控件重新启动(卸载+加载)
- react-native - React-native BLE 读取 blob 请求
- powerbi - 在 Power BI 中计算累积值
- drools - Drools 验证:变量不能在绑定中使用