Как загрузить SWF-файл в QWebEngineView из памяти

#python #flash #pyqt5 #qtwebengine

#python #flash #pyqt5 #qtwebengine

Вопрос:

я пытаюсь загрузить flash (swf) файл с помощью QWebEngineView я хочу загрузить swf из памяти, но пока мне удалось загрузить его только с URL-адреса

данные — это bytearray результата urlopen (urllib). self.webview является экземпляром QWebEngineView.

 self.webview.load(QtCore.QUrl(url))              # works
self.webview.setContent(QtCore.QByteArray(data)) # does not work
  

используя URL-адрес, запускается SWF-файл. загрузка из bytearray приводит к пустой странице или странице с тарабарщиной. ошибок не отображается.

я использую pyqt5 с python3

Комментарии:

1. Почему вы удалили свой ответ? На какой URL вы ссылаетесь в своем вопросе?

2. @eyllanesc я не заметил, что забыл удалить старую функцию загрузки, она не работала, она загружалась только с помощью load после сбоя с использованием setContent. он работает с любым внешним URL, пробовал несколько разных сайтов. URL- это строка здесь.

3. Не могли бы вы предоставить мне один из тех «URL», которые вы использовали для своего теста

4. @eyllanesc да, одна из ссылок, которые я использовал » condor.depaul.edu/sjost/hci430/flash-examples/swf/wheel.swf »

5. Еще один вопрос: какую версию pyqt5 вы используете и какая у вас операционная система?

Ответ №1:

Кажется, что вы не можете напрямую передавать необработанные данные, поэтому обходным путем является создание пользовательского 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_())
  

Комментарии:

1. Большое вам спасибо за вашу помощь, это обходное решение отлично работает! теперь я могу загружать flash-файлы в свой qt gui и из памяти и переключаться между flash-файлами быстро и без использования сети (после кэширования)