Commit 7629bca3 authored by Luke Campagnola's avatar Luke Campagnola
Browse files

Updates merged in from ACQ4:

  - converted most old-style signals into new-style for PySide compatibility (beware: API changes)
  - removed ObjectWorkaround, now just using QGraphicsWidget
  - performance enhancements, particularly in ROI.getArrayRegion
  - numerous bugfixes
parent 397a1c8a
# -*- coding: utf-8 -*-
from PyQt4 import QtGui, QtCore
import weakref
class TickSlider(QtGui.QGraphicsView):
def __init__(self, parent=None, orientation='bottom', allowAdd=True, **kargs):
......@@ -161,6 +161,9 @@ class TickSlider(QtGui.QGraphicsView):
class GradientWidget(TickSlider):
sigGradientChanged = QtCore.Signal(object)
def __init__(self, *args, **kargs):
TickSlider.__init__(self, *args, **kargs)
self.currentTick = None
......@@ -171,8 +174,10 @@ class GradientWidget(TickSlider):
self.colorDialog = QtGui.QColorDialog()
self.colorDialog.setOption(QtGui.QColorDialog.ShowAlphaChannel, True)
self.colorDialog.setOption(QtGui.QColorDialog.DontUseNativeDialog, True)
QtCore.QObject.connect(self.colorDialog, QtCore.SIGNAL('currentColorChanged(const QColor&)'), self.currentColorChanged)
QtCore.QObject.connect(self.colorDialog, QtCore.SIGNAL('rejected()'), self.currentColorRejected)
#QtCore.QObject.connect(self.colorDialog, QtCore.SIGNAL('currentColorChanged(const QColor&)'), self.currentColorChanged)
self.colorDialog.currentColorChanged.connect(self.currentColorChanged)
#QtCore.QObject.connect(self.colorDialog, QtCore.SIGNAL('rejected()'), self.currentColorRejected)
self.colorDialog.rejected.connect(self.currentColorRejected)
#self.gradient = QtGui.QLinearGradient(QtCore.QPointF(0,0), QtCore.QPointF(100,0))
self.scene.addItem(self.gradRect)
......@@ -199,7 +204,8 @@ class GradientWidget(TickSlider):
def updateGradient(self):
self.gradient = self.getGradient()
self.gradRect.setBrush(QtGui.QBrush(self.gradient))
self.emit(QtCore.SIGNAL('gradientChanged'), self)
#self.emit(QtCore.SIGNAL('gradientChanged'), self)
self.sigGradientChanged.emit(self)
def setLength(self, newLen):
TickSlider.setLength(self, newLen)
......@@ -356,7 +362,7 @@ class Tick(QtGui.QGraphicsPolygonItem):
def __init__(self, view, pos, color, movable=True, scale=10):
#QObjectWorkaround.__init__(self)
self.movable = movable
self.view = view
self.view = weakref.ref(view)
self.scale = scale
self.color = color
#self.endTick = endTick
......@@ -385,7 +391,7 @@ class Tick(QtGui.QGraphicsPolygonItem):
newPos.setY(self.pos().y())
#newPos.setX(min(max(newPos.x(), 0), 100))
self.setPos(newPos)
self.view.tickMoved(self, newPos)
self.view().tickMoved(self, newPos)
self.movedSincePress = True
#self.emit(QtCore.SIGNAL('tickChanged'), self)
ev.accept()
......@@ -405,7 +411,7 @@ class Tick(QtGui.QGraphicsPolygonItem):
def mouseReleaseEvent(self, ev):
#print self, "release", ev.scenePos()
if not self.movedSincePress:
self.view.tickClicked(self, ev)
self.view().tickClicked(self, ev)
#if ev.button() == QtCore.Qt.LeftButton and ev.scenePos() == self.pressPos:
#color = QtGui.QColorDialog.getColor(self.color, None, "Select Color", QtGui.QColorDialog.ShowAlphaChannel)
......
......@@ -11,9 +11,15 @@ from PyQt4 import QtCore, QtGui, QtOpenGL, QtSvg
from Point import *
#from vector import *
import sys
#import debug
class GraphicsView(QtGui.QGraphicsView):
sigRangeChanged = QtCore.Signal(object, object)
sigMouseReleased = QtCore.Signal(object)
sigSceneMouseMoved = QtCore.Signal(object)
#sigRegionChanged = QtCore.Signal(object)
def __init__(self, parent=None, useOpenGL=True):
"""Re-implementation of QGraphicsView that removes scrollbars and allows unambiguous control of the
viewed coordinate range. Also automatically creates a QGraphicsScene and a central QGraphicsWidget
......@@ -25,6 +31,7 @@ class GraphicsView(QtGui.QGraphicsView):
The view can be panned using the middle mouse button and scaled using the right mouse button if
enabled via enableMouse()."""
self.closed = False
QtGui.QGraphicsView.__init__(self, parent)
if 'linux' in sys.platform: ## linux has bugs in opengl implementation
......@@ -42,7 +49,7 @@ class GraphicsView(QtGui.QGraphicsView):
brush.setStyle(QtCore.Qt.SolidPattern)
palette.setBrush(QtGui.QPalette.Disabled,QtGui.QPalette.Base,brush)
self.setPalette(palette)
self.setProperty("cursor",QtCore.QVariant(QtCore.Qt.ArrowCursor))
#self.setProperty("cursor",QtCore.QVariant(QtCore.Qt.ArrowCursor))
self.setFocusPolicy(QtCore.Qt.StrongFocus)
self.setFrameShape(QtGui.QFrame.NoFrame)
self.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
......@@ -78,6 +85,14 @@ class GraphicsView(QtGui.QGraphicsView):
self.scaleCenter = False ## should scaling center around view center (True) or mouse click (False)
self.clickAccepted = False
#def paintEvent(self, *args):
#prof = debug.Profiler('GraphicsView.paintEvent '+str(id(self)), disabled=True)
#QtGui.QGraphicsView.paintEvent(self, *args)
#prof.finish()
def close(self):
self.closed = True
def useOpenGL(self, b=True):
if b:
v = QtOpenGL.QGLWidget()
......@@ -112,6 +127,8 @@ class GraphicsView(QtGui.QGraphicsView):
self.lastButtonReleased = None
def resizeEvent(self, ev):
if self.closed:
return
if self.autoPixelRange:
self.range = QtCore.QRectF(0, 0, self.size().width(), self.size().height())
self.setRange(self.range, padding=0, disableAutoPixel=False)
......@@ -148,7 +165,8 @@ class GraphicsView(QtGui.QGraphicsView):
#print " translate:", st
self.setMatrix(m)
self.currentScale = scale
self.emit(QtCore.SIGNAL('viewChanged'), self.range)
#self.emit(QtCore.SIGNAL('viewChanged'), self.range)
self.sigRangeChanged.emit(self, self.range)
if propagate:
for v in self.lockedViewports:
......@@ -200,6 +218,16 @@ class GraphicsView(QtGui.QGraphicsView):
#print "New Range:", self.range
self.centralWidget.setGeometry(self.range)
self.updateMatrix(propagate)
def scaleToImage(self, image):
"""Scales such that pixels in image are the same size as screen pixels. This may result in a significant performance increase."""
pxSize = image.pixelSize()
tl = image.sceneBoundingRect().topLeft()
w = self.size().width() * pxSize[0]
h = self.size().height() * pxSize[1]
range = QtCore.QRectF(tl.x(), tl.y(), w, h)
self.setRange(range, padding=0)
def lockXRange(self, v1):
......@@ -299,7 +327,8 @@ class GraphicsView(QtGui.QGraphicsView):
if not self.mouseEnabled:
return
#self.mouseTrail.append(Point(self.mapToScene(ev.pos())))
self.emit(QtCore.SIGNAL("mouseReleased"), ev)
#self.emit(QtCore.SIGNAL("mouseReleased"), ev)
self.sigMouseReleased.emit(ev)
self.lastButtonReleased = ev.button()
return ## Everything below disabled for now..
......@@ -320,7 +349,8 @@ class GraphicsView(QtGui.QGraphicsView):
QtGui.QGraphicsView.mouseMoveEvent(self, ev)
if not self.mouseEnabled:
return
self.emit(QtCore.SIGNAL("sceneMouseMoved(PyQt_PyObject)"), self.mapToScene(ev.pos()))
#self.emit(QtCore.SIGNAL("sceneMouseMoved(PyQt_PyObject)"), self.mapToScene(ev.pos()))
self.sigSceneMouseMoved.emit(self.mapToScene(ev.pos()))
#print "moved. Grabber:", self.scene().mouseGrabberItem()
......@@ -333,13 +363,15 @@ class GraphicsView(QtGui.QGraphicsView):
#if self.yInverted:
#scale[0] = 1. / scale[0]
self.scale(scale[0], scale[1], center=self.mapToScene(self.mousePressPos))
self.emit(QtCore.SIGNAL('regionChanged(QRectF)'), self.range)
#self.emit(QtCore.SIGNAL('regionChanged(QRectF)'), self.range)
self.sigRangeChanged.emit(self, self.range)
elif ev.buttons() in [QtCore.Qt.MidButton, QtCore.Qt.LeftButton]: ## Allow panning by left or mid button.
tr = -delta / self.currentScale
self.translate(tr[0], tr[1])
self.emit(QtCore.SIGNAL('regionChanged(QRectF)'), self.range)
#self.emit(QtCore.SIGNAL('regionChanged(QRectF)'), self.range)
self.sigRangeChanged.emit(self, self.range)
#return ## Everything below disabled for now..
......
......@@ -31,6 +31,9 @@ class PlotROI(ROI):
class ImageView(QtGui.QWidget):
sigTimeChanged = QtCore.Signal(object, object)
def __init__(self, parent=None, name="ImageView", *args):
QtGui.QWidget.__init__(self, parent, *args)
self.levelMax = 4096
......@@ -106,25 +109,38 @@ class ImageView(QtGui.QWidget):
setattr(self, fn, getattr(self.ui.graphicsView, fn))
#QtCore.QObject.connect(self.ui.timeSlider, QtCore.SIGNAL('valueChanged(int)'), self.timeChanged)
self.timeLine.connect(self.timeLine, QtCore.SIGNAL('positionChanged'), self.timeLineChanged)
#self.timeLine.connect(self.timeLine, QtCore.SIGNAL('positionChanged'), self.timeLineChanged)
self.timeLine.sigPositionChanged.connect(self.timeLineChanged)
#QtCore.QObject.connect(self.ui.whiteSlider, QtCore.SIGNAL('valueChanged(int)'), self.updateImage)
#QtCore.QObject.connect(self.ui.blackSlider, QtCore.SIGNAL('valueChanged(int)'), self.updateImage)
QtCore.QObject.connect(self.ui.gradientWidget, QtCore.SIGNAL('gradientChanged'), self.updateImage)
QtCore.QObject.connect(self.ui.roiBtn, QtCore.SIGNAL('clicked()'), self.roiClicked)
self.roi.connect(self.roi, QtCore.SIGNAL('regionChanged'), self.roiChanged)
QtCore.QObject.connect(self.ui.normBtn, QtCore.SIGNAL('toggled(bool)'), self.normToggled)
QtCore.QObject.connect(self.ui.normDivideRadio, QtCore.SIGNAL('clicked()'), self.updateNorm)
QtCore.QObject.connect(self.ui.normSubtractRadio, QtCore.SIGNAL('clicked()'), self.updateNorm)
QtCore.QObject.connect(self.ui.normOffRadio, QtCore.SIGNAL('clicked()'), self.updateNorm)
QtCore.QObject.connect(self.ui.normROICheck, QtCore.SIGNAL('clicked()'), self.updateNorm)
QtCore.QObject.connect(self.ui.normFrameCheck, QtCore.SIGNAL('clicked()'), self.updateNorm)
QtCore.QObject.connect(self.ui.normTimeRangeCheck, QtCore.SIGNAL('clicked()'), self.updateNorm)
QtCore.QObject.connect(self.playTimer, QtCore.SIGNAL('timeout()'), self.timeout)
#QtCore.QObject.connect(self.ui.gradientWidget, QtCore.SIGNAL('gradientChanged'), self.updateImage)
self.ui.gradientWidget.sigGradientChanged.connect(self.updateImage)
#QtCore.QObject.connect(self.ui.roiBtn, QtCore.SIGNAL('clicked()'), self.roiClicked)
self.ui.roiBtn.clicked.connect(self.roiClicked)
#self.roi.connect(self.roi, QtCore.SIGNAL('regionChanged'), self.roiChanged)
self.roi.sigRegionChanged.connect(self.roiChanged)
#QtCore.QObject.connect(self.ui.normBtn, QtCore.SIGNAL('toggled(bool)'), self.normToggled)
self.ui.normBtn.toggled.connect(self.normToggled)
#QtCore.QObject.connect(self.ui.normDivideRadio, QtCore.SIGNAL('clicked()'), self.updateNorm)
self.ui.normDivideRadio.clicked.connect(self.updateNorm)
#QtCore.QObject.connect(self.ui.normSubtractRadio, QtCore.SIGNAL('clicked()'), self.updateNorm)
self.ui.normSubtractRadio.clicked.connect(self.updateNorm)
#QtCore.QObject.connect(self.ui.normOffRadio, QtCore.SIGNAL('clicked()'), self.updateNorm)
self.ui.normOffRadio.clicked.connect(self.updateNorm)
#QtCore.QObject.connect(self.ui.normROICheck, QtCore.SIGNAL('clicked()'), self.updateNorm)
self.ui.normROICheck.clicked.connect(self.updateNorm)
#QtCore.QObject.connect(self.ui.normFrameCheck, QtCore.SIGNAL('clicked()'), self.updateNorm)
self.ui.normFrameCheck.clicked.connect(self.updateNorm)
#QtCore.QObject.connect(self.ui.normTimeRangeCheck, QtCore.SIGNAL('clicked()'), self.updateNorm)
self.ui.normTimeRangeCheck.clicked.connect(self.updateNorm)
#QtCore.QObject.connect(self.playTimer, QtCore.SIGNAL('timeout()'), self.timeout)
self.playTimer.timeout.connect(self.timeout)
##QtCore.QObject.connect(self.ui.normStartSlider, QtCore.SIGNAL('valueChanged(int)'), self.updateNorm)
#QtCore.QObject.connect(self.ui.normStopSlider, QtCore.SIGNAL('valueChanged(int)'), self.updateNorm)
self.normProxy = proxyConnect(self.normRgn, QtCore.SIGNAL('regionChanged'), self.updateNorm)
self.normRoi.connect(self.normRoi, QtCore.SIGNAL('regionChangeFinished'), self.updateNorm)
self.normProxy = proxyConnect(None, self.normRgn.sigRegionChanged, self.updateNorm)
#self.normRoi.connect(self.normRoi, QtCore.SIGNAL('regionChangeFinished'), self.updateNorm)
self.normRoi.sigRegionChangeFinished.connect(self.updateNorm)
self.ui.roiPlot.registerPlot(self.name + '_ROI')
......@@ -135,11 +151,16 @@ class ImageView(QtGui.QWidget):
#self.quit()
#QtGui.QWidget.__dtor__(self)
def quit(self):
def close(self):
self.ui.graphicsView.close()
self.ui.gradientWidget.sigGradientChanged.disconnect(self.updateImage)
self.scene.clear()
del self.image
del self.imageDisp
#self.image = None
#self.imageDisp = None
self.ui.roiPlot.close()
self.setParent(None)
def keyPressEvent(self, ev):
if ev.key() == QtCore.Qt.Key_Space:
......@@ -319,7 +340,6 @@ class ImageView(QtGui.QWidget):
axes: {'t':0, 'x':1, 'y':2, 'c':3}; Dictionary indicating the interpretation for each axis.
This is only needed to override the default guess.
"""
if not isinstance(img, np.ndarray):
raise Exception("Image must be specified as ndarray.")
self.image = img
......@@ -348,7 +368,7 @@ class ImageView(QtGui.QWidget):
elif img.ndim == 4:
self.axes = {'t': 0, 'x': 1, 'y': 2, 'c': 3}
else:
raise Exception("Can not interpret image with dimensions %s" % (str(img)))
raise Exception("Can not interpret image with dimensions %s" % (str(img.shape)))
elif isinstance(axes, dict):
self.axes = axes.copy()
elif isinstance(axes, list) or isinstance(axes, tuple):
......@@ -441,7 +461,7 @@ class ImageView(QtGui.QWidget):
#else:
#norm = zeros(image.shape)
if div:
norm = norm.astype(float32)
norm = norm.astype(np.float32)
if self.ui.normTimeRangeCheck.isChecked() and image.ndim == 3:
(sind, start) = self.timeIndex(self.normRgn.lines[0])
......@@ -464,7 +484,7 @@ class ImageView(QtGui.QWidget):
if self.ui.normROICheck.isChecked() and image.ndim == 3:
n = self.normRoi.getArrayRegion(norm, self.imageItem, (1, 2)).mean(axis=1).mean(axis=1)
n = n[:,newaxis,newaxis]
n = n[:,np.newaxis,np.newaxis]
#print start, end, sind, eind
if div:
norm /= n
......@@ -483,7 +503,8 @@ class ImageView(QtGui.QWidget):
self.currentIndex = ind
self.updateImage()
#self.timeLine.setPos(time)
self.emit(QtCore.SIGNAL('timeChanged'), ind, time)
#self.emit(QtCore.SIGNAL('timeChanged'), ind, time)
self.sigTimeChanged.emit(ind, time)
def updateImage(self):
## Redraw image on screen
......
......@@ -63,4 +63,7 @@ class MultiPlotItem(QtGui.QGraphicsWidget):
else:
raise Exception("Data type %s not (yet?) supported for MultiPlot." % type(data))
def close(self):
for p in self.plots:
p[0].close()
\ No newline at end of file
......@@ -37,3 +37,7 @@ class MultiPlotWidget(GraphicsView):
def restoreState(self, state):
pass
#return self.plotItem.restoreState(state)
def close(self):
self.mPlotItem.close()
self.setParent(None)
\ No newline at end of file
# -*- coding: utf-8 -*-
from PyQt4 import QtGui, QtCore
"""For circumventing PyQt's lack of multiple inheritance (just until PySide becomes stable)"""
class Obj(QtCore.QObject):
def event(self, ev):
self.emit(QtCore.SIGNAL('event'), ev)
return QtCore.QObject.event(self, ev)
class QObjectWorkaround:
def __init__(self):
self._qObj_ = Obj()
self.connect(QtCore.SIGNAL('event'), self.event)
def connect(self, *args):
if args[0] is self:
return QtCore.QObject.connect(self._qObj_, *args[1:])
else:
return QtCore.QObject.connect(self._qObj_, *args)
def disconnect(self, *args):
return QtCore.QObject.disconnect(self._qObj_, *args)
def emit(self, *args):
return QtCore.QObject.emit(self._qObj_, *args)
def blockSignals(self, b):
return self._qObj_.blockSignals(b)
def setProperty(self, prop, val):
return self._qObj_.setProperty(prop, val)
def property(self, prop):
return self._qObj_.property(prop)
def event(self, ev):
pass
#class QGraphicsObject(QtGui.QGraphicsItem, QObjectWorkaround):
#def __init__(self, *args):
#QtGui.QGraphicsItem.__init__(self, *args)
#QObjectWorkaround.__init__(self)
class QGraphicsObject(QtGui.QGraphicsWidget):
def shape(self):
return QtGui.QGraphicsItem.shape(self)
#QGraphicsObject = QtGui.QGraphicsObject
\ No newline at end of file
This diff is collapsed.
......@@ -10,6 +10,9 @@ from PlotItem import *
import exceptions
class PlotWidget(GraphicsView):
sigRangeChanged = QtCore.Signal(object, object)
"""Widget implementing a graphicsView with a single PlotItem inside."""
def __init__(self, parent=None, **kargs):
GraphicsView.__init__(self, parent)
......@@ -20,17 +23,23 @@ class PlotWidget(GraphicsView):
## Explicitly wrap methods from plotItem
for m in ['addItem', 'removeItem', 'autoRange', 'clear', 'setXRange', 'setYRange']:
setattr(self, m, getattr(self.plotItem, m))
QtCore.QObject.connect(self.plotItem, QtCore.SIGNAL('viewChanged'), self.viewChanged)
#QtCore.QObject.connect(self.plotItem, QtCore.SIGNAL('viewChanged'), self.viewChanged)
self.plotItem.sigRangeChanged.connect(self.viewRangeChanged)
#def __dtor__(self):
##print "Called plotWidget sip destructor"
#self.quit()
def quit(self):
self.plotItem.clear()
self.scene().clear()
#def quit(self):
def close(self):
self.plotItem.close()
self.plotItem = None
#self.scene().clear()
#self.mPlotItem.close()
self.setParent(None)
def __getattr__(self, attr): ## implicitly wrap methods from plotItem
if hasattr(self.plotItem, attr):
m = getattr(self.plotItem, attr)
......@@ -38,8 +47,9 @@ class PlotWidget(GraphicsView):
return m
raise exceptions.NameError(attr)
def viewChanged(self, *args):
self.emit(QtCore.SIGNAL('viewChanged'), *args)
def viewRangeChanged(self, view, range):
#self.emit(QtCore.SIGNAL('viewChanged'), *args)
self.sigRangeChanged.emit(self, range)
def widgetGroupInterface(self):
return (None, PlotWidget.saveState, PlotWidget.restoreState)
......
......@@ -34,6 +34,9 @@ class Point(QtCore.QPointF):
return
QtCore.QPointF.__init__(self, *args)
def __len__(self):
return 2
def __reduce__(self):
return (Point, (self.x(), self.y()))
......
......@@ -2,14 +2,6 @@
from PyQt4 import QtCore
from ptime import time
def proxyConnect(source, signal, slot, delay=0.3):
"""Connect a signal to a slot with delay. Returns the SignalProxy
object that was created. Be sure to store this object so it is not
garbage-collected immediately."""
sp = SignalProxy(source, signal, delay)
sp.connect(sp, signal, slot)
return sp
class SignalProxy(QtCore.QObject):
"""Object which collects rapid-fire signals and condenses them
into a single signal. Used, for example, to prevent a SpinBox
......@@ -17,53 +9,70 @@ class SignalProxy(QtCore.QObject):
over it."""
def __init__(self, source, signal, delay=0.3):
"""Initialization arguments:
source - Any QObject that will emit signal, or None if signal is new style
signal - Output of QtCore.SIGNAL(...), or obj.signal for new style
delay - Time (in seconds) to wait for signals to stop before emitting (default 0.3s)"""
QtCore.QObject.__init__(self)
source.connect(source, signal, self.signal)
if source is None:
signal.connect(self.signalReceived)
self.signal = QtCore.SIGNAL('signal')
else:
source.connect(source, signal, self.signalReceived)
self.signal = signal
self.delay = delay
self.waitUntil = 0
self.args = None
self.timers = 0
self.signal = signal
self.timer = QtCore.QTimer()
self.timer.timeout.connect(self.flush)
self.block = False
def setDelay(self, delay):
self.delay = delay
def flush(self):
"""If there is a signal queued up, send it now."""
if self.args is None or self.block:
return False
if self.block:
return
self.emit(self.signal, *self.args)
self.args = None
return True
def signal(self, *args):
"""Received signal, queue to be forwarded later."""
def signalReceived(self, *args):
"""Received signal. Cancel previous timer and store args to be forwarded later."""
if self.block:
return
self.waitUntil = time() + self.delay
self.args = args
self.timers += 1
QtCore.QTimer.singleShot((self.delay*1000)+1, self.tryEmit)
self.timer.stop()
self.timer.start((self.delay*1000)+1)
def tryEmit(self):
"""Emit signal if it has been long enougn since receiving the last signal."""
def flush(self):
"""If there is a signal queued up, send it now."""
if self.args is None or self.block:
return False
self.timers -= 1
t = time()
if t >= self.waitUntil:
return self.flush()
else:
if self.timers == 0:
self.timers += 1
QtCore.QTimer.singleShot((self.waitUntil - t) * 1000, self.tryEmit)
self.emit(self.signal, *self.args)
self.args = None
return True
def disconnect(self):
self.block = True
\ No newline at end of file
def proxyConnect(source, signal, slot, delay=0.3):
"""Connect a signal to a slot with delay. Returns the SignalProxy
object that was created. Be sure to store this object so it is not
garbage-collected immediately."""
sp = SignalProxy(source, signal, delay)
if source is None:
sp.connect(sp, QtCore.SIGNAL('signal'), slot)
else:
sp.connect(sp, signal, slot)
return sp
if __name__ == '__main__':
from PyQt4 import QtGui
app = QtGui.QApplication([])
win = QtGui.QMainWindow()
spin = QtGui.QSpinBox()
win.setCentralWidget(spin)
win.show()
def fn(*args):
print "Got signal:", args
proxy = proxyConnect(spin, QtCore.SIGNAL('valueChanged(int)'), fn)
\ No newline at end of file
......@@ -3,17 +3,16 @@
import sys, os
sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..'))
from pyqtgraph.GraphicsView import *
from pyqtgraph.graphicsItems import *
from numpy import random
from PyQt4 import QtCore, QtGui
from scipy.ndimage import *
import numpy as np
import pyqtgraph as pg
app = QtGui.QApplication([])
## Create window with GraphicsView widget
win = QtGui.QMainWindow()
view = GraphicsView()
view = pg.GraphicsView()
#view.useOpenGL(True)
win.setCentralWidget(view)
win.show()
......@@ -25,26 +24,29 @@ view.enableMouse()
view.setAspectLocked(True)
## Create image item
img = ImageItem()
img = pg.ImageItem()
view.scene().addItem(img)
## Set initial view bounds
view.setRange(QtCore.QRectF(0, 0, 200, 200))
## Create random image
data = np.random.normal(size=(50, 200, 200))
i = 0
def updateData():
global img
## Create random image
data = random.random((200, 200))
global img, data, i
## Display the data
img.updateImage(data)
img.updateImage(data[i])
i = (i+1) % data.shape[0]
# update image data every 20ms (or so)
t = QtCore.QTimer()
QtCore.QObject.connect(t, QtCore.SIGNAL('timeout()'), updateData)
t.timeout.connect(updateData)
t.start(20)
app.exec_()
## Start Qt event loop unless running in interactive mode.
if sys.flags.interactive != 1:
app.exec_()