我正在使用第三方路由器通过 wi-fi 访问我自己的机器人。我写了一个小应用程序,它自动登录到路由器,浏览tab
路由器界面,所有这些都JavaScript
在QML
应用程序内部使用。我遇到的一个小问题是我必须触发继电器来打开/关闭机器人,并且在路由器 GUI 内部我需要触发 a combobox
,如下面的打印屏幕所示。点击I/O
选项卡后,路由器页面地址为https://123.456.789.123:7878/admin/ACEmanagerX.html#
:
对应html
的也如下所示:
编辑
现在为了重现这个问题,我部署了一个非常小的网站https://comboboxtest.netlify.com/,它只包含一个我试图触发的具有相同名称和相同选择的组合框。
问题是我找不到一种简单的方法来触发继电器的开或关。
预期的行为是:如果是OFF
(值 0),则将它ON
(值 1,即驱动有效低电平)放入,反之亦然。
如果你复制/粘贴下面的代码并运行它,它会自动打开网站,但不幸的是,它不会改变组合框的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
}
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句