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._button = pressEvent.button()
|
||||
self._modifiers = moveEvent.modifiers()
|
||||
self.acceptedItem = None
|
||||
|
||||
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."""
|
||||
@ -160,7 +161,7 @@ class MouseClickEvent:
|
||||
self._buttons = pressEvent.buttons()
|
||||
self._modifiers = pressEvent.modifiers()
|
||||
self._time = ptime.time()
|
||||
|
||||
self.acceptedItem = None
|
||||
|
||||
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."""
|
||||
|
21
Transform.py
21
Transform.py
@ -2,6 +2,7 @@
|
||||
from .Qt import QtCore, QtGui
|
||||
from .Point import Point
|
||||
import numpy as np
|
||||
import pyqtgraph as pg
|
||||
|
||||
class Transform(QtGui.QTransform):
|
||||
"""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)
|
||||
self.reset()
|
||||
|
||||
if isinstance(init, dict):
|
||||
if init is None:
|
||||
return
|
||||
elif isinstance(init, dict):
|
||||
self.restoreState(init)
|
||||
elif isinstance(init, Transform):
|
||||
self._state = {
|
||||
@ -22,6 +25,10 @@ class Transform(QtGui.QTransform):
|
||||
self.update()
|
||||
elif isinstance(init, QtGui.QTransform):
|
||||
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):
|
||||
@ -65,6 +72,18 @@ class Transform(QtGui.QTransform):
|
||||
}
|
||||
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):
|
||||
"""Acceptable arguments are:
|
||||
x, y
|
||||
|
@ -110,7 +110,9 @@ importAll('widgets', excludes=['MatplotlibWidget'])
|
||||
from .imageview import *
|
||||
from .WidgetGroup import *
|
||||
from .Point import Point
|
||||
from .Vector import Vector
|
||||
from .Transform import Transform
|
||||
from .Transform3D import Transform3D
|
||||
from .functions import *
|
||||
from .graphicsWindows import *
|
||||
from .SignalProxy import *
|
||||
|
@ -51,7 +51,7 @@ class Canvas(QtGui.QWidget):
|
||||
|
||||
#self.view.enableMouse()
|
||||
self.view.setAspectLocked(True)
|
||||
self.view.invertY()
|
||||
#self.view.invertY()
|
||||
|
||||
grid = GridItem()
|
||||
self.grid = CanvasItem(grid, name='Grid', movable=False)
|
||||
|
@ -7,14 +7,14 @@ class Dock(QtGui.QWidget, DockDrop):
|
||||
|
||||
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)
|
||||
DockDrop.__init__(self)
|
||||
self.area = area
|
||||
self.label = DockLabel(name, self)
|
||||
self.labelHidden = False
|
||||
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.label.setAlignment(QtCore.Qt.AlignHCenter)
|
||||
self.topLayout = QtGui.QGridLayout()
|
||||
@ -63,6 +63,12 @@ class Dock(QtGui.QWidget, DockDrop):
|
||||
self.widgetArea.setStyleSheet(self.hStyle)
|
||||
|
||||
self.setStretch(*size)
|
||||
|
||||
if widget is not None:
|
||||
self.addWidget(widget)
|
||||
|
||||
if hideTitle:
|
||||
self.hideTitleBar()
|
||||
|
||||
def implements(self, name=None):
|
||||
if name is None:
|
||||
@ -108,7 +114,7 @@ class Dock(QtGui.QWidget, DockDrop):
|
||||
|
||||
def setOrientation(self, o='auto', force=False):
|
||||
#print self.name(), "setOrientation", o, force
|
||||
if o == 'auto':
|
||||
if o == 'auto' and self.autoOrient:
|
||||
if self.container().type() == 'tab':
|
||||
o = 'horizontal'
|
||||
elif self.width() > self.height()*1.5:
|
||||
|
@ -9,21 +9,19 @@ import pyqtgraph as pg
|
||||
app = QtGui.QApplication([])
|
||||
|
||||
## Create window with GraphicsView widget
|
||||
win = QtGui.QMainWindow()
|
||||
win.resize(800,800)
|
||||
view = pg.GraphicsView()
|
||||
#view.useOpenGL(True)
|
||||
win.setCentralWidget(view)
|
||||
win.show()
|
||||
w = pg.GraphicsView()
|
||||
w.show()
|
||||
w.resize(800,800)
|
||||
|
||||
## Allow mouse scale/pan
|
||||
view.enableMouse()
|
||||
## ..But lock the aspect ratio
|
||||
view = pg.ViewBox()
|
||||
w.setCentralItem(view)
|
||||
|
||||
## lock the aspect ratio
|
||||
view.setAspectLocked(True)
|
||||
|
||||
## Create image item
|
||||
img = pg.ImageItem(np.zeros((200,200)))
|
||||
view.scene().addItem(img)
|
||||
view.addItem(img)
|
||||
|
||||
## Set initial view bounds
|
||||
view.setRange(QtCore.QRectF(0, 0, 200, 200))
|
||||
|
@ -30,9 +30,7 @@ class ImageItem(GraphicsObject):
|
||||
|
||||
|
||||
sigImageChanged = QtCore.Signal()
|
||||
|
||||
## performance gains from this are marginal, and it's rather unreliable.
|
||||
useWeave = False
|
||||
sigRemoveRequested = QtCore.Signal(object) # self; emitted when 'remove' is selected from context menu
|
||||
|
||||
def __init__(self, image=None, **kargs):
|
||||
"""
|
||||
@ -48,7 +46,6 @@ class ImageItem(GraphicsObject):
|
||||
#self.clipMask = None
|
||||
|
||||
self.paintMode = None
|
||||
#self.useWeave = True
|
||||
|
||||
self.levels = None ## [min, max] or [[redMin, redMax], ...]
|
||||
self.lut = None
|
||||
@ -56,6 +53,7 @@ class ImageItem(GraphicsObject):
|
||||
#self.clipLevel = None
|
||||
self.drawKernel = None
|
||||
self.border = None
|
||||
self.removable = False
|
||||
|
||||
if image is not None:
|
||||
self.setImage(image, **kargs)
|
||||
@ -160,6 +158,9 @@ class ImageItem(GraphicsObject):
|
||||
self.setCompositionMode(kargs['compositionMode'])
|
||||
if 'border' in kargs:
|
||||
self.setBorder(kargs['border'])
|
||||
if 'removable' in kargs:
|
||||
self.removable = kargs['removable']
|
||||
self.menu = None
|
||||
|
||||
def setRect(self, rect):
|
||||
"""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)
|
||||
self.qimage = fn.makeQImage(argb, alpha)
|
||||
#self.pixmap = QtGui.QPixmap.fromImage(self.qimage)
|
||||
prof.finish()
|
||||
|
||||
|
||||
@ -324,21 +324,72 @@ class ImageItem(GraphicsObject):
|
||||
return 1,1
|
||||
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:
|
||||
self.drawAt(ev.pos(), ev)
|
||||
ev.accept()
|
||||
else:
|
||||
ev.ignore()
|
||||
|
||||
def raiseContextMenu(self, ev):
|
||||
## only raise menu if this terminal is removable
|
||||
menu = self.getMenu()
|
||||
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 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 tabletEvent(self, ev):
|
||||
print(ev.device())
|
||||
print(ev.pointerType())
|
||||
@ -364,20 +415,10 @@ class ImageItem(GraphicsObject):
|
||||
ty[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]))
|
||||
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
|
||||
src = dk
|
||||
#print self.image[ts].shape, src.shape
|
||||
|
||||
if isinstance(self.drawMode, collections.Callable):
|
||||
self.drawMode(dk, self.image, mask, ss, ts, ev)
|
||||
@ -401,197 +442,5 @@ class ImageItem(GraphicsObject):
|
||||
self.drawMode = mode
|
||||
self.drawMask = mask
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#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
|
||||
|
||||
def removeClicked(self):
|
||||
self.sigRemoveRequested.emit(self)
|
@ -322,7 +322,7 @@ class PlotCurveItem(GraphicsObject):
|
||||
|
||||
|
||||
pixels = self.pixelVectors()
|
||||
if pixels is None:
|
||||
if pixels == (None, None):
|
||||
pixels = [Point(0,0), Point(0,0)]
|
||||
xmin = x.min() - pixels[0].x() * lineWidth
|
||||
xmax = x.max() + pixels[0].x() * lineWidth
|
||||
|
@ -22,7 +22,7 @@ class ScaleBar(UIGraphicsItem):
|
||||
|
||||
rect = self.boundingRect()
|
||||
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
|
||||
x = rect.right() + (rect.left()-rect.right()) * 0.02
|
||||
x1 = x - self.size
|
||||
|
@ -327,7 +327,8 @@ class ViewBox(GraphicsWidget):
|
||||
changes[1] = yRange
|
||||
|
||||
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]
|
||||
for ax, range in changes.items():
|
||||
@ -390,13 +391,17 @@ class ViewBox(GraphicsWidget):
|
||||
"""
|
||||
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.
|
||||
Note that this is not the same as enableAutoRange, which causes the view to
|
||||
automatically auto-range whenever its contents are changed.
|
||||
"""
|
||||
bounds = self.childrenBoundingRect()
|
||||
if item is None:
|
||||
bounds = self.childrenBoundingRect()
|
||||
else:
|
||||
bounds = self.mapFromItemToView(item, item.boundingRect()).boundingRect()
|
||||
|
||||
if bounds is not None:
|
||||
self.setRange(bounds, padding=padding)
|
||||
|
||||
@ -738,6 +743,19 @@ class ViewBox(GraphicsWidget):
|
||||
return self.childGroup.mapToItem(item, 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):
|
||||
"""Return the bounding rect of the item in view coordinates"""
|
||||
return self.mapSceneToView(item.sceneBoundingRect()).boundingRect()
|
||||
|
@ -175,7 +175,7 @@ class ImageView(QtGui.QWidget):
|
||||
|
||||
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.
|
||||
|
||||
@ -284,6 +284,8 @@ class ImageView(QtGui.QWidget):
|
||||
self.imageItem.scale(*scale)
|
||||
if pos is not None:
|
||||
self.imageItem.setPos(*pos)
|
||||
if transform is not None:
|
||||
self.imageItem.setTransform(transform)
|
||||
prof.mark('6')
|
||||
|
||||
if autoRange:
|
||||
@ -325,7 +327,7 @@ class ImageView(QtGui.QWidget):
|
||||
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.view.setRange(self.imageItem.boundingRect(), padding=0.)
|
||||
self.view.autoRange() ##setRange(self.imageItem.viewBoundingRect(), padding=0.)
|
||||
|
||||
def getProcessedImage(self):
|
||||
"""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):
|
||||
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)
|
||||
for w in self.rowWidgets[row]:
|
||||
w.setParent(None)
|
||||
|
@ -12,6 +12,8 @@ class JoystickButton(QtGui.QPushButton):
|
||||
self.setCheckable(True)
|
||||
self.state = None
|
||||
self.setState(0,0)
|
||||
self.setFixedWidth(50)
|
||||
self.setFixedHeight(50)
|
||||
|
||||
|
||||
def mousePressEvent(self, ev):
|
||||
|
@ -47,6 +47,8 @@ class ValueLabel(QtGui.QLabel):
|
||||
self.formatStr = text
|
||||
self.update()
|
||||
|
||||
def setAverageTime(self, t):
|
||||
self.averageTime = t
|
||||
|
||||
def averageValue(self):
|
||||
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