Python 如何从内存将swf文件加载到QWebEngineView

Python 如何从内存将swf文件加载到QWebEngineView,python,flash,pyqt5,qtwebengine,Python,Flash,Pyqt5,Qtwebengine,我正在尝试使用QWebEngineView加载flash(swf)文件 我想从内存加载swf,但到目前为止我只能从URL加载它 数据是urlopen(urllib)结果的字节数组。 self.webview是QWebEngineView的一个实例 self.webview.load(QtCore.QUrl(url))# self.webview.setContent(QtCore.QByteArray(data))不工作 使用swf运行的URL。从bytearray加载将导致空页或乱码页面。没

我正在尝试使用QWebEngineView加载flash(swf)文件 我想从内存加载swf,但到目前为止我只能从URL加载它

数据是urlopen(urllib)结果的字节数组。
self.webview
是QWebEngineView的一个实例

self.webview.load(QtCore.QUrl(url))#
self.webview.setContent(QtCore.QByteArray(data))不工作
使用swf运行的URL。从bytearray加载将导致空页或乱码页面。没有显示错误


我将pyqt5与python3一起使用,您似乎无法直接传递原始数据,因此解决方法是创建一个自定义的QWebEngineUrlSchemeHandler,通过url提供资源:

from PyQt5 import QtCore, QtWidgets, QtWebEngineCore, QtWebEngineWidgets


class CustomUrlSchemeHandler(QtWebEngineCore.QWebEngineUrlSchemeHandler):
    SCHEMENAME = b"custom"

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

    def add_data(self, path, mimetype, data):
        self._datas[path] = mimetype, data
        url = QtCore.QUrl()
        url.setScheme(self.SCHEMENAME.decode())
        url.setPath(path)
        return url

    def requestStarted(self, job):
        requestMethod = job.requestMethod()
        if requestMethod != b"GET":
            job.fail(QtWebEngineCore.QWebEngineUrlRequestJob.RequestDenied)
            return

        requestUrl = job.requestUrl()
        requestPath = requestUrl.path()
        value = self._datas.get(requestPath)
        if value is not None:
            mimetype, data = value
            buf = QtCore.QBuffer(parent=self)
            job.destroyed.connect(buf.deleteLater)
            buf.open(QtCore.QIODevice.WriteOnly)
            buf.write(data)
            buf.close()
            job.reply(mimetype.encode(), buf)
        else:
            job.fail(QtWebEngineCore.QWebEngineUrlRequestJobUrlNotFound)

    @classmethod
    def registerUrlScheme(cls):
        scheme = QtWebEngineCore.QWebEngineUrlScheme(cls.SCHEMENAME)
        QtWebEngineCore.QWebEngineUrlScheme.registerScheme(scheme)


if __name__ == "__main__":

    import sys
    import urllib.request

    data = b""
    with urllib.request.urlopen(
        "https://condor.depaul.edu/sjost/hci430/flash-examples/swf/wheel.swf"
    ) as response:
        data = response.read()

    CustomUrlSchemeHandler.registerUrlScheme()

    app = QtWidgets.QApplication(sys.argv)

    settings = QtWebEngineWidgets.QWebEngineSettings.defaultSettings()
    settings.setAttribute(QtWebEngineWidgets.QWebEngineSettings.PluginsEnabled, True)

    view = QtWebEngineWidgets.QWebEngineView()

    handler = CustomUrlSchemeHandler()
    view.page().profile().installUrlSchemeHandler(handler.SCHEMENAME, handler)

    view.resize(640, 480)
    view.show()

    url = handler.add_data("test.swg", "application/x-shockwave-flash", data)
    view.load(url)

    sys.exit(app.exec_())

您似乎无法直接传递原始数据,因此解决方法是创建一个自定义QWebEngineUrlSchemeHandler,通过url提供资源:

from PyQt5 import QtCore, QtWidgets, QtWebEngineCore, QtWebEngineWidgets


class CustomUrlSchemeHandler(QtWebEngineCore.QWebEngineUrlSchemeHandler):
    SCHEMENAME = b"custom"

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

    def add_data(self, path, mimetype, data):
        self._datas[path] = mimetype, data
        url = QtCore.QUrl()
        url.setScheme(self.SCHEMENAME.decode())
        url.setPath(path)
        return url

    def requestStarted(self, job):
        requestMethod = job.requestMethod()
        if requestMethod != b"GET":
            job.fail(QtWebEngineCore.QWebEngineUrlRequestJob.RequestDenied)
            return

        requestUrl = job.requestUrl()
        requestPath = requestUrl.path()
        value = self._datas.get(requestPath)
        if value is not None:
            mimetype, data = value
            buf = QtCore.QBuffer(parent=self)
            job.destroyed.connect(buf.deleteLater)
            buf.open(QtCore.QIODevice.WriteOnly)
            buf.write(data)
            buf.close()
            job.reply(mimetype.encode(), buf)
        else:
            job.fail(QtWebEngineCore.QWebEngineUrlRequestJobUrlNotFound)

    @classmethod
    def registerUrlScheme(cls):
        scheme = QtWebEngineCore.QWebEngineUrlScheme(cls.SCHEMENAME)
        QtWebEngineCore.QWebEngineUrlScheme.registerScheme(scheme)


if __name__ == "__main__":

    import sys
    import urllib.request

    data = b""
    with urllib.request.urlopen(
        "https://condor.depaul.edu/sjost/hci430/flash-examples/swf/wheel.swf"
    ) as response:
        data = response.read()

    CustomUrlSchemeHandler.registerUrlScheme()

    app = QtWidgets.QApplication(sys.argv)

    settings = QtWebEngineWidgets.QWebEngineSettings.defaultSettings()
    settings.setAttribute(QtWebEngineWidgets.QWebEngineSettings.PluginsEnabled, True)

    view = QtWebEngineWidgets.QWebEngineView()

    handler = CustomUrlSchemeHandler()
    view.page().profile().installUrlSchemeHandler(handler.SCHEMENAME, handler)

    view.resize(640, 480)
    view.show()

    url = handler.add_data("test.swg", "application/x-shockwave-flash", data)
    view.load(url)

    sys.exit(app.exec_())

你为什么删除你的答案?在你的问题中,你指的是什么url?@eyllanesc我没有注意到我忘记删除旧的加载函数,它不起作用,只是在使用setContent失败后使用load加载。它适用于任何外部url,并尝试了几个不同的网站。url在这里是一个字符串。你能给我提供一个你在网站上使用的“url”吗test@eyllanesc是的,我使用的其中一个链接“”还有一个问题:您使用的是什么版本的pyqt5?您的操作系统是什么?为什么删除您的答案?在你的问题中,你指的是什么url?@eyllanesc我没有注意到我忘记删除旧的加载函数,它不起作用,只是在使用setContent失败后使用load加载。它适用于任何外部url,并尝试了几个不同的网站。url在这里是一个字符串。你能给我提供一个你在网站上使用的“url”吗test@eyllanesc是的,我使用的其中一个链接“”还有一个问题:您使用的是什么版本的pyqt5,您的操作系统是什么?非常感谢您的帮助,此解决方案非常有效!我现在可以在我的qt gui和内存中加载flash文件,并在flash文件之间快速切换,无需网络使用(一旦缓存)。非常感谢您的帮助,此解决方案非常有效!现在,我可以在qt gui和内存中加载flash文件,并在flash文件之间快速切换,无需网络使用(一旦缓存)