Qt5-QML:如何通过 JavaScript 处理 QML 中的组合框

伊曼纽尔

我正在使用第三方路由器通过 wi-fi 访问我自己的机器人。我写了一个小应用程序,它自动登录到路由器,浏览tab路由器界面,所有这些都JavaScriptQML应用程序内部使用。我遇到的一个小问题是我必须触发继电器来打开/关闭机器人,并且在路由器 GUI 内部我需要触发 a combobox,如下面的打印屏幕所示。点击I/O选项卡后,路由器页面地址为https://123.456.789.123:7878/admin/ACEmanagerX.html#

真正的

对应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] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章