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 invalidsrc
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?
Thanks
-
@donquibeats
The page is HTML, so just normal<img src="...">
syntax. Certainly notqrc:///
, won't be understood.file:////
should work if that's acceptable in HTML, not sure where that might be rooted from. Orvoid 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 withhttp://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 thatos.path.abspath(__file__)
should be an acceptable value forbaseUrl
, 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?
-
@eyllanesc
So this is using thevoid 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. -
@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 onos.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
toos.getcwd()
, otherwise the image won't show.