Web view in Python in Slicer-4.9

In Qt4, I used to use qt.QWebView() to show html content on the GUI, but this does not seem to be available in Qt5 in Slicer. I’ve tried to access Qt WebEngine from Python but it is either not wrapped or I just could not find it.

Is there an equivalent in Qt5?

This should work on both Qt4 and Qt5:

w = slicer.qSlicerWebWidget()
w.webView().url = qt.QUrl("https://eff.org/")
w.show()

This approach also has the advantage of abstracting the interface.

Following r26986, executing javascript on the page can be done from python using:

w.evalJS("window.alert('Hello')")

Thank you very much! The web widget appears, with a small style error that scrollbars (both horizontal and vertical) have about 2x larger than anywhere else in the application:

image

However, a bigger issue is that webView’s page member (QWebEnginePage) is not accessible from Python. This severely limits usability.

For example, we used this code before, to set the widget size to show a HTML page in the layout without scrollbars (make the widget height as large as the content after content was loaded):

frame = webView.page().mainFrame()
webView.page().setViewportSize(frame.contentsSize)
webView.setMinimumHeight(frame.contentsSize.height())

Why page is not accessible in Python? Why I cannot instantiate a QWebEngineView object directly in Python?

We rely on PythonQt for wrapping the Qt base class.

@pieper At some point did you look into enabling the wrapping for webengine ?

1 Like

Right, I believe PythonQt does not yet wrap all the classes we would need and not clear yet when it will.

Instead it seemed we could get by with writing higher level methods in C++ and expose them in qSlicerWebWidget for use in python. Something like webWidget.setSizeToContentSize() for similar for the situation Andras mentioned.

I think we have a fairly short list of requirements at that level.

Just out of curiosity, how difficult it is to add wrapping for a class? Isn’t it automatic? Is there something particularly problematic with the web view? Do they accept pull requests if we implement wrapping for some new classes?

In the short term, I’ll just add functions in our own wrapper class in Slicer.

There is a custom wrapper generator and it can be run on any Qt source tree to generate the wrapping. I hadn’t looked into it much until recently there was an issue with the socket types. To avoid needing to compile and run the generator when building PythonQt, the generated sources are in the repository and they are only updated as needed (as needed by Florian for MeVislab basically), but it’s not that hard to build the generator and experiment. There are already some QtWebEngine files in the repository but they aren’t enabled and didn’t completely work last time I checked (early in the Slicer Qt5 porting process).

So, yes, it may be that updating PythonQt’s generator to work well with QtWebEngine would be a more general fix. And yes probably the key elements of that would be possible to put back into PythonQt. But PythonQt uses qmake, so the CMake parts that we would need would still be in the commontk fork.

Thanks for the information!

OK, probably I won’t try to enable it then. I’ll just add what I specifically need to the Slicer wrapper.