# PythonQt properties shadowing methods

**URL:** https://discourse.slicer.org/t/pythonqt-properties-shadowing-methods/16992
**Category:** Development
**Created:** [April 8, 2021, 1:38am UTC](https://discourse.slicer.org/t/pythonqt-properties-shadowing-methods/16992 "2021-04-08T01:38:10Z")
**Posts on this page:** 1
**Showing post:** 9

<div class="post-metadata">

### Author: ![fbordignon](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/fbordignon/32/5269_2.png) [@fbordignon](https://discourse.slicer.org/u/fbordignon)
#### Post date: [August 30, 2021, 1:14pm UTC](https://discourse.slicer.org/t/pythonqt-properties-shadowing-methods/16992/9 "2021-08-30T13:14:19Z")

</div>

For this example, the user needs to have the [python3.dll fix](https://github.com/Slicer/Slicer/pull/5822), alternatively one can temporarily [download and install WinPython 3.6.7](https://sourceforge.net/projects/winpython/files/WinPython_3.6/3.6.7.0/WinPython64-3.6.7.0Zero.exe/download) and copy python3.dll from `winpython/python-3.6.7.amd64/python3.dll` to `Slicer/bin/python3.dll`  
Slicer can crash if one does not have PythonQt compiled with [this fix](https://github.com/commontk/PythonQt/pull/81). It works without it, but Slicer can become unstable.

Working example based on [plotting example of pyqtgraph](https://github.com/pyqtgraph/pyqtgraph/blob/master/examples/Plotting.py):

```python
# Copy and paste this on Slicer's python terminal
pip_install('pyside2==5.15.1') # must be important to match pyside2 version to slicer's qt version
pip_install('pyqtgraph')

import textwrap
from PySide2.QtWidgets import QVBoxLayout
import shiboken2
import numpy as np
from pyqtgraph.Qt import QtGui, QtCore
import pyqtgraph as pg

# Custom layout base class
class BaseLayout:
    TAG = "EmptyScreen"
    UID = 1010
    LAYOUT = textwrap.dedent(
        f"""
        <layout type="vertical">
            <item>
                <{TAG}></{TAG}>
            </item>
        </layout>
    """
    )
    @classmethod
    def register(cls):
        viewFactory = slicer.qSlicerSingletonViewFactory()
        viewFactory.setTagName(cls.TAG)
        if slicer.app.layoutManager() is not None:
            slicer.app.layoutManager().registerViewFactory(viewFactory)
        container = cls.build(viewFactory)
        layoutManager = slicer.app.layoutManager()
        layoutManager.layoutLogic().GetLayoutNode().AddLayoutDescription(cls.UID, cls.LAYOUT)
        return container
    @classmethod
    def build(cls, factory):
        viewWidget = qt.QWidget()
        viewWidget.setAutoFillBackground(True)
        factory.setWidget(viewWidget)
        viewLayout = qt.QVBoxLayout()
        viewWidget.setLayout(viewLayout)
        return viewWidget
    @classmethod
    def show(cls):
        slicer.app.layoutManager().setLayout(cls.UID)

#my plot layout class
class PlotLayout(BaseLayout):
    TAG = "MyPlotWidget"
    UID = 1019
    LAYOUT = textwrap.dedent(f"""
        <layout type="vertical">
            <item>
                <{TAG}></{TAG}>
            </item>
        </layout>
    """)

lw = PlotLayout.register().layout()
PlotLayout.show()

# wrap pythonQt instance with shiboken2 (pyside2)
pysidelayout = shiboken2.wrapInstance(hash(lw), QVBoxLayout)

pg.mkQApp()

# start of pyqtgraph plotting example https://github.com/pyqtgraph/pyqtgraph/blob/master/examples/Plotting.py
win = pg.GraphicsLayoutWidget(show=True, title="Basic plotting examples")
pysidelayout.addWidget(win)

# Enable antialiasing for prettier plots
pg.setConfigOptions(antialias=True)

p1 = win.addPlot(title="Basic array plotting", y=np.random.normal(size=100))

p2 = win.addPlot(title="Multiple curves")
p2.plot(np.random.normal(size=100), pen=(255,0,0), name="Red curve")
p2.plot(np.random.normal(size=110)+5, pen=(0,255,0), name="Green curve")
p2.plot(np.random.normal(size=120)+10, pen=(0,0,255), name="Blue curve")

p3 = win.addPlot(title="Drawing with points")
p3.plot(np.random.normal(size=100), pen=(200,200,200), symbolBrush=(255,0,0), symbolPen='w')

win.nextRow()

p4 = win.addPlot(title="Parametric, grid enabled")
x = np.cos(np.linspace(0, 2*np.pi, 1000))
y = np.sin(np.linspace(0, 4*np.pi, 1000))
p4.plot(x, y)
p4.showGrid(x=True, y=True)

p5 = win.addPlot(title="Scatter plot, axis labels, log scale")
x = np.random.normal(size=1000) * 1e-5
y = x*1000 + 0.005 * np.random.normal(size=1000)
y -= y.min()-1.0
mask = x > 1e-15
x = x[mask]
y = y[mask]
p5.plot(x, y, pen=None, symbol='t', symbolPen=None, symbolSize=10, symbolBrush=(100, 100, 255, 50))
p5.setLabel('left', "Y Axis", units='A')
p5.setLabel('bottom', "Y Axis", units='s')
p5.setLogMode(x=True, y=False)

p6 = win.addPlot(title="Updating plot")
curve = p6.plot(pen='y')
data = np.random.normal(size=(10,1000))
ptr = 0

def update():
    global curve, data, ptr, p6
    curve.setData(data[ptr%10])
    if ptr == 0:
        p6.enableAutoRange('xy', False) ## stop auto-scaling after the first data set is plotted
    ptr += 1

timer = QtCore.QTimer()
timer.timeout.connect(update)
timer.start(50)

win.nextRow()

p7 = win.addPlot(title="Filled plot, axis disabled")
y = np.sin(np.linspace(0, 10, 1000)) + np.random.normal(size=1000, scale=0.1)
p7.plot(y, fillLevel=-0.3, brush=(50,50,200,100))
p7.showAxis('bottom', False)

x2 = np.linspace(-100, 100, 1000)
data2 = np.sin(x2) / x2
p8 = win.addPlot(title="Region Selection")
p8.plot(data2, pen=(255,255,255,200))
lr = pg.LinearRegionItem([400,700])
lr.setZValue(-10)
p8.addItem(lr)

p9 = win.addPlot(title="Zoom on selected region")
p9.plot(data2)

def updatePlot():
    p9.setXRange(*lr.getRegion(), padding=0)

def updateRegion():
    lr.setRegion(p9.getViewBox().viewRange()[0])

lr.sigRegionChanged.connect(updatePlot)
p9.sigXRangeChanged.connect(updateRegion)
updatePlot()

```

 ![image](https://us1.discourse-cdn.com/flex002/uploads/slicer/original/3X/a/4/a402884270034660f227ec6aa37fcca44ae5c5b8.png)

---

_[View the full topic](https://discourse.slicer.org/t/pythonqt-properties-shadowing-methods/16992)._
