PyQt5:QWebEngineVi中的mouseClick和源代码

2024-10-02 16:30:47 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个使用PyQt-5.5.1的工作脚本,现在我想将其移植到新的PyQt版本(5.7)。大多数事情都做得很好,但我面临两个主要问题:(1)执行(模拟)鼠标点击,(2)访问(假设:打印)当前显示在QWebView或QWebEngineView中的网页的html源代码。在

例如,我可以在PyQt-5.5.1中使用QWebView执行以下操作:

QTest.mouseClick(self.wvTest, Qt.LeftButton, QPoint(x, y))

以及

^{pr2}$

我知道关于{QueWeangNeNeWW的^ ^ a1}和this page,但不能将C++符号转换成工作的Python代码。在

如何使其适应PyQt-5.7中的QWebEngineView?下面是PyQt-5.5.1的一个完全有效的代码段,对于新的PyQt版本,该代码段失败了:

  • 对于按钮1:完全没有鼠标点击反应。在
  • 对于按钮2:AttributeError: 'QWebEnginePage' object has no attribute 'mainFrame',当我删除mainframe():TypeError: toHtml(self, Callable[..., None]): not enough arguments。在

import sys
from PyQt5.QtWidgets import QWidget, QPushButton, QApplication
from PyQt5.QtCore import QRect, Qt, QUrl, QPoint, QEvent
from PyQt5.QtTest import QTest
from PyQt5.Qt import PYQT_VERSION_STR

if PYQT_VERSION_STR=='5.5.1': from PyQt5 import QtWebKitWidgets else: from PyQt5 import QtWebEngineWidgets

class Example(QWidget): def __init__(self): super().__init__() self.initUI() def initUI(self): self.button1 = QPushButton('Button1', self) self.button1.clicked.connect(self.buttonOne) self.button1.setGeometry(QRect(10, 10, 90, 20)) self.button2 = QPushButton('Button2', self) self.button2.clicked.connect(self.buttonTwo) self.button2.setGeometry(QRect(110, 10, 90, 20)) if PYQT_VERSION_STR=='5.5.1': self.wvTest = QtWebKitWidgets.QWebView(self) else: self.wvTest = QtWebEngineWidgets.QWebEngineView(self) self.wvTest.setGeometry(QRect(10, 40, 430, 550)) self.wvTest.setUrl(QUrl('http://www.startpage.com')) self.wvTest.setObjectName('wvTest') self.setGeometry(300, 300, 450, 600) self.setWindowTitle('WebView minimalistic') self.show() def buttonOne(self): qp = QPoint(38, 314) QTest.mouseClick(self.wvTest, Qt.LeftButton, pos=qp) # or: QTest.mouseMove(self.wvTest, pos=self.qp) print('Button1 pressed.') def buttonTwo(self): frame = self.wvTest.page().mainFrame() print(frame.toHtml().encode('utf-8')) if __name__ == '__main__': app = QApplication(sys.argv) ex = Example() sys.exit(app.exec_())


Tags: fromimportselfdefsysqtpyqt5pyqt
1条回答
网友
1楼 · 发布于 2024-10-02 16:30:47

QWebEngineView类不是QWebView的直接替代品。正如porting guide所表明的那样,许多api已经从根本上改变了,一些主要特性也完全丢失了。除非你的浏览器实现非常非常简单,否则这很可能使你无法编写兼容层。编写一个单独的测试套件可能更容易(除非您不介意编写大量的条件代码)。在

首先,您需要为QTBUG-43602实现一个变通方法。QWebEngineView的当前设计意味着内部的{}处理鼠标事件,因此每当页面加载时,您的代码都需要获得对该事件的新引用:

class Example(QWidget):
    ...

    def initUI(self):
        ...    
        self._glwidget = None

        if PYQT_VERSION_STR=='5.5.1':
            self.wvTest = QtWebKitWidgets.QWebView(self)
        else:
            self.wvTest = QtWebEngineWidgets.QWebEngineView(self)
            self.wvTest.installEventFilter(self)
        ...

    def eventFilter(self, source, event):
        if (event.type() == QEvent.ChildAdded and
            source is self.wvTest and
            event.child().isWidgetType()):
            self._glwidget = event.child()
            self._glwidget.installEventFilter(self)
        elif (event.type() == QEvent.MouseButtonPress and
              source is self._glwidget):
            print('web-view mouse-press:', event.pos())
        return super().eventFilter(source, event)

    def buttonOne(self):
        qp = QPoint(38, 314)
        widget = self._glwidget or self.wvTest
        QTest.mouseClick(widget, Qt.LeftButton, pos=qp)

为了访问页面的html,您将需要一些条件代码,因为web引擎API是异步工作的,并且需要回调。此外,web引擎中没有用于处理帧的内置API(您需要使用javascript来实现),因此所有内容都需要经过web页面:

^{2}$

相关问题 更多 >