使用QWebEngineView显示html时如何获取verticalScrollBar的最大值和当前值
How can I get the maximum and current value of the verticalScrollBar when displaying html with QWebEngineView
我正在尝试在 Maya(Python 2.7.11 和 Maya Qt 5.6.1. 和 PySide2)中创建一个 UI,其中“确定”按钮呈灰色,直到用户滚动到底端。我可以通过从 verticalScrollBar 获取值和最大值来使用 QTextEdit 轻松地做到这一点,但我似乎无法在 QWebEngineView 或 QWebEnginePage 中找到类似的对象。有什么想法吗?
如果您想从 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);
//
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(""))
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_())
我正在尝试在 Maya(Python 2.7.11 和 Maya Qt 5.6.1. 和 PySide2)中创建一个 UI,其中“确定”按钮呈灰色,直到用户滚动到底端。我可以通过从 verticalScrollBar 获取值和最大值来使用 QTextEdit 轻松地做到这一点,但我似乎无法在 QWebEngineView 或 QWebEnginePage 中找到类似的对象。有什么想法吗?
如果您想从 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);
//
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(""))
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_())