SaibotMagd
7th July 2020, 17:51
Hello,
I'm a somewhat programming and python nooby and I have to implement a pipeline in my institut. A researcher create a dataviewer in the tutorial file using PyQt5 but even the test-function push the process into a hanging state (kernel is forced to restart after the window is terminated). i.e. it creates a pop-up window with the correct name and resolution but the window itself is black without any widgets and it halts immediately.
I know it's a somewhat impossible mission to find the solution but maybe someone got a climse of a idea what I could try next.
class DataViewer(pg.QtGui.QWidget):
def __init__(self, source, axis = None, scale = None, title = None, invertY = False, minMax = None, screen = None, parent = None, *args):
### Print pointer to QApplication Instance (we now know that at this time a QApp is initalized)
print(pg.QtGui.QApplication.instance())
print(pg.QtGui.QApplication.allWidgets())
### Images soures
self.initializeSources(source, axis = axis, scale = scale)
#print('init')
### Gui Construction
pg.QtGui.QWidget.__init__(self, parent, *args);
#print('gui')
if title is None:
if isinstance(source, str):
title = source;
elif isinstance(source, io.src.Source):
title = source.location;
if title is None:
title = 'DataViewer';
self.setWindowTitle(title);
self.resize(1600,1200)
#print('title')
self.layout = pg.QtGui.QGridLayout(self);
self.layout.setContentsMargins(0,0,0,0)
#print('layout')
# image pane
self.view = pg.ViewBox();
self.view.setAspectLocked(True);
self.view.invertY(invertY)
self.graphicsView = pg.GraphicsView()
self.graphicsView.setObjectName("GraphicsView")
self.graphicsView.setCentralItem(self.view)
splitter = pg.QtGui.QSplitter();
splitter.setOrientation(pg.QtCore.Qt.Horizontal)
splitter.setSizes([self.width() - 10, 10]);
self.layout.addWidget(splitter);
image_splitter = pg.QtGui.QSplitter();
image_splitter.setOrientation(pg.QtCore.Qt.Vertica l)
image_splitter.setSizePolicy(pg.QtGui.QSizePolicy. Expanding, pg.QtGui.QSizePolicy.Expanding)
splitter.addWidget(image_splitter);
#print('image')
# Image plots
image_options = dict(clipToView = True, autoDownsample = True, autoLevels = False, useOpenGL = None);
self.image_items = [pg.ImageItem(s[self.source_slice[:s.ndim]], **image_options) for s in self.sources];
for i in self.image_items:
i.setRect(pg.QtCore.QRect(0, 0, self.source_range_x, self.source_range_y))
i.setCompositionMode(pg.QtGui.QPainter.Composition Mode_Plus);
self.view.addItem(i);
self.view.setXRange(0, self.source_range_x);
self.view.setYRange(0, self.source_range_y);
#print('plots')
# Slice Selector
self.slicePlot = pg.PlotWidget()
sizePolicy = pg.QtGui.QSizePolicy(pg.QtGui.QSizePolicy.Preferre d, pg.QtGui.QSizePolicy.Preferred)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.slicePlot.sizePo licy().hasHeightForWidth())
self.slicePlot.setSizePolicy(sizePolicy)
self.slicePlot.setMinimumSize(pg.QtCore.QSize(0, 40))
self.slicePlot.setObjectName("roiPlot");
#self.sliceCurve = self.slicePlot.plot()
self.sliceLine = pg.InfiniteLine(0, movable=True)
self.sliceLine.setPen((255, 255, 255, 200))
self.sliceLine.setZValue(1)
self.slicePlot.addItem(self.sliceLine)
self.slicePlot.hideAxis('left')
self.updateSlicer();
self.sliceLine.sigPositionChanged.connect(self.upd ateSlice)
#print('slice')
# Axis Tools
axis_tools_layout = pg.QtGui.QGridLayout()
self.axis_buttons = [];
axesnames = ['x', 'y', 'z'];
for d in range(3):
button = pg.QtGui.QRadioButton(axesnames[d]);
button.setMaximumWidth(50);
axis_tools_layout.addWidget(button,0,d);
button.clicked.connect(ft.partial(self.setSliceAxi s, d));
self.axis_buttons.append(button);
self.axis_buttons[self.source_axis].setChecked(True);
axis_tools_widget = pg.QtGui.QWidget();
axis_tools_widget.setLayout(axis_tools_layout);
#print('axis')
# coordinate label
self.source_pointer = [0,0,0];
self.source_label = pg.QtGui.QLabel("");
axis_tools_layout.addWidget(self.source_label,0,3) ;
self.graphicsView.scene().sigMouseMoved.connect(se lf.updateLabelFromMouseMove);
#print('coords')
#compose the image viewer
image_splitter.addWidget(self.graphicsView);
image_splitter.addWidget(self.slicePlot)
image_splitter.addWidget(axis_tools_widget);
image_splitter.setSizes([self.height()-35-20, 35, 20])
#print('viewer')
# lut widgets
if self.nsources == 1:
cols = ['flame'];
elif self.nsources == 2:
cols = ['purple', 'green'];
else:
cols = np.array(['white', 'green','red', 'blue', 'purple'] * self.nsources)[:self.nsources];
self.luts = [LUT(image = i, color = c) for i,c in zip(self.image_items, cols)];
lut_layout = pg.QtGui.QGridLayout();
lut_layout.setContentsMargins(0,0,0,0);
for d,l in enumerate(self.luts):
lut_layout.addWidget(l,0,d);
lut_widget = pg.QtGui.QWidget();
lut_widget.setLayout(lut_layout);
lut_widget.setContentsMargins(0,0,0,0);
lut_widget.setSizePolicy(pg.QtGui.QSizePolicy.Pref erred, pg.QtGui.QSizePolicy.Expanding)
splitter.addWidget(lut_widget);
splitter.setStretchFactor(0, 1);
splitter.setStretchFactor(1, 0);
# update scale
for l in self.luts:
l.range_buttons[1][2].click();
if minMax is not None:
self.setMinMax(minMax);
self.show();
print(pg.QtGui.QApplication.instance())
What I found out till now:
the "allWidget()" function print out all widgets collected by the QApp. and this works finde
the code runs till the end (I got a instance pointer at the beginning and in the end; there're the same)
I tried several PyQt examples to test for openGL or non openGL Outputs and they all worked fine
there's no out-of-memory or CPU overload
I tried to cut the code per widget to find the issue, but whatever line of code I commented out no window pops-up anymore
I found this great article: https://doc.qt.io/archives/qq/qq27-responsive-guis.html#conclusion Could it be something like that?
Like I said I'm not a programmer and I didn't write the code myself (the author don't answer right now). Its overwhelming but I have to find a solution. Any ideas what I could try next? Anything would be helpful.
I'm a somewhat programming and python nooby and I have to implement a pipeline in my institut. A researcher create a dataviewer in the tutorial file using PyQt5 but even the test-function push the process into a hanging state (kernel is forced to restart after the window is terminated). i.e. it creates a pop-up window with the correct name and resolution but the window itself is black without any widgets and it halts immediately.
I know it's a somewhat impossible mission to find the solution but maybe someone got a climse of a idea what I could try next.
class DataViewer(pg.QtGui.QWidget):
def __init__(self, source, axis = None, scale = None, title = None, invertY = False, minMax = None, screen = None, parent = None, *args):
### Print pointer to QApplication Instance (we now know that at this time a QApp is initalized)
print(pg.QtGui.QApplication.instance())
print(pg.QtGui.QApplication.allWidgets())
### Images soures
self.initializeSources(source, axis = axis, scale = scale)
#print('init')
### Gui Construction
pg.QtGui.QWidget.__init__(self, parent, *args);
#print('gui')
if title is None:
if isinstance(source, str):
title = source;
elif isinstance(source, io.src.Source):
title = source.location;
if title is None:
title = 'DataViewer';
self.setWindowTitle(title);
self.resize(1600,1200)
#print('title')
self.layout = pg.QtGui.QGridLayout(self);
self.layout.setContentsMargins(0,0,0,0)
#print('layout')
# image pane
self.view = pg.ViewBox();
self.view.setAspectLocked(True);
self.view.invertY(invertY)
self.graphicsView = pg.GraphicsView()
self.graphicsView.setObjectName("GraphicsView")
self.graphicsView.setCentralItem(self.view)
splitter = pg.QtGui.QSplitter();
splitter.setOrientation(pg.QtCore.Qt.Horizontal)
splitter.setSizes([self.width() - 10, 10]);
self.layout.addWidget(splitter);
image_splitter = pg.QtGui.QSplitter();
image_splitter.setOrientation(pg.QtCore.Qt.Vertica l)
image_splitter.setSizePolicy(pg.QtGui.QSizePolicy. Expanding, pg.QtGui.QSizePolicy.Expanding)
splitter.addWidget(image_splitter);
#print('image')
# Image plots
image_options = dict(clipToView = True, autoDownsample = True, autoLevels = False, useOpenGL = None);
self.image_items = [pg.ImageItem(s[self.source_slice[:s.ndim]], **image_options) for s in self.sources];
for i in self.image_items:
i.setRect(pg.QtCore.QRect(0, 0, self.source_range_x, self.source_range_y))
i.setCompositionMode(pg.QtGui.QPainter.Composition Mode_Plus);
self.view.addItem(i);
self.view.setXRange(0, self.source_range_x);
self.view.setYRange(0, self.source_range_y);
#print('plots')
# Slice Selector
self.slicePlot = pg.PlotWidget()
sizePolicy = pg.QtGui.QSizePolicy(pg.QtGui.QSizePolicy.Preferre d, pg.QtGui.QSizePolicy.Preferred)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.slicePlot.sizePo licy().hasHeightForWidth())
self.slicePlot.setSizePolicy(sizePolicy)
self.slicePlot.setMinimumSize(pg.QtCore.QSize(0, 40))
self.slicePlot.setObjectName("roiPlot");
#self.sliceCurve = self.slicePlot.plot()
self.sliceLine = pg.InfiniteLine(0, movable=True)
self.sliceLine.setPen((255, 255, 255, 200))
self.sliceLine.setZValue(1)
self.slicePlot.addItem(self.sliceLine)
self.slicePlot.hideAxis('left')
self.updateSlicer();
self.sliceLine.sigPositionChanged.connect(self.upd ateSlice)
#print('slice')
# Axis Tools
axis_tools_layout = pg.QtGui.QGridLayout()
self.axis_buttons = [];
axesnames = ['x', 'y', 'z'];
for d in range(3):
button = pg.QtGui.QRadioButton(axesnames[d]);
button.setMaximumWidth(50);
axis_tools_layout.addWidget(button,0,d);
button.clicked.connect(ft.partial(self.setSliceAxi s, d));
self.axis_buttons.append(button);
self.axis_buttons[self.source_axis].setChecked(True);
axis_tools_widget = pg.QtGui.QWidget();
axis_tools_widget.setLayout(axis_tools_layout);
#print('axis')
# coordinate label
self.source_pointer = [0,0,0];
self.source_label = pg.QtGui.QLabel("");
axis_tools_layout.addWidget(self.source_label,0,3) ;
self.graphicsView.scene().sigMouseMoved.connect(se lf.updateLabelFromMouseMove);
#print('coords')
#compose the image viewer
image_splitter.addWidget(self.graphicsView);
image_splitter.addWidget(self.slicePlot)
image_splitter.addWidget(axis_tools_widget);
image_splitter.setSizes([self.height()-35-20, 35, 20])
#print('viewer')
# lut widgets
if self.nsources == 1:
cols = ['flame'];
elif self.nsources == 2:
cols = ['purple', 'green'];
else:
cols = np.array(['white', 'green','red', 'blue', 'purple'] * self.nsources)[:self.nsources];
self.luts = [LUT(image = i, color = c) for i,c in zip(self.image_items, cols)];
lut_layout = pg.QtGui.QGridLayout();
lut_layout.setContentsMargins(0,0,0,0);
for d,l in enumerate(self.luts):
lut_layout.addWidget(l,0,d);
lut_widget = pg.QtGui.QWidget();
lut_widget.setLayout(lut_layout);
lut_widget.setContentsMargins(0,0,0,0);
lut_widget.setSizePolicy(pg.QtGui.QSizePolicy.Pref erred, pg.QtGui.QSizePolicy.Expanding)
splitter.addWidget(lut_widget);
splitter.setStretchFactor(0, 1);
splitter.setStretchFactor(1, 0);
# update scale
for l in self.luts:
l.range_buttons[1][2].click();
if minMax is not None:
self.setMinMax(minMax);
self.show();
print(pg.QtGui.QApplication.instance())
What I found out till now:
the "allWidget()" function print out all widgets collected by the QApp. and this works finde
the code runs till the end (I got a instance pointer at the beginning and in the end; there're the same)
I tried several PyQt examples to test for openGL or non openGL Outputs and they all worked fine
there's no out-of-memory or CPU overload
I tried to cut the code per widget to find the issue, but whatever line of code I commented out no window pops-up anymore
I found this great article: https://doc.qt.io/archives/qq/qq27-responsive-guis.html#conclusion Could it be something like that?
Like I said I'm not a programmer and I didn't write the code myself (the author don't answer right now). Its overwhelming but I have to find a solution. Any ideas what I could try next? Anything would be helpful.