Important: Please read the Qt Code of Conduct -

Proper way to display local images in QtWebEngineView?

  • This is my first dip into QtWebEngineView, using it as a component in my larger PyQt5 app.

    There's a situation where I want to be able to show dynamically generated HTML in a preview widget. Things are working fine with QtWebEngineView and I'm using the setHtml() method to feed a programmatically-created HTML file directly to the widget without saving it to a file first.

    However I can't find a way of getting images to display using this method. I've tried qrc:/// URL's with relative paths for the application, file://// paths for absolute local paths, and so on. Everything I've tried so far has resulted in an invalid src showing as a broken link.

    Is there a way to get locally-stored images to display in a QtWebEngineView that has been populated using setHtml()?

    If so, what syntax should I be using for the img src tags please?

    Are there security restrictions about where the file can be stored, can the file be anywhere on the user's machine or must the files be within the domain of the application's working area etc.?

    These images will vary in number so as far as I can tell from the docs, a .qrc resource file isn't going to work for me?


  • @donquibeats
    The page is HTML, so just normal <img src="..."> syntax. Certainly not qrc:///, won't be understood. file://// should work if that's acceptable in HTML, not sure where that might be rooted from. Or void QWebEnginePage::setHtml(const QString &html, const QUrl &baseUrl = QUrl()) takes an optional base URL:

    baseUrl is optional and used to resolve relative URLs in the document, such as referenced images or stylesheets.

    I can't recall what plain /... is rooted at if you do not specify a base URL.

  • Thanks for the response.

    I can get images to show in the QtWebEngineView if I use test images off the internet, and set a baseUrl beginning with http://www. etc.

    However I'm still drawing a blank with trying to get the QtWebEngineView to show files that have been saved to a local folder. No option I've tried for the baseUrl setting has managed to sort that so far- I was particularly thinking that os.path.abspath(__file__) should be an acceptable value for baseUrl, but no joy with that.

    Again, I don't understand if there are sandboxing restrictions going on here.

    I seem to still be missing something?

  • Use view.setHtml(HTML_STR, QtCore.QUrl.FromLocalFile(os.path.dirname(os.path.realpath(__file__))))

  • @eyllanesc
    So this is using the void QWebEnginePage::setHtml(const QString &html, const QUrl &baseUrl = QUrl()) I referred to earlier. We should perhaps clarify to @donquibeats that this statement makes any relative URLs (e.g. in <img src="...">) to be sought relative to the directory of the Python script file executing this line. Depending on where the OP's image files are located, this might need adjusting appropriately.

  • I think the OP knows that since it tries to use os.path.abspath(__file__), also that is explicit in the docs

  • @eyllanesc
    I always respect your replies, they are always really good. However, in this case personally I am not keen on using __file__: if you lay out your Python program with subdirectories for sources, and this line comes in one of those subdirectories, links will relative to there, which may not be obvious.

    I think I would prefer using os.path.abspath(sys.argv[0]) so that I know everything is relative to where the main program script is, which doesn't change. What do you think?

  • Thanks @JonB and @eyllanesc for the really helpful responses. Thanks to you I've understood that the images should be within the folder structure of the running script, and I've got things working as wanted as a result.

    I already had a small custom function for identifying the path of the script, due to unrelated previous issues with PyInstaller and operating paths, so I was able to feed that to the QUrl constructor. But yes, when running in a non-compiled state, this is based on os.path.abspath.

    Thanks again

  • I'd give an example of proper loading local images from PyQt or PySide, in my case images should be within the folder structure of the running script.

    self.webPage.setHtml('<img src="uk_pron.png"/>', baseUrl=QUrl.fromLocalFile(os.getcwd()+os.path.sep))

    don't forget to add the trailing path separator os.path.sep to os.getcwd(), otherwise the image won't show.

Log in to reply