【问题标题】:how to change a part of html in pyqt5 qwebengineview如何在pyqt5 qwebengineview中更改html的一部分
【发布时间】:2020-01-15 12:14:51
【问题描述】:

我在 qwebengineview.setHtml() 中查看了一些 html,现在我想在单击该 html 视图中的按钮时运行 python 函数,然后将一些 html 添加到我的 html 视图中,这是我的函数的输出我打过电话。具体来说:我希望在按下表单按钮时删除输入。

我已阅读此question,但它没有告诉我如何更改我的 html 或更改其中的一部分或附加到它。
示例:

import os
import sys
from PyQt5 import QtCore, QtWidgets, QtWebEngineWidgets, QtWebChannel
from jinja2 import Template


class Element(QtCore.QObject):
    def __init__(self, name, parent=None):
        super(Element, self).__init__(parent)
        self._name = name

    @property
    def name(self):
        return self._name

    def script(self):
        raise NotImplementedError


class FormObject(Element):
    numbersChanged = QtCore.pyqtSignal(str, str)

    def script(self):
        _script = r"""
        var btn = document.getElementById('sub1');
        btn.addEventListener("click", function(event){
            var number1 = document.getElementById('num1');
            var number2 = document.getElementById('num2');
            {{name}}.update(number1.value , number2.value);
        });
        """
        return Template(_script).render(name=self.name)

    @QtCore.pyqtSlot(str, str)
    def update(self, number1, number2):
        self.numbersChanged.emit(number1, number2)


class WebEnginePage(QtWebEngineWidgets.QWebEnginePage):
    def __init__(self, *args, **kwargs):
        super(WebEnginePage, self).__init__(*args, **kwargs)
        self.loadFinished.connect(self.onLoadFinished)
        self._objects = []

    def add_object(self, obj):
        self._objects.append(obj)

    @QtCore.pyqtSlot(bool)
    def onLoadFinished(self, ok):
        if ok:
            self.load_qwebchannel()
            self.load_objects()

    def load_qwebchannel(self):
        file = QtCore.QFile(":/qtwebchannel/qwebchannel.js")
        if file.open(QtCore.QIODevice.ReadOnly):
            content = file.readAll()
            file.close()
            self.runJavaScript(content.data().decode())
        if self.webChannel() is None:
            channel = QtWebChannel.QWebChannel(self)
            self.setWebChannel(channel)

    def load_objects(self):
        if self.webChannel() is not None:
            objects = {obj.name: obj for obj in self._objects}
            self.webChannel().registerObjects(objects)
            _script = r"""
            {% for obj in objects %}
            var {{obj}};
            {% endfor %}
            new QWebChannel(qt.webChannelTransport, function (channel) {
            {% for obj in objects %}
                {{obj}} = channel.objects.{{obj}};
            {% endfor %}
            });
            """
            self.runJavaScript(Template(_script).render(objects=objects.keys()))
            for obj in self._objects:
                if isinstance(obj, Element):
                    self.runJavaScript(obj.script())


class WebPage(QtWebEngineWidgets.QWebEngineView):
    def __init__(self, parent=None):
        super().__init__(parent)

        page = WebEnginePage(self)
        self.setPage(page)

        formobject = FormObject("formobject", self)
        formobject.numbersChanged.connect(self.on_numbersChanged)
        page.add_object(formobject)

        filepath = os.path.abspath(
            os.path.join(os.path.dirname(__file__), "new.html")
        )
        self.load(QtCore.QUrl.fromLocalFile(filepath))

    @QtCore.pyqtSlot(str, str)
    def on_numbersChanged(self, number1, number2):
        print(number1, number2)


if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    web = WebPage()
    web.show()
    sys.exit(app.exec_())

<!DOCTYPE <html>
    <body>
        <form>
            Number 1:<input type="text" id="num1">
            <br>
            Number 2:<input type="text" id="num2">
            <br>
            <input type="submit" id="sub1">
        </form>
    </body>
</html>

【问题讨论】:

  • 如果您使用相同的 html,那么问题是相同的,所以它是重复的
  • 我现在这个问题,我已经使用了那个问题的代码,但现在我的问题是如何附加或编辑或删除我的 html 视图的一部分。
  • 1) 你想什么时候删除它? 2) 您希望追加、编辑或删除 HTML 的哪一部分?
  • 在调用该按钮已调用的python函数之后。
  • 这是我第一个问题的答案,我的第二个问题的答案是什么?

标签: python python-3.x pyqt pyqt5 qwebengineview


【解决方案1】:

如果你想从 HTML 中删除一个元素,你必须用 js 来完成,但是知道什么时候做的主要问题是,在表单的情况下页面会重新加载,所以你必须立即删除“输入”为它加载后,可以使用带有适当“t”的 QTimer.singleShot(t, func)。

考虑到上述情况并使用相同的代码,那么解决方案是

class WebPage(QtWebEngineWidgets.QWebEngineView):
    def __init__(self, parent=None):
        super().__init__(parent)

        page = WebEnginePage(self)
        self.setPage(page)

        formobject = FormObject("formobject", self)
        formobject.numbersChanged.connect(self.on_numbersChanged)
        page.add_object(formobject)

        filepath = os.path.abspath(
            os.path.join(os.path.dirname(__file__), "new.html")
        )
        self.load(QtCore.QUrl.fromLocalFile(filepath))

    @QtCore.pyqtSlot(str, str)
    def on_numbersChanged(self, number1, number2):
        print(number1, number2)
        QtCore.QTimer.singleShot(100, self.remove_inputs)

    def remove_inputs(self):
        self.page().runJavaScript(
            """
            function remove_by_id(_id){
                var elem = document.getElementById(_id);
                elem.parentNode.removeChild(elem);
            }
            remove_by_id("num1");
            remove_by_id("num2");
        """
        )

【讨论】:

  • @icode 你想添加什么HTML,在哪里,什么时候?,我已经表明你应该问一个具体的问题
  • 例如我有一个
    ,现在我想向其中添加一些其他标签或从中删除或编辑它们。
  • @icode 用你提供的 HTML 告诉我一个具体的例子,但如果你注意到了,你只需要使用 js 来执行这些操作。你对js有什么了解吗?
  • 是的,我现在关于 js 并且我已经测试了一个示例,它可以按照我想要的方式工作。非常感谢。
猜你喜欢
相关资源
最近更新 更多
热门标签