minor bugfixes / features:
- optional context menu for ImageItem - inverted y-axis in Canvas (+y now points upward) - extra __init__ arguments for Dock - Transform can be constructed from Matrix4x4 - many others
This commit is contained in:
parent
2c80098cf6
commit
f258c3d87c
@ -32,6 +32,7 @@ class MouseDragEvent:
|
|||||||
self._buttons = moveEvent.buttons()
|
self._buttons = moveEvent.buttons()
|
||||||
self._button = pressEvent.button()
|
self._button = pressEvent.button()
|
||||||
self._modifiers = moveEvent.modifiers()
|
self._modifiers = moveEvent.modifiers()
|
||||||
|
self.acceptedItem = None
|
||||||
|
|
||||||
def accept(self):
|
def accept(self):
|
||||||
"""An item should call this method if it can handle the event. This will prevent the event being delivered to any other items."""
|
"""An item should call this method if it can handle the event. This will prevent the event being delivered to any other items."""
|
||||||
@ -160,7 +161,7 @@ class MouseClickEvent:
|
|||||||
self._buttons = pressEvent.buttons()
|
self._buttons = pressEvent.buttons()
|
||||||
self._modifiers = pressEvent.modifiers()
|
self._modifiers = pressEvent.modifiers()
|
||||||
self._time = ptime.time()
|
self._time = ptime.time()
|
||||||
|
self.acceptedItem = None
|
||||||
|
|
||||||
def accept(self):
|
def accept(self):
|
||||||
"""An item should call this method if it can handle the event. This will prevent the event being delivered to any other items."""
|
"""An item should call this method if it can handle the event. This will prevent the event being delivered to any other items."""
|
||||||
|
21
Transform.py
21
Transform.py
@ -2,6 +2,7 @@
|
|||||||
from .Qt import QtCore, QtGui
|
from .Qt import QtCore, QtGui
|
||||||
from .Point import Point
|
from .Point import Point
|
||||||
import numpy as np
|
import numpy as np
|
||||||
|
import pyqtgraph as pg
|
||||||
|
|
||||||
class Transform(QtGui.QTransform):
|
class Transform(QtGui.QTransform):
|
||||||
"""Transform that can always be represented as a combination of 3 matrices: scale * rotate * translate
|
"""Transform that can always be represented as a combination of 3 matrices: scale * rotate * translate
|
||||||
@ -11,7 +12,9 @@ class Transform(QtGui.QTransform):
|
|||||||
QtGui.QTransform.__init__(self)
|
QtGui.QTransform.__init__(self)
|
||||||
self.reset()
|
self.reset()
|
||||||
|
|
||||||
if isinstance(init, dict):
|
if init is None:
|
||||||
|
return
|
||||||
|
elif isinstance(init, dict):
|
||||||
self.restoreState(init)
|
self.restoreState(init)
|
||||||
elif isinstance(init, Transform):
|
elif isinstance(init, Transform):
|
||||||
self._state = {
|
self._state = {
|
||||||
@ -22,6 +25,10 @@ class Transform(QtGui.QTransform):
|
|||||||
self.update()
|
self.update()
|
||||||
elif isinstance(init, QtGui.QTransform):
|
elif isinstance(init, QtGui.QTransform):
|
||||||
self.setFromQTransform(init)
|
self.setFromQTransform(init)
|
||||||
|
elif isinstance(init, QtGui.QMatrix4x4):
|
||||||
|
self.setFromMatrix4x4(init)
|
||||||
|
else:
|
||||||
|
raise Exception("Cannot create Transform from input type: %s" % str(type(init)))
|
||||||
|
|
||||||
|
|
||||||
def getScale(self):
|
def getScale(self):
|
||||||
@ -65,6 +72,18 @@ class Transform(QtGui.QTransform):
|
|||||||
}
|
}
|
||||||
self.update()
|
self.update()
|
||||||
|
|
||||||
|
def setFromMatrix4x4(self, m):
|
||||||
|
m = pg.Transform3D(m)
|
||||||
|
angle, axis = m.getRotation()
|
||||||
|
if angle != 0 and (axis[0] != 0 or axis[1] != 0 or axis[2] != 1):
|
||||||
|
raise Exception("Can only convert 4x4 matrix to 3x3 if rotation is around Z-axis.")
|
||||||
|
self._state = {
|
||||||
|
'pos': Point(m.getTranslation()),
|
||||||
|
'scale': Point(m.getScale()),
|
||||||
|
'angle': angle
|
||||||
|
}
|
||||||
|
self.update()
|
||||||
|
|
||||||
def translate(self, *args):
|
def translate(self, *args):
|
||||||
"""Acceptable arguments are:
|
"""Acceptable arguments are:
|
||||||
x, y
|
x, y
|
||||||
|
@ -110,7 +110,9 @@ importAll('widgets', excludes=['MatplotlibWidget'])
|
|||||||
from .imageview import *
|
from .imageview import *
|
||||||
from .WidgetGroup import *
|
from .WidgetGroup import *
|
||||||
from .Point import Point
|
from .Point import Point
|
||||||
|
from .Vector import Vector
|
||||||
from .Transform import Transform
|
from .Transform import Transform
|
||||||
|
from .Transform3D import Transform3D
|
||||||
from .functions import *
|
from .functions import *
|
||||||
from .graphicsWindows import *
|
from .graphicsWindows import *
|
||||||
from .SignalProxy import *
|
from .SignalProxy import *
|
||||||
|
@ -51,7 +51,7 @@ class Canvas(QtGui.QWidget):
|
|||||||
|
|
||||||
#self.view.enableMouse()
|
#self.view.enableMouse()
|
||||||
self.view.setAspectLocked(True)
|
self.view.setAspectLocked(True)
|
||||||
self.view.invertY()
|
#self.view.invertY()
|
||||||
|
|
||||||
grid = GridItem()
|
grid = GridItem()
|
||||||
self.grid = CanvasItem(grid, name='Grid', movable=False)
|
self.grid = CanvasItem(grid, name='Grid', movable=False)
|
||||||
|
@ -7,14 +7,14 @@ class Dock(QtGui.QWidget, DockDrop):
|
|||||||
|
|
||||||
sigStretchChanged = QtCore.Signal()
|
sigStretchChanged = QtCore.Signal()
|
||||||
|
|
||||||
def __init__(self, name, area=None, size=(10, 10)):
|
def __init__(self, name, area=None, size=(10, 10), widget=None, hideTitle=False, autoOrientation=True):
|
||||||
QtGui.QWidget.__init__(self)
|
QtGui.QWidget.__init__(self)
|
||||||
DockDrop.__init__(self)
|
DockDrop.__init__(self)
|
||||||
self.area = area
|
self.area = area
|
||||||
self.label = DockLabel(name, self)
|
self.label = DockLabel(name, self)
|
||||||
self.labelHidden = False
|
self.labelHidden = False
|
||||||
self.moveLabel = True ## If false, the dock is no longer allowed to move the label.
|
self.moveLabel = True ## If false, the dock is no longer allowed to move the label.
|
||||||
self.autoOrient = True
|
self.autoOrient = autoOrientation
|
||||||
self.orientation = 'horizontal'
|
self.orientation = 'horizontal'
|
||||||
#self.label.setAlignment(QtCore.Qt.AlignHCenter)
|
#self.label.setAlignment(QtCore.Qt.AlignHCenter)
|
||||||
self.topLayout = QtGui.QGridLayout()
|
self.topLayout = QtGui.QGridLayout()
|
||||||
@ -64,6 +64,12 @@ class Dock(QtGui.QWidget, DockDrop):
|
|||||||
|
|
||||||
self.setStretch(*size)
|
self.setStretch(*size)
|
||||||
|
|
||||||
|
if widget is not None:
|
||||||
|
self.addWidget(widget)
|
||||||
|
|
||||||
|
if hideTitle:
|
||||||
|
self.hideTitleBar()
|
||||||
|
|
||||||
def implements(self, name=None):
|
def implements(self, name=None):
|
||||||
if name is None:
|
if name is None:
|
||||||
return ['dock']
|
return ['dock']
|
||||||
@ -108,7 +114,7 @@ class Dock(QtGui.QWidget, DockDrop):
|
|||||||
|
|
||||||
def setOrientation(self, o='auto', force=False):
|
def setOrientation(self, o='auto', force=False):
|
||||||
#print self.name(), "setOrientation", o, force
|
#print self.name(), "setOrientation", o, force
|
||||||
if o == 'auto':
|
if o == 'auto' and self.autoOrient:
|
||||||
if self.container().type() == 'tab':
|
if self.container().type() == 'tab':
|
||||||
o = 'horizontal'
|
o = 'horizontal'
|
||||||
elif self.width() > self.height()*1.5:
|
elif self.width() > self.height()*1.5:
|
||||||
|
@ -9,21 +9,19 @@ import pyqtgraph as pg
|
|||||||
app = QtGui.QApplication([])
|
app = QtGui.QApplication([])
|
||||||
|
|
||||||
## Create window with GraphicsView widget
|
## Create window with GraphicsView widget
|
||||||
win = QtGui.QMainWindow()
|
w = pg.GraphicsView()
|
||||||
win.resize(800,800)
|
w.show()
|
||||||
view = pg.GraphicsView()
|
w.resize(800,800)
|
||||||
#view.useOpenGL(True)
|
|
||||||
win.setCentralWidget(view)
|
|
||||||
win.show()
|
|
||||||
|
|
||||||
## Allow mouse scale/pan
|
view = pg.ViewBox()
|
||||||
view.enableMouse()
|
w.setCentralItem(view)
|
||||||
## ..But lock the aspect ratio
|
|
||||||
|
## lock the aspect ratio
|
||||||
view.setAspectLocked(True)
|
view.setAspectLocked(True)
|
||||||
|
|
||||||
## Create image item
|
## Create image item
|
||||||
img = pg.ImageItem(np.zeros((200,200)))
|
img = pg.ImageItem(np.zeros((200,200)))
|
||||||
view.scene().addItem(img)
|
view.addItem(img)
|
||||||
|
|
||||||
## Set initial view bounds
|
## Set initial view bounds
|
||||||
view.setRange(QtCore.QRectF(0, 0, 200, 200))
|
view.setRange(QtCore.QRectF(0, 0, 200, 200))
|
||||||
|
@ -30,9 +30,7 @@ class ImageItem(GraphicsObject):
|
|||||||
|
|
||||||
|
|
||||||
sigImageChanged = QtCore.Signal()
|
sigImageChanged = QtCore.Signal()
|
||||||
|
sigRemoveRequested = QtCore.Signal(object) # self; emitted when 'remove' is selected from context menu
|
||||||
## performance gains from this are marginal, and it's rather unreliable.
|
|
||||||
useWeave = False
|
|
||||||
|
|
||||||
def __init__(self, image=None, **kargs):
|
def __init__(self, image=None, **kargs):
|
||||||
"""
|
"""
|
||||||
@ -48,7 +46,6 @@ class ImageItem(GraphicsObject):
|
|||||||
#self.clipMask = None
|
#self.clipMask = None
|
||||||
|
|
||||||
self.paintMode = None
|
self.paintMode = None
|
||||||
#self.useWeave = True
|
|
||||||
|
|
||||||
self.levels = None ## [min, max] or [[redMin, redMax], ...]
|
self.levels = None ## [min, max] or [[redMin, redMax], ...]
|
||||||
self.lut = None
|
self.lut = None
|
||||||
@ -56,6 +53,7 @@ class ImageItem(GraphicsObject):
|
|||||||
#self.clipLevel = None
|
#self.clipLevel = None
|
||||||
self.drawKernel = None
|
self.drawKernel = None
|
||||||
self.border = None
|
self.border = None
|
||||||
|
self.removable = False
|
||||||
|
|
||||||
if image is not None:
|
if image is not None:
|
||||||
self.setImage(image, **kargs)
|
self.setImage(image, **kargs)
|
||||||
@ -160,6 +158,9 @@ class ImageItem(GraphicsObject):
|
|||||||
self.setCompositionMode(kargs['compositionMode'])
|
self.setCompositionMode(kargs['compositionMode'])
|
||||||
if 'border' in kargs:
|
if 'border' in kargs:
|
||||||
self.setBorder(kargs['border'])
|
self.setBorder(kargs['border'])
|
||||||
|
if 'removable' in kargs:
|
||||||
|
self.removable = kargs['removable']
|
||||||
|
self.menu = None
|
||||||
|
|
||||||
def setRect(self, rect):
|
def setRect(self, rect):
|
||||||
"""Scale and translate the image to fit within rect (must be a QRect or QRectF)."""
|
"""Scale and translate the image to fit within rect (must be a QRect or QRectF)."""
|
||||||
@ -264,7 +265,6 @@ class ImageItem(GraphicsObject):
|
|||||||
|
|
||||||
argb, alpha = fn.makeARGB(self.image, lut=lut, levels=self.levels)
|
argb, alpha = fn.makeARGB(self.image, lut=lut, levels=self.levels)
|
||||||
self.qimage = fn.makeQImage(argb, alpha)
|
self.qimage = fn.makeQImage(argb, alpha)
|
||||||
#self.pixmap = QtGui.QPixmap.fromImage(self.qimage)
|
|
||||||
prof.finish()
|
prof.finish()
|
||||||
|
|
||||||
|
|
||||||
@ -324,20 +324,71 @@ class ImageItem(GraphicsObject):
|
|||||||
return 1,1
|
return 1,1
|
||||||
return br.width()/self.width(), br.height()/self.height()
|
return br.width()/self.width(), br.height()/self.height()
|
||||||
|
|
||||||
def mousePressEvent(self, ev):
|
#def mousePressEvent(self, ev):
|
||||||
|
#if self.drawKernel is not None and ev.button() == QtCore.Qt.LeftButton:
|
||||||
|
#self.drawAt(ev.pos(), ev)
|
||||||
|
#ev.accept()
|
||||||
|
#else:
|
||||||
|
#ev.ignore()
|
||||||
|
|
||||||
|
#def mouseMoveEvent(self, ev):
|
||||||
|
##print "mouse move", ev.pos()
|
||||||
|
#if self.drawKernel is not None:
|
||||||
|
#self.drawAt(ev.pos(), ev)
|
||||||
|
|
||||||
|
#def mouseReleaseEvent(self, ev):
|
||||||
|
#pass
|
||||||
|
|
||||||
|
def mouseDragEvent(self, ev):
|
||||||
|
if ev.button() != QtCore.Qt.LeftButton:
|
||||||
|
ev.ignore()
|
||||||
|
return
|
||||||
|
|
||||||
|
ev.accept()
|
||||||
|
self.drawAt(ev.pos(), ev)
|
||||||
|
|
||||||
|
def mouseClickEvent(self, ev):
|
||||||
|
if ev.button() == QtCore.Qt.RightButton:
|
||||||
|
if self.raiseContextMenu(ev):
|
||||||
|
ev.accept()
|
||||||
if self.drawKernel is not None and ev.button() == QtCore.Qt.LeftButton:
|
if self.drawKernel is not None and ev.button() == QtCore.Qt.LeftButton:
|
||||||
self.drawAt(ev.pos(), ev)
|
self.drawAt(ev.pos(), ev)
|
||||||
ev.accept()
|
|
||||||
else:
|
|
||||||
ev.ignore()
|
|
||||||
|
|
||||||
def mouseMoveEvent(self, ev):
|
def raiseContextMenu(self, ev):
|
||||||
#print "mouse move", ev.pos()
|
## only raise menu if this terminal is removable
|
||||||
if self.drawKernel is not None:
|
menu = self.getMenu()
|
||||||
self.drawAt(ev.pos(), ev)
|
if menu is None:
|
||||||
|
return False
|
||||||
|
menu = self.scene().addParentContextMenus(self, menu, ev)
|
||||||
|
pos = ev.screenPos()
|
||||||
|
menu.popup(QtCore.QPoint(pos.x(), pos.y()))
|
||||||
|
return True
|
||||||
|
|
||||||
|
def getMenu(self):
|
||||||
|
if self.menu is None:
|
||||||
|
if not self.removable:
|
||||||
|
return None
|
||||||
|
self.menu = QtGui.QMenu()
|
||||||
|
self.menu.setTitle("Image")
|
||||||
|
remAct = QtGui.QAction("Remove image", self.menu)
|
||||||
|
remAct.triggered.connect(self.removeClicked)
|
||||||
|
self.menu.addAction(remAct)
|
||||||
|
self.menu.remAct = remAct
|
||||||
|
return self.menu
|
||||||
|
|
||||||
|
|
||||||
|
def hoverEvent(self, ev):
|
||||||
|
if not ev.isExit() and self.drawKernel is not None and ev.acceptDrags(QtCore.Qt.LeftButton):
|
||||||
|
ev.acceptClicks(QtCore.Qt.LeftButton) ## we don't use the click, but we also don't want anyone else to use it.
|
||||||
|
ev.acceptClicks(QtCore.Qt.RightButton)
|
||||||
|
#self.box.setBrush(fn.mkBrush('w'))
|
||||||
|
elif not ev.isExit() and self.removable:
|
||||||
|
ev.acceptClicks(QtCore.Qt.RightButton) ## accept context menu clicks
|
||||||
|
#else:
|
||||||
|
#self.box.setBrush(self.brush)
|
||||||
|
#self.update()
|
||||||
|
|
||||||
|
|
||||||
def mouseReleaseEvent(self, ev):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def tabletEvent(self, ev):
|
def tabletEvent(self, ev):
|
||||||
print(ev.device())
|
print(ev.device())
|
||||||
@ -364,20 +415,10 @@ class ImageItem(GraphicsObject):
|
|||||||
ty[i] += dy1+dy2
|
ty[i] += dy1+dy2
|
||||||
sy[i] += dy1+dy2
|
sy[i] += dy1+dy2
|
||||||
|
|
||||||
#print sx
|
|
||||||
#print sy
|
|
||||||
#print tx
|
|
||||||
#print ty
|
|
||||||
#print self.image.shape
|
|
||||||
#print self.image[tx[0]:tx[1], ty[0]:ty[1]].shape
|
|
||||||
#print dk[sx[0]:sx[1], sy[0]:sy[1]].shape
|
|
||||||
ts = (slice(tx[0],tx[1]), slice(ty[0],ty[1]))
|
ts = (slice(tx[0],tx[1]), slice(ty[0],ty[1]))
|
||||||
ss = (slice(sx[0],sx[1]), slice(sy[0],sy[1]))
|
ss = (slice(sx[0],sx[1]), slice(sy[0],sy[1]))
|
||||||
#src = dk[sx[0]:sx[1], sy[0]:sy[1]]
|
|
||||||
#mask = self.drawMask[sx[0]:sx[1], sy[0]:sy[1]]
|
|
||||||
mask = self.drawMask
|
mask = self.drawMask
|
||||||
src = dk
|
src = dk
|
||||||
#print self.image[ts].shape, src.shape
|
|
||||||
|
|
||||||
if isinstance(self.drawMode, collections.Callable):
|
if isinstance(self.drawMode, collections.Callable):
|
||||||
self.drawMode(dk, self.image, mask, ss, ts, ev)
|
self.drawMode(dk, self.image, mask, ss, ts, ev)
|
||||||
@ -401,197 +442,5 @@ class ImageItem(GraphicsObject):
|
|||||||
self.drawMode = mode
|
self.drawMode = mode
|
||||||
self.drawMask = mask
|
self.drawMask = mask
|
||||||
|
|
||||||
|
def removeClicked(self):
|
||||||
|
self.sigRemoveRequested.emit(self)
|
||||||
|
|
||||||
|
|
||||||
#def setImage(self, image=None, copy=True, autoRange=True, clipMask=None, white=None, black=None, axes=None):
|
|
||||||
#prof = debug.Profiler('ImageItem.updateImage 0x%x' %id(self), disabled=True)
|
|
||||||
##debug.printTrace()
|
|
||||||
#if axes is None:
|
|
||||||
#axh = {'x': 0, 'y': 1, 'c': 2}
|
|
||||||
#else:
|
|
||||||
#axh = axes
|
|
||||||
##print "Update image", black, white
|
|
||||||
#if white is not None:
|
|
||||||
#self.whiteLevel = white
|
|
||||||
#if black is not None:
|
|
||||||
#self.blackLevel = black
|
|
||||||
|
|
||||||
#gotNewData = False
|
|
||||||
#if image is None:
|
|
||||||
#if self.image is None:
|
|
||||||
#return
|
|
||||||
#else:
|
|
||||||
#gotNewData = True
|
|
||||||
#if self.image is None or image.shape != self.image.shape:
|
|
||||||
#self.prepareGeometryChange()
|
|
||||||
#if copy:
|
|
||||||
#self.image = image.view(np.ndarray).copy()
|
|
||||||
#else:
|
|
||||||
#self.image = image.view(np.ndarray)
|
|
||||||
##print " image max:", self.image.max(), "min:", self.image.min()
|
|
||||||
#prof.mark('1')
|
|
||||||
|
|
||||||
## Determine scale factors
|
|
||||||
#if autoRange or self.blackLevel is None:
|
|
||||||
#if self.image.dtype is np.ubyte:
|
|
||||||
#self.blackLevel = 0
|
|
||||||
#self.whiteLevel = 255
|
|
||||||
#else:
|
|
||||||
#self.blackLevel = self.image.min()
|
|
||||||
#self.whiteLevel = self.image.max()
|
|
||||||
##print "Image item using", self.blackLevel, self.whiteLevel
|
|
||||||
|
|
||||||
#if self.blackLevel != self.whiteLevel:
|
|
||||||
#scale = 255. / (self.whiteLevel - self.blackLevel)
|
|
||||||
#else:
|
|
||||||
#scale = 0.
|
|
||||||
|
|
||||||
#prof.mark('2')
|
|
||||||
|
|
||||||
### Recolor and convert to 8 bit per channel
|
|
||||||
## Try using weave, then fall back to python
|
|
||||||
#shape = self.image.shape
|
|
||||||
#black = float(self.blackLevel)
|
|
||||||
#white = float(self.whiteLevel)
|
|
||||||
|
|
||||||
#if black == 0 and white == 255 and self.image.dtype == np.ubyte:
|
|
||||||
#im = self.image
|
|
||||||
#elif self.image.dtype in [np.ubyte, np.uint16]:
|
|
||||||
## use lookup table instead
|
|
||||||
#npts = 2**(self.image.itemsize * 8)
|
|
||||||
#lut = self.getLookupTable(npts, black, white)
|
|
||||||
#im = lut[self.image]
|
|
||||||
#else:
|
|
||||||
#im = self.applyColorScaling(self.image, black, scale)
|
|
||||||
|
|
||||||
#prof.mark('3')
|
|
||||||
|
|
||||||
#try:
|
|
||||||
#im1 = np.empty((im.shape[axh['y']], im.shape[axh['x']], 4), dtype=np.ubyte)
|
|
||||||
#except:
|
|
||||||
#print im.shape, axh
|
|
||||||
#raise
|
|
||||||
#alpha = np.clip(int(255 * self.alpha), 0, 255)
|
|
||||||
#prof.mark('4')
|
|
||||||
## Fill image
|
|
||||||
#if im.ndim == 2:
|
|
||||||
#im2 = im.transpose(axh['y'], axh['x'])
|
|
||||||
#im1[..., 0] = im2
|
|
||||||
#im1[..., 1] = im2
|
|
||||||
#im1[..., 2] = im2
|
|
||||||
#im1[..., 3] = alpha
|
|
||||||
#elif im.ndim == 3: #color image
|
|
||||||
#im2 = im.transpose(axh['y'], axh['x'], axh['c'])
|
|
||||||
#if im2.shape[2] > 4:
|
|
||||||
#raise Exception("ImageItem got image with more than 4 color channels (shape is %s; axes are %s)" % (str(im.shape), str(axh)))
|
|
||||||
### [B G R A] Reorder colors
|
|
||||||
#order = [2,1,0,3] ## for some reason, the colors line up as BGR in the final image.
|
|
||||||
|
|
||||||
#for i in range(0, im.shape[axh['c']]):
|
|
||||||
#im1[..., order[i]] = im2[..., i]
|
|
||||||
|
|
||||||
### fill in unused channels with 0 or alpha
|
|
||||||
#for i in range(im.shape[axh['c']], 3):
|
|
||||||
#im1[..., i] = 0
|
|
||||||
#if im.shape[axh['c']] < 4:
|
|
||||||
#im1[..., 3] = alpha
|
|
||||||
|
|
||||||
#else:
|
|
||||||
#raise Exception("Image must be 2 or 3 dimensions")
|
|
||||||
##self.im1 = im1
|
|
||||||
## Display image
|
|
||||||
#prof.mark('5')
|
|
||||||
#if self.clipLevel is not None or clipMask is not None:
|
|
||||||
#if clipMask is not None:
|
|
||||||
#mask = clipMask.transpose()
|
|
||||||
#else:
|
|
||||||
#mask = (self.image < self.clipLevel).transpose()
|
|
||||||
#im1[..., 0][mask] *= 0.5
|
|
||||||
#im1[..., 1][mask] *= 0.5
|
|
||||||
#im1[..., 2][mask] = 255
|
|
||||||
#prof.mark('6')
|
|
||||||
##print "Final image:", im1.dtype, im1.min(), im1.max(), im1.shape
|
|
||||||
##self.ims = im1.tostring() ## Must be held in memory here because qImage won't do it for us :(
|
|
||||||
#prof.mark('7')
|
|
||||||
#try:
|
|
||||||
#buf = im1.data
|
|
||||||
#except AttributeError:
|
|
||||||
#im1 = np.ascontiguousarray(im1)
|
|
||||||
#buf = im1.data
|
|
||||||
|
|
||||||
#qimage = QtGui.QImage(buf, im1.shape[1], im1.shape[0], QtGui.QImage.Format_ARGB32)
|
|
||||||
#self.qimage = qimage
|
|
||||||
#self.qimage.data = im1
|
|
||||||
#self._pixmap = None
|
|
||||||
#prof.mark('8')
|
|
||||||
|
|
||||||
##self.pixmap = QtGui.QPixmap.fromImage(qimage)
|
|
||||||
#prof.mark('9')
|
|
||||||
###del self.ims
|
|
||||||
##self.item.setPixmap(self.pixmap)
|
|
||||||
|
|
||||||
#self.update()
|
|
||||||
#prof.mark('10')
|
|
||||||
|
|
||||||
#if gotNewData:
|
|
||||||
##self.emit(QtCore.SIGNAL('imageChanged'))
|
|
||||||
#self.sigImageChanged.emit()
|
|
||||||
|
|
||||||
#prof.finish()
|
|
||||||
|
|
||||||
#def getLookupTable(self, num, black, white):
|
|
||||||
#num = int(num)
|
|
||||||
#black = int(black)
|
|
||||||
#white = int(white)
|
|
||||||
#if white < black:
|
|
||||||
#b = black
|
|
||||||
#black = white
|
|
||||||
#white = b
|
|
||||||
#key = (num, black, white)
|
|
||||||
#lut = np.empty(num, dtype=np.ubyte)
|
|
||||||
#lut[:black] = 0
|
|
||||||
#rng = lut[black:white]
|
|
||||||
#try:
|
|
||||||
#rng[:] = np.linspace(0, 255, white-black)[:len(rng)]
|
|
||||||
#except:
|
|
||||||
#print key, rng.shape
|
|
||||||
#lut[white:] = 255
|
|
||||||
#return lut
|
|
||||||
|
|
||||||
|
|
||||||
#def applyColorScaling(self, img, offset, scale):
|
|
||||||
#try:
|
|
||||||
#if not ImageItem.useWeave:
|
|
||||||
#raise Exception('Skipping weave compile')
|
|
||||||
##sim = np.ascontiguousarray(self.image) ## should not be needed
|
|
||||||
#sim = img.reshape(img.size)
|
|
||||||
##sim.shape = sim.size
|
|
||||||
#im = np.empty(sim.shape, dtype=np.ubyte)
|
|
||||||
#n = im.size
|
|
||||||
|
|
||||||
#code = """
|
|
||||||
#for( int i=0; i<n; i++ ) {
|
|
||||||
#float a = (sim(i)-offset) * (float)scale;
|
|
||||||
#if( a > 255.0 )
|
|
||||||
#a = 255.0;
|
|
||||||
#else if( a < 0.0 )
|
|
||||||
#a = 0.0;
|
|
||||||
#im(i) = a;
|
|
||||||
#}
|
|
||||||
#"""
|
|
||||||
|
|
||||||
#weave.inline(code, ['sim', 'im', 'n', 'offset', 'scale'], type_converters=converters.blitz, compiler = 'gcc')
|
|
||||||
##sim.shape = shape
|
|
||||||
#im.shape = img.shape
|
|
||||||
#except:
|
|
||||||
#if ImageItem.useWeave:
|
|
||||||
#ImageItem.useWeave = False
|
|
||||||
##sys.excepthook(*sys.exc_info())
|
|
||||||
##print "=============================================================================="
|
|
||||||
##print "Weave compile failed, falling back to slower version."
|
|
||||||
##img.shape = shape
|
|
||||||
#im = ((img - offset) * scale).clip(0.,255.).astype(np.ubyte)
|
|
||||||
#return im
|
|
||||||
|
|
@ -322,7 +322,7 @@ class PlotCurveItem(GraphicsObject):
|
|||||||
|
|
||||||
|
|
||||||
pixels = self.pixelVectors()
|
pixels = self.pixelVectors()
|
||||||
if pixels is None:
|
if pixels == (None, None):
|
||||||
pixels = [Point(0,0), Point(0,0)]
|
pixels = [Point(0,0), Point(0,0)]
|
||||||
xmin = x.min() - pixels[0].x() * lineWidth
|
xmin = x.min() - pixels[0].x() * lineWidth
|
||||||
xmax = x.max() + pixels[0].x() * lineWidth
|
xmax = x.max() + pixels[0].x() * lineWidth
|
||||||
|
@ -22,7 +22,7 @@ class ScaleBar(UIGraphicsItem):
|
|||||||
|
|
||||||
rect = self.boundingRect()
|
rect = self.boundingRect()
|
||||||
unit = self.pixelSize()
|
unit = self.pixelSize()
|
||||||
y = rect.bottom() + (rect.top()-rect.bottom()) * 0.02
|
y = rect.top() + (rect.bottom()-rect.top()) * 0.02
|
||||||
y1 = y + unit[1]*self._width
|
y1 = y + unit[1]*self._width
|
||||||
x = rect.right() + (rect.left()-rect.right()) * 0.02
|
x = rect.right() + (rect.left()-rect.right()) * 0.02
|
||||||
x1 = x - self.size
|
x1 = x - self.size
|
||||||
|
@ -327,7 +327,8 @@ class ViewBox(GraphicsWidget):
|
|||||||
changes[1] = yRange
|
changes[1] = yRange
|
||||||
|
|
||||||
if len(changes) == 0:
|
if len(changes) == 0:
|
||||||
raise Exception("Must specify at least one of rect, xRange, or yRange.")
|
print rect
|
||||||
|
raise Exception("Must specify at least one of rect, xRange, or yRange. (gave rect=%s)" % str(type(rect)))
|
||||||
|
|
||||||
changed = [False, False]
|
changed = [False, False]
|
||||||
for ax, range in changes.items():
|
for ax, range in changes.items():
|
||||||
@ -390,13 +391,17 @@ class ViewBox(GraphicsWidget):
|
|||||||
"""
|
"""
|
||||||
self.setRange(xRange=[min, max], update=update, padding=padding)
|
self.setRange(xRange=[min, max], update=update, padding=padding)
|
||||||
|
|
||||||
def autoRange(self, padding=0.02):
|
def autoRange(self, padding=0.02, item=None):
|
||||||
"""
|
"""
|
||||||
Set the range of the view box to make all children visible.
|
Set the range of the view box to make all children visible.
|
||||||
Note that this is not the same as enableAutoRange, which causes the view to
|
Note that this is not the same as enableAutoRange, which causes the view to
|
||||||
automatically auto-range whenever its contents are changed.
|
automatically auto-range whenever its contents are changed.
|
||||||
"""
|
"""
|
||||||
|
if item is None:
|
||||||
bounds = self.childrenBoundingRect()
|
bounds = self.childrenBoundingRect()
|
||||||
|
else:
|
||||||
|
bounds = self.mapFromItemToView(item, item.boundingRect()).boundingRect()
|
||||||
|
|
||||||
if bounds is not None:
|
if bounds is not None:
|
||||||
self.setRange(bounds, padding=padding)
|
self.setRange(bounds, padding=padding)
|
||||||
|
|
||||||
@ -738,6 +743,19 @@ class ViewBox(GraphicsWidget):
|
|||||||
return self.childGroup.mapToItem(item, obj)
|
return self.childGroup.mapToItem(item, obj)
|
||||||
#return item.mapFromScene(self.mapViewToScene(obj))
|
#return item.mapFromScene(self.mapViewToScene(obj))
|
||||||
|
|
||||||
|
def mapViewToDevice(self, obj):
|
||||||
|
return self.mapToDevice(self.mapFromView(obj))
|
||||||
|
|
||||||
|
def mapDeviceToView(self, obj):
|
||||||
|
return self.mapToView(self.mapFromDevice(obj))
|
||||||
|
|
||||||
|
def viewPixelSize(self):
|
||||||
|
"""Return the (width, height) of a screen pixel in view coordinates."""
|
||||||
|
o = self.mapToView(Point(0,0))
|
||||||
|
px, py = [Point(self.mapToView(v) - o) for v in self.pixelVectors()]
|
||||||
|
return (px.length(), py.length())
|
||||||
|
|
||||||
|
|
||||||
def itemBoundingRect(self, item):
|
def itemBoundingRect(self, item):
|
||||||
"""Return the bounding rect of the item in view coordinates"""
|
"""Return the bounding rect of the item in view coordinates"""
|
||||||
return self.mapSceneToView(item.sceneBoundingRect()).boundingRect()
|
return self.mapSceneToView(item.sceneBoundingRect()).boundingRect()
|
||||||
|
@ -175,7 +175,7 @@ class ImageView(QtGui.QWidget):
|
|||||||
|
|
||||||
self.roiClicked() ## initialize roi plot to correct shape / visibility
|
self.roiClicked() ## initialize roi plot to correct shape / visibility
|
||||||
|
|
||||||
def setImage(self, img, autoRange=True, autoLevels=True, levels=None, axes=None, xvals=None, pos=None, scale=None):
|
def setImage(self, img, autoRange=True, autoLevels=True, levels=None, axes=None, xvals=None, pos=None, scale=None, transform=None):
|
||||||
"""
|
"""
|
||||||
Set the image to be displayed in the widget.
|
Set the image to be displayed in the widget.
|
||||||
|
|
||||||
@ -284,6 +284,8 @@ class ImageView(QtGui.QWidget):
|
|||||||
self.imageItem.scale(*scale)
|
self.imageItem.scale(*scale)
|
||||||
if pos is not None:
|
if pos is not None:
|
||||||
self.imageItem.setPos(*pos)
|
self.imageItem.setPos(*pos)
|
||||||
|
if transform is not None:
|
||||||
|
self.imageItem.setTransform(transform)
|
||||||
prof.mark('6')
|
prof.mark('6')
|
||||||
|
|
||||||
if autoRange:
|
if autoRange:
|
||||||
@ -325,7 +327,7 @@ class ImageView(QtGui.QWidget):
|
|||||||
image = self.getProcessedImage()
|
image = self.getProcessedImage()
|
||||||
|
|
||||||
#self.ui.graphicsView.setRange(QtCore.QRectF(0, 0, image.shape[self.axes['x']], image.shape[self.axes['y']]), padding=0., lockAspect=True)
|
#self.ui.graphicsView.setRange(QtCore.QRectF(0, 0, image.shape[self.axes['x']], image.shape[self.axes['y']]), padding=0., lockAspect=True)
|
||||||
self.view.setRange(self.imageItem.boundingRect(), padding=0.)
|
self.view.autoRange() ##setRange(self.imageItem.viewBoundingRect(), padding=0.)
|
||||||
|
|
||||||
def getProcessedImage(self):
|
def getProcessedImage(self):
|
||||||
"""Returns the image data after it has been processed by any normalization options in use."""
|
"""Returns the image data after it has been processed by any normalization options in use."""
|
||||||
|
@ -57,7 +57,7 @@ class CheckTable(QtGui.QWidget):
|
|||||||
|
|
||||||
def removeRow(self, name):
|
def removeRow(self, name):
|
||||||
row = self.rowNames.index(name)
|
row = self.rowNames.index(name)
|
||||||
self.oldRows[name] = self.saveState['rows'][name] ## save for later
|
self.oldRows[name] = self.saveState()['rows'][row] ## save for later
|
||||||
self.rowNames.pop(row)
|
self.rowNames.pop(row)
|
||||||
for w in self.rowWidgets[row]:
|
for w in self.rowWidgets[row]:
|
||||||
w.setParent(None)
|
w.setParent(None)
|
||||||
|
@ -12,6 +12,8 @@ class JoystickButton(QtGui.QPushButton):
|
|||||||
self.setCheckable(True)
|
self.setCheckable(True)
|
||||||
self.state = None
|
self.state = None
|
||||||
self.setState(0,0)
|
self.setState(0,0)
|
||||||
|
self.setFixedWidth(50)
|
||||||
|
self.setFixedHeight(50)
|
||||||
|
|
||||||
|
|
||||||
def mousePressEvent(self, ev):
|
def mousePressEvent(self, ev):
|
||||||
|
@ -47,6 +47,8 @@ class ValueLabel(QtGui.QLabel):
|
|||||||
self.formatStr = text
|
self.formatStr = text
|
||||||
self.update()
|
self.update()
|
||||||
|
|
||||||
|
def setAverageTime(self, t):
|
||||||
|
self.averageTime = t
|
||||||
|
|
||||||
def averageValue(self):
|
def averageValue(self):
|
||||||
return reduce(lambda a,b: a+b, [v[1] for v in self.values]) / float(len(self.values))
|
return reduce(lambda a,b: a+b, [v[1] for v in self.values]) / float(len(self.values))
|
||||||
|
Loading…
Reference in New Issue
Block a user