简体   繁体   English

使用QWebEngineView显示html时如何获取verticalScrollBar的最大值和当前值

[英]How can I get the maximum and current value of the verticalScrollBar when displaying html with QWebEngineView

I'm attempting to create a UI in Maya (Python 2.7.11 and Maya Qt 5.6.1. and PySide2) where the OK button is grayed out until the user scrolls to the bottom. 我试图在Maya(Python 2.7.11和Maya Qt 5.6.1。和PySide2)中创建UI,在该UI中,“确定”按钮显示为灰色,直到用户滚动到底部。 I can do this easily with QTextEdit by grabbing the value and maximum from the verticalScrollBar but I can't seem to find similar objects in QWebEngineView or QWebEnginePage. 我可以通过从verticalScrollBar抓取值和最大值来轻松实现QTextEdit的功能,但在QWebEngineView或QWebEnginePage中似乎找不到类似的对象。 Any Ideas? 有任何想法吗?

In the case you want to get some information from the DOM you have to do it with javascript, in this case we will create an object that will have the required information and export it to the HTML so that each time the scroll status changes it will be updated. 如果要从DOM中获取一些信息,则必须使用javascript进行处理,在这种情况下,我们将创建一个具有所需信息的对象,并将其导出到HTML,以便每次滚动状态更改时,被更新。

from PySide2 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):
        return ''

class YScrollBarListener(Element):
    valueChanged = QtCore.Signal(int)
    maximumChanged = QtCore.Signal(int)

    def __init__(self, name, parent=None):
        super(YScrollBarListener, self).__init__(name, parent)
        self._value = -1
        self._maximum = -1

    @QtCore.Property(int, notify=valueChanged)
    def value(self):
        return self._value

    @QtCore.Property(int, notify=maximumChanged)
    def maximum(self):
        return self._maximum

    def script(self):
        _script = '''
        window.addEventListener("scroll", function(event){
            {{name}}.update_value(this.scrollY);
            // https://stackoverflow.com/a/43571388/6622587
            var scrollMaxY = window.scrollMaxY || (document.documentElement.scrollHeight - document.documentElement.clientHeight)
            {{name}}.update_maximum(scrollMaxY)
        });
        '''
        return Template(_script).render(name=self.name)

    @QtCore.Slot(int)
    def update_value(self, value):
        if self._value != value:
            self._value = value
            self.valueChanged.emit(value)

    @QtCore.Slot(int)
    def update_maximum(self, maximum):
        if self._maximum != maximum:
            self._maximum = maximum
            self.maximumChanged.emit(maximum)

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.Slot(bool)
    def onLoadFinished(self, ok):
        print("Finished loading: ", ok)
        if ok:
            self.load_qwebchannel()
            self.add_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 add_objects(self):
        if self.webChannel() is not None:
            objects = {obj.name : obj for obj in self._objects}
            self.webChannel().registerObjects(objects)
            _script = '''
            {% 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 Widget(QtWidgets.QWidget):
    def __init__(self, parent=None):
        super(Widget, self).__init__(parent)

        self._scrollbar_listener = YScrollBarListener("y_scrollbar_listener", self)
        self._scrollbar_listener.valueChanged.connect(self.on_y_value_changed)
        view = QtWebEngineWidgets.QWebEngineView()
        page = WebEnginePage(view)
        page.add_object(self._scrollbar_listener)
        view.setPage(page)

        view.load(QtCore.QUrl("https://stackoverflow.com/questions/43282899"))

        self._button = QtWidgets.QPushButton("button")
        progressbar = QtWidgets.QProgressBar(maximum=100)
        view.loadProgress.connect(progressbar.setValue)

        lay = QtWidgets.QVBoxLayout(self)
        lay.addWidget(view)
        lay.addWidget(self._button)
        lay.addWidget(progressbar)

        self.resize(640, 480)

    def on_y_value_changed(self, value):
        self._button.setEnabled(self._scrollbar_listener.maximum != value)


if __name__ == '__main__':
    import sys
    app = QtWidgets.QApplication(sys.argv)
    app.setStyle('fusion')
    app.setStyleSheet('''
    QPushButton
    {
        background-color: #2E8B57;
    }
    QPushButton:disabled
    {
        background-color: #FFFAFA;
    }
    ''')
    w = Widget()
    w.show()
    sys.exit(app.exec_())

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 我如何在pyqt5 python中获取qwebengineview的当前url? - how do i get the current url of qwebengineview in pyqt5 python? 如何将QPlainTextEdit verticalScrollBar设置为最大值? - How to set QPlainTextEdit verticalScrollBar to maximum? 如何获取 QWebEngineView 中加载的页面的 html - How to get html of a page loaded in QWebEngineView 如何在 Cython 中获得最大 integer 值? - How can I get the maximum integer value in Cython? 如何创建带有图像边框的透明圆形 QWebEngineView? - how can I create a transparent circular QWebEngineView with an image border? QWebEngineView中央小部件时如何在QWebEngineView之上制作QFrame - How to make QFrame on top of QWebEngineView when is QWebEngineView central widget 为什么我的本地 html 加载到 PySide6 QWebEngineView 时无法访问? - Why my local html is not accessed when I load it into PySide6 QWebEngineView? 如何使用 PyQt5 的 QWebEngineView “渲染” HTML - How to “render” HTML with PyQt5's QWebEngineView 使用 sort_values,如何从列列表中获取最大值? - Using sort_values, how can I get the maximum value from a list of a column? 如何获取 Dataframe 中上一行的值以更改当前行值(动态地,而不是静态值) - How can I get the value of the previous row in a Dataframe to change the current row value (dynamically, not with a static value)
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM