merge inp

This commit is contained in:
Guillaume Poulin 2013-09-05 00:28:03 +08:00
commit c02e6184ef
23 changed files with 362 additions and 140 deletions

View File

@ -12,6 +12,7 @@ Contributors:
Christian Gavin
Michael Cristopher Hogg
Ulrich Leutner
Felix Schill
Requirements:
PyQt 4.7+ or PySide

View File

@ -130,8 +130,13 @@ def update():
if ui.rawRadio.isChecked():
ui.rawImg.setImage(data[ptr%data.shape[0]], lut=useLut, levels=useScale)
ui.stack.setCurrentIndex(1)
elif ui.rawGLRadio.isChecked():
ui.rawGLImg.setImage(data[ptr%data.shape[0]], lut=useLut, levels=useScale)
ui.stack.setCurrentIndex(2)
else:
img.setImage(data[ptr%data.shape[0]], autoLevels=False, levels=useScale, lut=useLut)
ui.stack.setCurrentIndex(0)
#img.setImage(data[ptr%data.shape[0]], autoRange=False)
ptr += 1

View File

@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>985</width>
<height>674</height>
<width>695</width>
<height>798</height>
</rect>
</property>
<property name="windowTitle">
@ -17,33 +17,62 @@
<layout class="QGridLayout" name="gridLayout_2">
<item row="1" column="0" colspan="4">
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="RawImageWidget" name="rawImg" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="GraphicsView" name="graphicsView"/>
</item>
<item row="1" column="0">
<item row="3" column="0">
<widget class="QRadioButton" name="rawRadio">
<property name="text">
<string>RawImageWidget (unscaled; faster)</string>
<string>RawImageWidget</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="1">
<item row="2" column="0">
<widget class="QRadioButton" name="gfxRadio">
<property name="text">
<string>GraphicsView + ImageItem (scaled; slower)</string>
<string>GraphicsView + ImageItem</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QStackedWidget" name="stack">
<property name="currentIndex">
<number>2</number>
</property>
<widget class="QWidget" name="page">
<layout class="QGridLayout" name="gridLayout_3">
<item row="0" column="0">
<widget class="GraphicsView" name="graphicsView"/>
</item>
</layout>
</widget>
<widget class="QWidget" name="page_2">
<layout class="QGridLayout" name="gridLayout_4">
<item row="0" column="0">
<widget class="RawImageWidget" name="rawImg" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="page_3">
<layout class="QGridLayout" name="gridLayout_5">
<item row="0" column="0">
<widget class="RawImageGLWidget" name="rawGLImg" native="true"/>
</item>
</layout>
</widget>
</widget>
</item>
<item row="4" column="0">
<widget class="QRadioButton" name="rawGLRadio">
<property name="text">
<string>RawGLImageWidget</string>
</property>
</widget>
</item>
@ -250,6 +279,12 @@
<extends>QDoubleSpinBox</extends>
<header>pyqtgraph</header>
</customwidget>
<customwidget>
<class>RawImageGLWidget</class>
<extends>QWidget</extends>
<header>pyqtgraph.widgets.RawImageWidget</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources/>
<connections/>

View File

@ -1,9 +1,9 @@
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file './examples/VideoTemplate.ui'
# Form implementation generated from reading ui file './VideoTemplate.ui'
#
# Created: Sun Nov 4 18:24:20 2012
# by: PyQt4 UI code generator 4.9.1
# Created: Tue Jul 9 23:38:17 2013
# by: PyQt4 UI code generator 4.9.3
#
# WARNING! All changes made in this file will be lost!
@ -17,31 +17,55 @@ except AttributeError:
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName(_fromUtf8("MainWindow"))
MainWindow.resize(985, 674)
MainWindow.resize(695, 798)
self.centralwidget = QtGui.QWidget(MainWindow)
self.centralwidget.setObjectName(_fromUtf8("centralwidget"))
self.gridLayout_2 = QtGui.QGridLayout(self.centralwidget)
self.gridLayout_2.setObjectName(_fromUtf8("gridLayout_2"))
self.gridLayout = QtGui.QGridLayout()
self.gridLayout.setObjectName(_fromUtf8("gridLayout"))
self.rawImg = RawImageWidget(self.centralwidget)
self.rawRadio = QtGui.QRadioButton(self.centralwidget)
self.rawRadio.setChecked(True)
self.rawRadio.setObjectName(_fromUtf8("rawRadio"))
self.gridLayout.addWidget(self.rawRadio, 3, 0, 1, 1)
self.gfxRadio = QtGui.QRadioButton(self.centralwidget)
self.gfxRadio.setObjectName(_fromUtf8("gfxRadio"))
self.gridLayout.addWidget(self.gfxRadio, 2, 0, 1, 1)
self.stack = QtGui.QStackedWidget(self.centralwidget)
self.stack.setObjectName(_fromUtf8("stack"))
self.page = QtGui.QWidget()
self.page.setObjectName(_fromUtf8("page"))
self.gridLayout_3 = QtGui.QGridLayout(self.page)
self.gridLayout_3.setObjectName(_fromUtf8("gridLayout_3"))
self.graphicsView = GraphicsView(self.page)
self.graphicsView.setObjectName(_fromUtf8("graphicsView"))
self.gridLayout_3.addWidget(self.graphicsView, 0, 0, 1, 1)
self.stack.addWidget(self.page)
self.page_2 = QtGui.QWidget()
self.page_2.setObjectName(_fromUtf8("page_2"))
self.gridLayout_4 = QtGui.QGridLayout(self.page_2)
self.gridLayout_4.setObjectName(_fromUtf8("gridLayout_4"))
self.rawImg = RawImageWidget(self.page_2)
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Preferred)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.rawImg.sizePolicy().hasHeightForWidth())
self.rawImg.setSizePolicy(sizePolicy)
self.rawImg.setObjectName(_fromUtf8("rawImg"))
self.gridLayout.addWidget(self.rawImg, 0, 0, 1, 1)
self.graphicsView = GraphicsView(self.centralwidget)
self.graphicsView.setObjectName(_fromUtf8("graphicsView"))
self.gridLayout.addWidget(self.graphicsView, 0, 1, 1, 1)
self.rawRadio = QtGui.QRadioButton(self.centralwidget)
self.rawRadio.setChecked(True)
self.rawRadio.setObjectName(_fromUtf8("rawRadio"))
self.gridLayout.addWidget(self.rawRadio, 1, 0, 1, 1)
self.gfxRadio = QtGui.QRadioButton(self.centralwidget)
self.gfxRadio.setObjectName(_fromUtf8("gfxRadio"))
self.gridLayout.addWidget(self.gfxRadio, 1, 1, 1, 1)
self.gridLayout_4.addWidget(self.rawImg, 0, 0, 1, 1)
self.stack.addWidget(self.page_2)
self.page_3 = QtGui.QWidget()
self.page_3.setObjectName(_fromUtf8("page_3"))
self.gridLayout_5 = QtGui.QGridLayout(self.page_3)
self.gridLayout_5.setObjectName(_fromUtf8("gridLayout_5"))
self.rawGLImg = RawImageGLWidget(self.page_3)
self.rawGLImg.setObjectName(_fromUtf8("rawGLImg"))
self.gridLayout_5.addWidget(self.rawGLImg, 0, 0, 1, 1)
self.stack.addWidget(self.page_3)
self.gridLayout.addWidget(self.stack, 0, 0, 1, 1)
self.rawGLRadio = QtGui.QRadioButton(self.centralwidget)
self.rawGLRadio.setObjectName(_fromUtf8("rawGLRadio"))
self.gridLayout.addWidget(self.rawGLRadio, 4, 0, 1, 1)
self.gridLayout_2.addLayout(self.gridLayout, 1, 0, 1, 4)
self.label = QtGui.QLabel(self.centralwidget)
self.label.setObjectName(_fromUtf8("label"))
@ -130,12 +154,14 @@ class Ui_MainWindow(object):
MainWindow.setCentralWidget(self.centralwidget)
self.retranslateUi(MainWindow)
self.stack.setCurrentIndex(2)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
MainWindow.setWindowTitle(QtGui.QApplication.translate("MainWindow", "MainWindow", None, QtGui.QApplication.UnicodeUTF8))
self.rawRadio.setText(QtGui.QApplication.translate("MainWindow", "RawImageWidget (unscaled; faster)", None, QtGui.QApplication.UnicodeUTF8))
self.gfxRadio.setText(QtGui.QApplication.translate("MainWindow", "GraphicsView + ImageItem (scaled; slower)", None, QtGui.QApplication.UnicodeUTF8))
self.rawRadio.setText(QtGui.QApplication.translate("MainWindow", "RawImageWidget", None, QtGui.QApplication.UnicodeUTF8))
self.gfxRadio.setText(QtGui.QApplication.translate("MainWindow", "GraphicsView + ImageItem", None, QtGui.QApplication.UnicodeUTF8))
self.rawGLRadio.setText(QtGui.QApplication.translate("MainWindow", "RawGLImageWidget", None, QtGui.QApplication.UnicodeUTF8))
self.label.setText(QtGui.QApplication.translate("MainWindow", "Data type", None, QtGui.QApplication.UnicodeUTF8))
self.dtypeCombo.setItemText(0, QtGui.QApplication.translate("MainWindow", "uint8", None, QtGui.QApplication.UnicodeUTF8))
self.dtypeCombo.setItemText(1, QtGui.QApplication.translate("MainWindow", "uint16", None, QtGui.QApplication.UnicodeUTF8))
@ -150,4 +176,5 @@ class Ui_MainWindow(object):
self.fpsLabel.setText(QtGui.QApplication.translate("MainWindow", "FPS", None, QtGui.QApplication.UnicodeUTF8))
self.rgbCheck.setText(QtGui.QApplication.translate("MainWindow", "RGB", None, QtGui.QApplication.UnicodeUTF8))
from pyqtgraph import SpinBox, GradientWidget, GraphicsView, RawImageWidget
from pyqtgraph.widgets.RawImageWidget import RawImageGLWidget
from pyqtgraph import GradientWidget, SpinBox, GraphicsView, RawImageWidget

View File

@ -1,9 +1,9 @@
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file './examples/VideoTemplate.ui'
# Form implementation generated from reading ui file './VideoTemplate.ui'
#
# Created: Sun Nov 4 18:24:21 2012
# by: pyside-uic 0.2.13 running on PySide 1.1.0
# Created: Tue Jul 9 23:38:19 2013
# by: pyside-uic 0.2.13 running on PySide 1.1.2
#
# WARNING! All changes made in this file will be lost!
@ -12,31 +12,55 @@ from PySide import QtCore, QtGui
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(985, 674)
MainWindow.resize(695, 798)
self.centralwidget = QtGui.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.gridLayout_2 = QtGui.QGridLayout(self.centralwidget)
self.gridLayout_2.setObjectName("gridLayout_2")
self.gridLayout = QtGui.QGridLayout()
self.gridLayout.setObjectName("gridLayout")
self.rawImg = RawImageWidget(self.centralwidget)
self.rawRadio = QtGui.QRadioButton(self.centralwidget)
self.rawRadio.setChecked(True)
self.rawRadio.setObjectName("rawRadio")
self.gridLayout.addWidget(self.rawRadio, 3, 0, 1, 1)
self.gfxRadio = QtGui.QRadioButton(self.centralwidget)
self.gfxRadio.setObjectName("gfxRadio")
self.gridLayout.addWidget(self.gfxRadio, 2, 0, 1, 1)
self.stack = QtGui.QStackedWidget(self.centralwidget)
self.stack.setObjectName("stack")
self.page = QtGui.QWidget()
self.page.setObjectName("page")
self.gridLayout_3 = QtGui.QGridLayout(self.page)
self.gridLayout_3.setObjectName("gridLayout_3")
self.graphicsView = GraphicsView(self.page)
self.graphicsView.setObjectName("graphicsView")
self.gridLayout_3.addWidget(self.graphicsView, 0, 0, 1, 1)
self.stack.addWidget(self.page)
self.page_2 = QtGui.QWidget()
self.page_2.setObjectName("page_2")
self.gridLayout_4 = QtGui.QGridLayout(self.page_2)
self.gridLayout_4.setObjectName("gridLayout_4")
self.rawImg = RawImageWidget(self.page_2)
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Preferred)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.rawImg.sizePolicy().hasHeightForWidth())
self.rawImg.setSizePolicy(sizePolicy)
self.rawImg.setObjectName("rawImg")
self.gridLayout.addWidget(self.rawImg, 0, 0, 1, 1)
self.graphicsView = GraphicsView(self.centralwidget)
self.graphicsView.setObjectName("graphicsView")
self.gridLayout.addWidget(self.graphicsView, 0, 1, 1, 1)
self.rawRadio = QtGui.QRadioButton(self.centralwidget)
self.rawRadio.setChecked(True)
self.rawRadio.setObjectName("rawRadio")
self.gridLayout.addWidget(self.rawRadio, 1, 0, 1, 1)
self.gfxRadio = QtGui.QRadioButton(self.centralwidget)
self.gfxRadio.setObjectName("gfxRadio")
self.gridLayout.addWidget(self.gfxRadio, 1, 1, 1, 1)
self.gridLayout_4.addWidget(self.rawImg, 0, 0, 1, 1)
self.stack.addWidget(self.page_2)
self.page_3 = QtGui.QWidget()
self.page_3.setObjectName("page_3")
self.gridLayout_5 = QtGui.QGridLayout(self.page_3)
self.gridLayout_5.setObjectName("gridLayout_5")
self.rawGLImg = RawImageGLWidget(self.page_3)
self.rawGLImg.setObjectName("rawGLImg")
self.gridLayout_5.addWidget(self.rawGLImg, 0, 0, 1, 1)
self.stack.addWidget(self.page_3)
self.gridLayout.addWidget(self.stack, 0, 0, 1, 1)
self.rawGLRadio = QtGui.QRadioButton(self.centralwidget)
self.rawGLRadio.setObjectName("rawGLRadio")
self.gridLayout.addWidget(self.rawGLRadio, 4, 0, 1, 1)
self.gridLayout_2.addLayout(self.gridLayout, 1, 0, 1, 4)
self.label = QtGui.QLabel(self.centralwidget)
self.label.setObjectName("label")
@ -125,12 +149,14 @@ class Ui_MainWindow(object):
MainWindow.setCentralWidget(self.centralwidget)
self.retranslateUi(MainWindow)
self.stack.setCurrentIndex(2)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
MainWindow.setWindowTitle(QtGui.QApplication.translate("MainWindow", "MainWindow", None, QtGui.QApplication.UnicodeUTF8))
self.rawRadio.setText(QtGui.QApplication.translate("MainWindow", "RawImageWidget (unscaled; faster)", None, QtGui.QApplication.UnicodeUTF8))
self.gfxRadio.setText(QtGui.QApplication.translate("MainWindow", "GraphicsView + ImageItem (scaled; slower)", None, QtGui.QApplication.UnicodeUTF8))
self.rawRadio.setText(QtGui.QApplication.translate("MainWindow", "RawImageWidget", None, QtGui.QApplication.UnicodeUTF8))
self.gfxRadio.setText(QtGui.QApplication.translate("MainWindow", "GraphicsView + ImageItem", None, QtGui.QApplication.UnicodeUTF8))
self.rawGLRadio.setText(QtGui.QApplication.translate("MainWindow", "RawGLImageWidget", None, QtGui.QApplication.UnicodeUTF8))
self.label.setText(QtGui.QApplication.translate("MainWindow", "Data type", None, QtGui.QApplication.UnicodeUTF8))
self.dtypeCombo.setItemText(0, QtGui.QApplication.translate("MainWindow", "uint8", None, QtGui.QApplication.UnicodeUTF8))
self.dtypeCombo.setItemText(1, QtGui.QApplication.translate("MainWindow", "uint16", None, QtGui.QApplication.UnicodeUTF8))
@ -145,4 +171,5 @@ class Ui_MainWindow(object):
self.fpsLabel.setText(QtGui.QApplication.translate("MainWindow", "FPS", None, QtGui.QApplication.UnicodeUTF8))
self.rgbCheck.setText(QtGui.QApplication.translate("MainWindow", "RGB", None, QtGui.QApplication.UnicodeUTF8))
from pyqtgraph import SpinBox, GradientWidget, GraphicsView, RawImageWidget
from pyqtgraph.widgets.RawImageWidget import RawImageGLWidget
from pyqtgraph import GradientWidget, SpinBox, GraphicsView, RawImageWidget

View File

@ -67,7 +67,7 @@ params = [
{'name': 'Float', 'type': 'float', 'value': 10.5, 'step': 0.1},
{'name': 'String', 'type': 'str', 'value': "hi"},
{'name': 'List', 'type': 'list', 'values': [1,2,3], 'value': 2},
{'name': 'Named List', 'type': 'list', 'values': {"one": 1, "two": 2, "three": 3}, 'value': 2},
{'name': 'Named List', 'type': 'list', 'values': {"one": 1, "two": "twosies", "three": [3,3,3]}, 'value': 2},
{'name': 'Boolean', 'type': 'bool', 'value': True, 'tip': "This is a checkbox"},
{'name': 'Color', 'type': 'color', 'value': "FF0", 'tip': "This is a color button"},
{'name': 'Gradient', 'type': 'colormap'},
@ -139,14 +139,19 @@ p.param('Save/Restore functionality', 'Restore State').sigActivated.connect(rest
## Create two ParameterTree widgets, both accessing the same data
t = ParameterTree()
t.setParameters(p, showTop=False)
t.show()
t.setWindowTitle('pyqtgraph example: Parameter Tree')
t.resize(400,800)
t2 = ParameterTree()
t2.setParameters(p, showTop=False)
t2.show()
t2.resize(400,800)
win = QtGui.QWidget()
layout = QtGui.QGridLayout()
win.setLayout(layout)
layout.addWidget(QtGui.QLabel("These are two views of the same data. They should always display the same values."), 0, 0, 1, 2)
layout.addWidget(t, 1, 0, 1, 1)
layout.addWidget(t2, 1, 1, 1, 1)
win.show()
win.resize(800,800)
## test save/restore
s = p.saveState()
p.restoreState(s)

View File

@ -255,7 +255,7 @@ def exit():
## close file handles
os.closerange(3, 4096) ## just guessing on the maximum descriptor count..
os._exit(os.EX_OK)
os._exit(0)
@ -281,7 +281,7 @@ def plot(*args, **kargs):
#if len(args)+len(kargs) > 0:
#w.plot(*args, **kargs)
pwArgList = ['title', 'labels', 'name', 'left', 'right', 'top', 'bottom']
pwArgList = ['title', 'labels', 'name', 'left', 'right', 'top', 'bottom', 'background']
pwArgs = {}
dataArgs = {}
for k in kargs:

View File

@ -119,7 +119,7 @@ class Exporter(object):
else:
childs = root.childItems()
rootItem = [root]
childs.sort(lambda a,b: cmp(a.zValue(), b.zValue()))
childs.sort(key=lambda a: a.zValue())
while len(childs) > 0:
ch = childs.pop(0)
tree = self.getPaintItems(ch)

View File

@ -1,6 +1,6 @@
from .Exporter import Exporter
from pyqtgraph.parametertree import Parameter
from pyqtgraph.Qt import QtGui, QtCore, QtSvg
from pyqtgraph.Qt import QtGui, QtCore, QtSvg, USE_PYSIDE
import pyqtgraph as pg
import numpy as np
@ -17,7 +17,11 @@ class ImageExporter(Exporter):
scene = item.scene()
else:
scene = item
bg = scene.views()[0].backgroundBrush().color()
bgbrush = scene.views()[0].backgroundBrush()
bg = bgbrush.color()
if bgbrush.style() == QtCore.Qt.NoBrush:
bg.setAlpha(0)
self.params = Parameter(name='params', type='group', children=[
{'name': 'width', 'type': 'int', 'value': tr.width(), 'limits': (0, None)},
{'name': 'height', 'type': 'int', 'value': tr.height(), 'limits': (0, None)},
@ -42,7 +46,10 @@ class ImageExporter(Exporter):
def export(self, fileName=None, toBytes=False, copy=False):
if fileName is None and not toBytes and not copy:
filter = ["*."+str(f) for f in QtGui.QImageWriter.supportedImageFormats()]
if USE_PYSIDE:
filter = ["*."+str(f) for f in QtGui.QImageWriter.supportedImageFormats()]
else:
filter = ["*."+bytes(f).decode('utf-8') for f in QtGui.QImageWriter.supportedImageFormats()]
preferred = ['*.png', '*.tif', '*.jpg']
for p in preferred[::-1]:
if p in filter:

View File

@ -376,10 +376,10 @@ class Flowchart(Node):
#tdeps[t] = lastNode
if lastInd is not None:
dels.append((lastInd+1, t))
dels.sort(lambda a,b: cmp(b[0], a[0]))
#dels.sort(lambda a,b: cmp(b[0], a[0]))
dels.sort(key=lambda a: a[0], reverse=True)
for i, t in dels:
ops.insert(i, ('d', t))
return ops
@ -491,7 +491,8 @@ class Flowchart(Node):
self.clear()
Node.restoreState(self, state)
nodes = state['nodes']
nodes.sort(lambda a, b: cmp(a['pos'][0], b['pos'][0]))
#nodes.sort(lambda a, b: cmp(a['pos'][0], b['pos'][0]))
nodes.sort(key=lambda a: a['pos'][0])
for n in nodes:
if n['name'] in self._nodes:
#self._nodes[n['name']].graphicsItem().moveBy(*n['pos'])

View File

@ -261,6 +261,9 @@ class PlotCurveItem(GraphicsObject):
by :func:`mkBrush <pyqtgraph.mkBrush>` is allowed.
antialias (bool) Whether to use antialiasing when drawing. This
is disabled by default because it decreases performance.
stepMode If True, two orthogonal lines are drawn for each sample
as steps. This is commonly used when drawing histograms.
Note that in this case, len(x) == len(y) + 1
============== ========================================================
If non-keyword arguments are used, they will be interpreted as

View File

@ -475,7 +475,7 @@ class PlotDataItem(GraphicsObject):
if self.xClean is None:
nanMask = np.isnan(self.xData) | np.isnan(self.yData) | np.isinf(self.xData) | np.isinf(self.yData)
if any(nanMask):
if nanMask.any():
self.dataMask = ~nanMask
self.xClean = self.xData[self.dataMask]
self.yClean = self.yData[self.dataMask]
@ -495,10 +495,7 @@ class PlotDataItem(GraphicsObject):
##y = resample(y[:len(x)*ds], len(x)) ## scipy.signal.resample causes nasty ringing
#y = y[::ds]
if self.opts['fftMode']:
f = np.fft.fft(y) / len(y)
y = abs(f[1:len(f)/2])
dt = x[-1] - x[0]
x = np.linspace(0, 0.5*len(x)/dt, len(y))
x,y = self._fourierTransform(x, y)
if self.opts['logMode'][0]:
x = np.log10(x)
if self.opts['logMode'][1]:
@ -666,8 +663,21 @@ class PlotDataItem(GraphicsObject):
self.xDisp = self.yDisp = None
self.updateItems()
def _fourierTransform(self, x, y):
## Perform fourier transform. If x values are not sampled uniformly,
## then use interpolate.griddata to resample before taking fft.
dx = np.diff(x)
uniform = not np.any(np.abs(dx-dx[0]) > (abs(dx[0]) / 1000.))
if not uniform:
import scipy.interpolate as interp
x2 = np.linspace(x[0], x[-1], len(x))
y = interp.griddata(x, y, x2, method='linear')
x = x2
f = np.fft.fft(y) / len(y)
y = abs(f[1:len(f)/2])
dt = x[-1] - x[0]
x = np.linspace(0, 0.5*len(x)/dt, len(y))
return x, y
def dataType(obj):
if hasattr(obj, '__len__') and len(obj) == 0:

View File

@ -49,7 +49,13 @@ class ROI(GraphicsObject):
sigRegionChanged Emitted any time the position of the ROI changes,
including while it is being dragged by the user.
sigHoverEvent Emitted when the mouse hovers over the ROI.
sigClicked Emitted when the user clicks on the ROI
sigClicked Emitted when the user clicks on the ROI.
Note that clicking is disabled by default to prevent
stealing clicks from objects behind the ROI. To
enable clicking, call
roi.setAcceptedMouseButtons(QtCore.Qt.LeftButton).
See QtGui.QGraphicsItem documentation for more
details.
sigRemoveRequested Emitted when the user selects 'remove' from the
ROI's context menu (if available).
----------------------- ----------------------------------------------------

View File

@ -139,6 +139,7 @@ class ViewBox(GraphicsWidget):
self.rbScaleBox = QtGui.QGraphicsRectItem(0, 0, 1, 1)
self.rbScaleBox.setPen(fn.mkPen((255,255,100), width=1))
self.rbScaleBox.setBrush(fn.mkBrush(255,255,0,100))
self.rbScaleBox.setZValue(1e9)
self.rbScaleBox.hide()
self.addItem(self.rbScaleBox, ignoreBounds=True)
@ -792,12 +793,15 @@ class ViewBox(GraphicsWidget):
else:
overlap = min(sg.bottom(), vg.bottom()) - max(sg.top(), vg.top())
if overlap < min(vg.height()/3, sg.height()/3): ## if less than 1/3 of views overlap,
## then just replicate the view
## then just replicate the view
y1 = vr.top()
y2 = vr.bottom()
else: ## views overlap; line them up
upp = float(vr.height()) / vg.height()
y2 = vr.bottom() - (sg.y()-vg.y()) * upp
if self.yInverted():
y2 = vr.bottom() + (sg.bottom()-vg.bottom()) * upp
else:
y2 = vr.bottom() + (sg.top()-vg.top()) * upp
y1 = y2 - sg.height() * upp
self.enableAutoRange(ViewBox.YAxis, False)
self.setYRange(y1, y2, padding=0)

View File

@ -325,7 +325,8 @@ class QtProcess(Process):
GUI.
- A QTimer is also started on the parent process which polls for requests
from the child process. This allows Qt signals emitted within the child
process to invoke slots on the parent process and vice-versa.
process to invoke slots on the parent process and vice-versa. This can
be disabled using processRequests=False in the constructor.
Example::
@ -342,18 +343,29 @@ class QtProcess(Process):
def __init__(self, **kwds):
if 'target' not in kwds:
kwds['target'] = startQtEventLoop
self._processRequests = kwds.pop('processRequests', True)
Process.__init__(self, **kwds)
self.startEventTimer()
def startEventTimer(self):
from pyqtgraph.Qt import QtGui, QtCore ## avoid module-level import to keep bootstrap snappy.
self.timer = QtCore.QTimer()
app = QtGui.QApplication.instance()
if app is None:
raise Exception("Must create QApplication before starting QtProcess")
if self._processRequests:
app = QtGui.QApplication.instance()
if app is None:
raise Exception("Must create QApplication before starting QtProcess, or use QtProcess(processRequests=False)")
self.startRequestProcessing()
def startRequestProcessing(self, interval=0.01):
"""Start listening for requests coming from the child process.
This allows signals to be connected from the child process to the parent.
"""
self.timer.timeout.connect(self.processRequests)
self.timer.start(10)
self.timer.start(interval*1000)
def stopRequestProcessing(self):
self.timer.stop()
def processRequests(self):
try:
Process.processRequests(self)

View File

@ -167,7 +167,7 @@ class GLViewWidget(QtOpenGL.QGLWidget):
else:
items = item.childItems()
items.append(item)
items.sort(key=lambda x: x.depthValue())
items.sort(key=lambda a: a.depthValue())
for i in items:
if not i.visible():
continue

View File

@ -30,8 +30,9 @@ class GLLinePlotItem(GLGraphicsItem):
Arguments:
------------------------------------------------------------------------
pos (N,3) array of floats specifying point locations.
color tuple of floats (0.0-1.0) specifying
a color for the entire item.
color (N,4) array of floats (0.0-1.0) or
tuple of floats specifying
a single color for the entire item.
width float specifying line width
antialias enables smooth line drawing
==================== ==================================================
@ -71,9 +72,18 @@ class GLLinePlotItem(GLGraphicsItem):
self.setupGLState()
glEnableClientState(GL_VERTEX_ARRAY)
try:
glVertexPointerf(self.pos)
glColor4f(*self.color)
if isinstance(self.color, np.ndarray):
glEnableClientState(GL_COLOR_ARRAY)
glColorPointerf(self.color)
else:
if isinstance(self.color, QtGui.QColor):
glColor4f(*fn.glColor(self.color))
else:
glColor4f(*self.color)
glLineWidth(self.width)
#glPointSize(self.width)
@ -85,6 +95,7 @@ class GLLinePlotItem(GLGraphicsItem):
glDrawArrays(GL_LINE_STRIP, 0, int(self.pos.size / self.pos.shape[-1]))
finally:
glDisableClientState(GL_COLOR_ARRAY)
glDisableClientState(GL_VERTEX_ARRAY)

View File

@ -1,3 +1,4 @@
import OpenGL
from OpenGL.GL import *
from OpenGL.GL import shaders
import re
@ -218,6 +219,8 @@ class Shader(object):
if self.compiled is None:
try:
self.compiled = shaders.compileShader(self.code, self.shaderType)
except OpenGL.NullFunctionError:
raise Exception("This OpenGL implementation does not support shader programs; many features on pyqtgraph will not work.")
except RuntimeError as exc:
## Format compile errors a bit more nicely
if len(exc.args) == 3:

View File

@ -1,6 +1,7 @@
from pyqtgraph.Qt import QtCore, QtGui
from pyqtgraph.widgets.TreeWidget import TreeWidget
import os, weakref, re
from .ParameterItem import ParameterItem
#import functions as fn
@ -103,7 +104,7 @@ class ParameterTree(TreeWidget):
sel = self.selectedItems()
if len(sel) != 1:
sel = None
if self.lastSel is not None:
if self.lastSel is not None and isinstance(self.lastSel, ParameterItem):
self.lastSel.selected(False)
if sel is None:
self.lastSel = None

View File

@ -476,32 +476,16 @@ class ListParameterItem(WidgetParameterItem):
return w
def value(self):
#vals = self.param.opts['limits']
key = asUnicode(self.widget.currentText())
#if isinstance(vals, dict):
#return vals[key]
#else:
#return key
#print key, self.forward
return self.forward.get(key, None)
def setValue(self, val):
#vals = self.param.opts['limits']
#if isinstance(vals, dict):
#key = None
#for k,v in vals.iteritems():
#if v == val:
#key = k
#if key is None:
#raise Exception("Value '%s' not allowed." % val)
#else:
#key = unicode(val)
self.targetValue = val
if val not in self.reverse:
if val not in self.reverse[0]:
self.widget.setCurrentIndex(0)
else:
key = self.reverse[val]
key = self.reverse[1][self.reverse[0].index(val)]
ind = self.widget.findText(key)
self.widget.setCurrentIndex(ind)
@ -531,8 +515,8 @@ class ListParameter(Parameter):
itemClass = ListParameterItem
def __init__(self, **opts):
self.forward = OrderedDict() ## name: value
self.reverse = OrderedDict() ## value: name
self.forward = OrderedDict() ## {name: value, ...}
self.reverse = ([], []) ## ([value, ...], [name, ...])
## Parameter uses 'limits' option to define the set of allowed values
if 'values' in opts:
@ -547,23 +531,40 @@ class ListParameter(Parameter):
Parameter.setLimits(self, limits)
#print self.name(), self.value(), limits
if self.value() not in self.reverse and len(self.reverse) > 0:
self.setValue(list(self.reverse.keys())[0])
if len(self.reverse) > 0 and self.value() not in self.reverse[0]:
self.setValue(self.reverse[0][0])
#def addItem(self, name, value=None):
#if name in self.forward:
#raise Exception("Name '%s' is already in use for this parameter" % name)
#limits = self.opts['limits']
#if isinstance(limits, dict):
#limits = limits.copy()
#limits[name] = value
#self.setLimits(limits)
#else:
#if value is not None:
#raise Exception ## raise exception or convert to dict?
#limits = limits[:]
#limits.append(name)
## what if limits == None?
@staticmethod
def mapping(limits):
## Return forward and reverse mapping dictionaries given a limit specification
forward = OrderedDict() ## name: value
reverse = OrderedDict() ## value: name
## Return forward and reverse mapping objects given a limit specification
forward = OrderedDict() ## {name: value, ...}
reverse = ([], []) ## ([value, ...], [name, ...])
if isinstance(limits, dict):
for k, v in limits.items():
forward[k] = v
reverse[v] = k
reverse[0].append(v)
reverse[1].append(k)
else:
for v in limits:
n = asUnicode(v)
forward[n] = v
reverse[v] = n
reverse[0].append(v)
reverse[1].append(n)
return forward, reverse
registerParameterType('list', ListParameter, override=True)
@ -615,13 +616,20 @@ registerParameterType('action', ActionParameter, override=True)
class TextParameterItem(WidgetParameterItem):
def __init__(self, param, depth):
WidgetParameterItem.__init__(self, param, depth)
self.hideWidget = False
self.subItem = QtGui.QTreeWidgetItem()
self.addChild(self.subItem)
def treeWidgetChanged(self):
## TODO: fix so that superclass method can be called
## (WidgetParameter should just natively support this style)
#WidgetParameterItem.treeWidgetChanged(self)
self.treeWidget().setFirstItemColumnSpanned(self.subItem, True)
self.treeWidget().setItemWidget(self.subItem, 0, self.textBox)
self.setExpanded(True)
# for now, these are copied from ParameterItem.treeWidgetChanged
self.setHidden(not self.param.opts.get('visible', True))
self.setExpanded(self.param.opts.get('expanded', True))
def makeWidget(self):
self.textBox = QtGui.QTextEdit()

View File

@ -82,6 +82,7 @@ class GraphicsView(QtGui.QGraphicsView):
## This might help, but it's probably dangerous in the general case..
#self.setOptimizationFlag(self.DontSavePainterState, True)
self.setBackgroundRole(QtGui.QPalette.NoRole)
self.setBackground(background)
self.setFocusPolicy(QtCore.Qt.StrongFocus)
@ -138,12 +139,9 @@ class GraphicsView(QtGui.QGraphicsView):
self._background = background
if background == 'default':
background = pyqtgraph.getConfigOption('background')
if background is None:
self.setBackgroundRole(QtGui.QPalette.NoRole)
else:
brush = fn.mkBrush(background)
self.setBackgroundBrush(brush)
brush = fn.mkBrush(background)
self.setBackgroundBrush(brush)
def paintEvent(self, ev):
self.scene().prepareForPaint()
#print "GV: paint", ev.rect()

View File

@ -40,10 +40,12 @@ class PlotWidget(GraphicsView):
For all
other methods, use :func:`getPlotItem <pyqtgraph.PlotWidget.getPlotItem>`.
"""
def __init__(self, parent=None, **kargs):
"""When initializing PlotWidget, all keyword arguments except *parent* are passed
def __init__(self, parent=None, background='default', **kargs):
"""When initializing PlotWidget, *parent* and *background* are passed to
:func:`GraphicsWidget.__init__() <pyqtgraph.GraphicsWidget.__init__>`
and all others are passed
to :func:`PlotItem.__init__() <pyqtgraph.PlotItem.__init__>`."""
GraphicsView.__init__(self, parent)
GraphicsView.__init__(self, parent, background=background)
self.setSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding)
self.enableMouse(False)
self.plotItem = PlotItem(**kargs)

View File

@ -11,8 +11,8 @@ import numpy as np
class RawImageWidget(QtGui.QWidget):
"""
Widget optimized for very fast video display.
Generally using an ImageItem inside GraphicsView is fast enough,
but if you need even more performance, this widget is about as fast as it gets (but only in unscaled mode).
Generally using an ImageItem inside GraphicsView is fast enough.
On some systems this may provide faster video. See the VideoSpeedTest example for benchmarking.
"""
def __init__(self, parent=None, scaled=False):
"""
@ -59,26 +59,82 @@ class RawImageWidget(QtGui.QWidget):
p.end()
if HAVE_OPENGL:
from OpenGL.GL import *
class RawImageGLWidget(QtOpenGL.QGLWidget):
"""
Similar to RawImageWidget, but uses a GL widget to do all drawing.
Generally this will be about as fast as using GraphicsView + ImageItem,
but performance may vary on some platforms.
Perfomance varies between platforms; see examples/VideoSpeedTest for benchmarking.
"""
def __init__(self, parent=None, scaled=False):
QtOpenGL.QGLWidget.__init__(self, parent=None)
self.scaled = scaled
self.image = None
self.uploaded = False
self.smooth = False
self.opts = None
def setImage(self, img):
self.image = fn.makeQImage(img)
def setImage(self, img, *args, **kargs):
"""
img must be ndarray of shape (x,y), (x,y,3), or (x,y,4).
Extra arguments are sent to functions.makeARGB
"""
self.opts = (img, args, kargs)
self.image = None
self.uploaded = False
self.update()
def paintEvent(self, ev):
def initializeGL(self):
self.texture = glGenTextures(1)
def uploadTexture(self):
glEnable(GL_TEXTURE_2D)
glBindTexture(GL_TEXTURE_2D, self.texture)
if self.smooth:
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
else:
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER)
#glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_BORDER)
shape = self.image.shape
### Test texture dimensions first
#glTexImage2D(GL_PROXY_TEXTURE_2D, 0, GL_RGBA, shape[0], shape[1], 0, GL_RGBA, GL_UNSIGNED_BYTE, None)
#if glGetTexLevelParameteriv(GL_PROXY_TEXTURE_2D, 0, GL_TEXTURE_WIDTH) == 0:
#raise Exception("OpenGL failed to create 2D texture (%dx%d); too large for this hardware." % shape[:2])
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, shape[0], shape[1], 0, GL_RGBA, GL_UNSIGNED_BYTE, self.image.transpose((1,0,2)))
glDisable(GL_TEXTURE_2D)
def paintGL(self):
if self.image is None:
return
p = QtGui.QPainter(self)
p.drawImage(self.rect(), self.image)
p.end()
if self.opts is None:
return
img, args, kwds = self.opts
kwds['useRGBA'] = True
self.image, alpha = fn.makeARGB(img, *args, **kwds)
if not self.uploaded:
self.uploadTexture()
glViewport(0, 0, self.width(), self.height())
glEnable(GL_TEXTURE_2D)
glBindTexture(GL_TEXTURE_2D, self.texture)
glColor4f(1,1,1,1)
glBegin(GL_QUADS)
glTexCoord2f(0,0)
glVertex3f(-1,-1,0)
glTexCoord2f(1,0)
glVertex3f(1, -1, 0)
glTexCoord2f(1,1)
glVertex3f(1, 1, 0)
glTexCoord2f(0,1)
glVertex3f(-1, 1, 0)
glEnd()
glDisable(GL_TEXTURE_3D)