关闭无法在pyqt应用中工作

时间:2018-08-13 10:45:59

标签: python pyqt closures

运行代码:

apt-get install python3-venv
python3 -m venv venv
. venv/bin/activate
pip install pyqt5
python3 script.py

要放入script.py的代码:

import sys

from PyQt5.QtCore import QUrl
from PyQt5.QtWebEngineCore import QWebEngineUrlRequestInterceptor
from PyQt5.QtWebEngineWidgets import QWebEngineView
from PyQt5.QtWidgets import QApplication, QVBoxLayout, QWidget, QScrollArea


class RequestInterceptor(QWebEngineUrlRequestInterceptor):

    def __init__(self, process_url):
        super().__init__()
        self.process_url = process_url

    def interceptRequest(self, info):
        self.process_url(info.requestUrl().toString())


class DictionaryComponents(QVBoxLayout):

    def __init__(self, url, process_url):
        super().__init__()

        self.url = url
        qurl = QUrl(url)
        self.host = qurl.host()
        self.process_url = process_url

        self.web_view_ui = QWebEngineView()
        self.web_view_ui.load(qurl)

        print('creating interceptor for host: {}'.format(self.host))
        self._request_interceptor = RequestInterceptor(
            lambda o: self.process_url(self.host, o)
        )
        self.web_view_ui.page().profile().setRequestInterceptor(self._request_interceptor)

        self.addWidget(self.web_view_ui)


class MainWindow(QScrollArea):

    def __init__(self, parent=None):
        super().__init__(parent)

        main_container = QWidget()
        main_container_layout = QVBoxLayout()

        for url in ['https://www.google.com', 'https://duckduckgo.com/']:
            dictionary = DictionaryComponents(url, print)
            main_container_layout.addLayout(dictionary)

        main_container.setLayout(main_container_layout)

        self.setWidgetResizable(True)
        self.setWidget(main_container)


if __name__ == '__main__':
    app = QApplication(sys.argv)
    mw = MainWindow()
    mw.show()
    sys.exit(app.exec_())

script.py的实际输出:

creating interceptor for host: www.google.com
creating interceptor for host: duckduckgo.com
duckduckgo.com https://www.google.com/
duckduckgo.com https://duckduckgo.com/

script.py的预期输出:

creating interceptor for host: www.google.com
creating interceptor for host: duckduckgo.com
www.google.com https://www.google.com/
duckduckgo.com https://duckduckgo.com/

我希望对https://www.google.com/的请求打印出该www.google.com主机,而不打印出duckduckgo.com。

该脚本将输出更多的输出:请求+不重要的qt / ssl错误。

我熟悉以下问题: http://enki-editor.org/2014/08/23/Pyqt_mem_mgmt.html

2 个答案:

答案 0 :(得分:0)

我认为您正在将第一个拦截器与第二个拦截器一起使用,因为根据Qt文档:

  

QWebEngineProfile类提供了一个由多个页面共享的Web引擎配置文件。

编辑,因为此答案可能还不够: 您可以使用QWebEnginePage(QWebEngineProfile *profile, QObject *parent = Q_NULLPTR)构造函数来提供与默认配置文件不同的配置文件。这样,每页将有一个单独的拦截器。

答案 1 :(得分:0)

感谢您的帮助!我照你说的做了,但是还是没用。我换了线

self.web_view_ui = QWebEngineView()
self.web_view_ui.load(qurl)

与此:

self.web_view_ui = QWebEngineView()
self.profile = QWebEngineProfile()
self.page = QWebEnginePage(self.profile)
self.web_view_ui.setPage(self.page)
self.web_view_ui.load(qurl)

原来,调用了错误的构造函数:

docs:http://doc.qt.io/qt-5/qwebenginepage.html#public-functions

QWebEnginePage(QObject *parent = Q_NULLPTR)

但我想要

QWebEnginePage(QWebEngineProfile *profile, QObject *parent = Q_NULLPTR)

因此更改为

self.page = QWebEnginePage(self.profile, None)

解决了此案。