admin管理员组文章数量:1332383
I am currently trying to implement a custom url scheme using an in-app browser made with PyQtWebEngine. The problem I am facing is that the whole app crashes right after loading the custom scheme url. The strange part is that it only crashes when provided custom urls, meaning any normal http/https urls work completely fine.
My minimal code example is the following:
import sys
from PyQt5.QtWidgets import QMainWindow, QApplication
from PyQt5.QtWebEngineWidgets import QWebEngineView, QWebEngineProfile
from PyQt5.QtWebEngineCore import (
QWebEngineUrlRequestJob,
QWebEngineUrlSchemeHandler,
QWebEngineUrlScheme,
)
from PyQt5.QtCore import QUrl, QByteArray, QBuffer
class SchemeHandler(QWebEngineUrlSchemeHandler):
def requestStarted(self, request: QWebEngineUrlRequestJob | None) -> None:
if not request:
return
print(f"Got request for {request.requestUrl()}")
request.reply(
QByteArray(b"text/html"), QBuffer(QByteArray(b"<h1>Custom Scheme</h1>"))
)
class Browser(QMainWindow):
def __init__(self) -> None:
super().__init__()
browser = QWebEngineView()
self.setCentralWidget(browser)
browser.showMaximized()
self.handler = SchemeHandler()
profile = QWebEngineProfile.defaultProfile()
if profile:
profile.installUrlSchemeHandler(b"test", self.handler)
print("Installed SchemeHandler")
browser.load(QUrl("test://someurl"))
def register_scheme():
scheme = QWebEngineUrlScheme(b"test")
scheme.setFlags(
QWebEngineUrlScheme.SecureScheme | QWebEngineUrlScheme.LocalAccessAllowed
)
scheme.setSyntax(QWebEngineUrlScheme.Syntax.Path)
scheme.setDefaultPort(80)
QWebEngineUrlScheme.registerScheme(scheme)
if __name__ == "__main__":
register_scheme()
app = QApplication(sys.argv)
b = Browser()
b.show()
app.exec_()
and it outputs this:
Installed SchemeHandler
Got request for PyQt5.QtCore.QUrl('test://someurl')
I am running Windows 11 Build 22631.4460, Python 3.12.3, PyQt5 5.15.11 and PyQtWebEngine 5.15.7.
I already tried updating all libraries, running the example in a venv and adding debugging output like os.environ["QTWEBENGINE_CHROMIUM_FLAGS"] = "--enable-logging --v=1"
.
I would appreciate any help!
I am currently trying to implement a custom url scheme using an in-app browser made with PyQtWebEngine. The problem I am facing is that the whole app crashes right after loading the custom scheme url. The strange part is that it only crashes when provided custom urls, meaning any normal http/https urls work completely fine.
My minimal code example is the following:
import sys
from PyQt5.QtWidgets import QMainWindow, QApplication
from PyQt5.QtWebEngineWidgets import QWebEngineView, QWebEngineProfile
from PyQt5.QtWebEngineCore import (
QWebEngineUrlRequestJob,
QWebEngineUrlSchemeHandler,
QWebEngineUrlScheme,
)
from PyQt5.QtCore import QUrl, QByteArray, QBuffer
class SchemeHandler(QWebEngineUrlSchemeHandler):
def requestStarted(self, request: QWebEngineUrlRequestJob | None) -> None:
if not request:
return
print(f"Got request for {request.requestUrl()}")
request.reply(
QByteArray(b"text/html"), QBuffer(QByteArray(b"<h1>Custom Scheme</h1>"))
)
class Browser(QMainWindow):
def __init__(self) -> None:
super().__init__()
browser = QWebEngineView()
self.setCentralWidget(browser)
browser.showMaximized()
self.handler = SchemeHandler()
profile = QWebEngineProfile.defaultProfile()
if profile:
profile.installUrlSchemeHandler(b"test", self.handler)
print("Installed SchemeHandler")
browser.load(QUrl("test://someurl"))
def register_scheme():
scheme = QWebEngineUrlScheme(b"test")
scheme.setFlags(
QWebEngineUrlScheme.SecureScheme | QWebEngineUrlScheme.LocalAccessAllowed
)
scheme.setSyntax(QWebEngineUrlScheme.Syntax.Path)
scheme.setDefaultPort(80)
QWebEngineUrlScheme.registerScheme(scheme)
if __name__ == "__main__":
register_scheme()
app = QApplication(sys.argv)
b = Browser()
b.show()
app.exec_()
and it outputs this:
Installed SchemeHandler
Got request for PyQt5.QtCore.QUrl('test://someurl')
I am running Windows 11 Build 22631.4460, Python 3.12.3, PyQt5 5.15.11 and PyQtWebEngine 5.15.7.
I already tried updating all libraries, running the example in a venv and adding debugging output like os.environ["QTWEBENGINE_CHROMIUM_FLAGS"] = "--enable-logging --v=1"
.
I would appreciate any help!
Share Improve this question edited Nov 21, 2024 at 13:00 ekhumoro 121k22 gold badges252 silver badges366 bronze badges asked Nov 21, 2024 at 8:17 JoaJoa 527 bronze badges 1- Have a look at: QtWebEngine intercepting request with custom URL schema serving reply. – Maurice Meyer Commented Nov 21, 2024 at 9:44
1 Answer
Reset to default 0The problem here is that the buffer will be immediately garbage-collected once the requestStarted
method returns. The reply is processed asynchronously, so when the request-job tries to access the buffer later, it will find nothing there, causing a fatal error. Strictly speaking, the same applies to the data passed to the buffer as well - this has to remain fully available for the entire read operation, otherwise it could also cause a fatal error. (NB: the Qt docs will usually include warnings about these kinds of issues by stating that it's the caller's responsibility to maintain ownership of the relevant objects).
Given all the above, your example can be fixed by keeping references to the buffer and data, like this:
class SchemeHandler(QWebEngineUrlSchemeHandler):
def requestStarted(self, request: QWebEngineUrlRequestJob | None) -> None:
if not request:
return
print(f"Got request for {request.requestUrl()}")
mimetype = QByteArray(b"text/html")
# keep a reference to the buffered data
self._data = QByteArray(b"<h1>Custom Scheme</h1>")
# make the request-job the parent of the buffer
buffer = QBuffer(request)
buffer.setData(self._data)
buffer.open(QBuffer.ReadOnly)
request.reply(mimetype, buffer)
本文标签: pythonPyQt WebEngine custom scheme crashStack Overflow
版权声明:本文标题:python - PyQt WebEngine custom scheme crash - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1742302969a2449358.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论