# Web view in Python in Slicer-4.9

**URL:** <https://discourse.slicer.org/t/web-view-in-python-in-slicer-4-9/2224>\
**Category:** Development\
**Created:** [March 2, 2018, 3:27am UTC](https://discourse.slicer.org/t/web-view-in-python-in-slicer-4-9/2224 "2018-03-02T03:27:18Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![lassoan](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/lassoan/32/13_2.png) [@lassoan](https://discourse.slicer.org/u/lassoan)\
**Post date:** [March 2, 2018, 3:27am UTC](https://discourse.slicer.org/t/web-view-in-python-in-slicer-4-9/2224/1 "2018-03-02T03:27:19Z")

</div>

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?

---

<div class="post-metadata">

**Author:** ![jcfr](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/jcfr/32/17825_2.png) [@jcfr](https://discourse.slicer.org/u/jcfr)\
**Post date:** [March 2, 2018, 3:52am UTC](https://discourse.slicer.org/t/web-view-in-python-in-slicer-4-9/2224/2 "2018-03-02T03:52:23Z")

</div>

This should work on both Qt4 and Qt5:

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

```

---

<div class="post-metadata">

**Author:** ![jcfr](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/jcfr/32/17825_2.png) [@jcfr](https://discourse.slicer.org/u/jcfr)\
**Post date:** [March 2, 2018, 7:51am UTC](https://discourse.slicer.org/t/web-view-in-python-in-slicer-4-9/2224/3 "2018-03-02T07:51:14Z")

</div>

This approach also has the advantage of abstracting the interface.

Following [r26986](http://viewvc.slicer.org/viewvc.cgi/Slicer4?view=revision&revision=26986), executing javascript on the page can be done from python using:

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

```

---

<div class="post-metadata">

**Author:** ![lassoan](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/lassoan/32/13_2.png) [@lassoan](https://discourse.slicer.org/u/lassoan)\
**Post date:** [March 3, 2018, 3:07pm UTC](https://discourse.slicer.org/t/web-view-in-python-in-slicer-4-9/2224/4 "2018-03-03T15:07:22Z")

</div>

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](https://us1.discourse-cdn.com/flex002/uploads/slicer/original/3X/1/e/1e146afbb9fb4a6e0c021e0340d3992879440ab6.jpeg)

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?

---

<div class="post-metadata">

**Author:** ![jcfr](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/jcfr/32/17825_2.png) [@jcfr](https://discourse.slicer.org/u/jcfr)\
**Post date:** [March 3, 2018, 10:55pm UTC](https://discourse.slicer.org/t/web-view-in-python-in-slicer-4-9/2224/5 "2018-03-03T22:55:09Z")

</div>

We rely on PythonQt for wrapping the Qt base class.

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

---

<div class="post-metadata">

**Author:** ![pieper](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/pieper/32/8_2.png) [@pieper](https://discourse.slicer.org/u/pieper)\
**Post date:** [March 4, 2018, 2:39pm UTC](https://discourse.slicer.org/t/web-view-in-python-in-slicer-4-9/2224/6 "2018-03-04T14:39:37Z")

</div>

> [@jcfr](#):
>
> @pieper At some point did you look into enabling the wrapping for webengine ?

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.

---

<div class="post-metadata">

**Author:** ![lassoan](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/lassoan/32/13_2.png) [@lassoan](https://discourse.slicer.org/u/lassoan)\
**Post date:** [March 4, 2018, 2:53pm UTC](https://discourse.slicer.org/t/web-view-in-python-in-slicer-4-9/2224/7 "2018-03-04T14:53:56Z")

</div>

> [@pieper](#):
>
> I believe PythonQt does not yet wrap all the classes we would need and not clear yet when it will

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.

---

<div class="post-metadata">

**Author:** ![pieper](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/pieper/32/8_2.png) [@pieper](https://discourse.slicer.org/u/pieper)\
**Post date:** [March 5, 2018, 12:50pm UTC](https://discourse.slicer.org/t/web-view-in-python-in-slicer-4-9/2224/8 "2018-03-05T12:50:40Z")

</div>

> [@lassoan](#):
>
> 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?

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](https://sourceforge.net/p/pythonqt/discussion/631392/thread/c989429c/). 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.

---

<div class="post-metadata">

**Author:** ![lassoan](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/lassoan/32/13_2.png) [@lassoan](https://discourse.slicer.org/u/lassoan)\
**Post date:** [March 5, 2018, 1:42pm UTC](https://discourse.slicer.org/t/web-view-in-python-in-slicer-4-9/2224/9 "2018-03-05T13:42:31Z")

</div>

Thanks for the information!

> [@pieper](#):
>
> There are already some QtWebEngine files in the repository but they aren’t enabled and didn’t completely work

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