From 9c70d948aab24231ebe4395a8148c304f4d7d352 Mon Sep 17 00:00:00 2001 From: Luke Campagnola Date: Thu, 14 Feb 2013 14:22:30 -0500 Subject: [PATCH 01/11] Fixed ArrowItem auto-range --- pyqtgraph/graphicsItems/ArrowItem.py | 35 +++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/pyqtgraph/graphicsItems/ArrowItem.py b/pyqtgraph/graphicsItems/ArrowItem.py index 0c6c0718..dcede02a 100644 --- a/pyqtgraph/graphicsItems/ArrowItem.py +++ b/pyqtgraph/graphicsItems/ArrowItem.py @@ -84,8 +84,41 @@ class ArrowItem(QtGui.QGraphicsPathItem): def paint(self, p, *args): p.setRenderHint(QtGui.QPainter.Antialiasing) QtGui.QGraphicsPathItem.paint(self, p, *args) + + #p.setPen(fn.mkPen('r')) + #p.setBrush(fn.mkBrush(None)) + #p.drawRect(self.boundingRect()) def shape(self): #if not self.opts['pxMode']: #return QtGui.QGraphicsPathItem.shape(self) - return self.path \ No newline at end of file + return self.path + + ## dataBounds and pixelPadding methods are provided to ensure ViewBox can + ## properly auto-range + def dataBounds(self, ax, frac, orthoRange=None): + pw = 0 + pen = self.pen() + if not pen.isCosmetic(): + pw = pen.width() * 0.7072 + if self.opts['pxMode']: + return [0,0] + else: + br = self.boundingRect() + if ax == 0: + return [br.left()-pw, br.right()+pw] + else: + return [br.top()-pw, br.bottom()+pw] + + def pixelPadding(self): + pad = 0 + if self.opts['pxMode']: + br = self.boundingRect() + pad += (br.width()**2 + br.height()**2) ** 0.5 + pen = self.pen() + if pen.isCosmetic(): + pad += max(1, pen.width()) * 0.7072 + return pad + + + \ No newline at end of file From 783af1a9184dac2e8f15afd31b3ee8234e615407 Mon Sep 17 00:00:00 2001 From: Luke Campagnola Date: Fri, 15 Feb 2013 11:01:03 -0500 Subject: [PATCH 02/11] fix for python 2.6 compatibility --- pyqtgraph/opengl/MeshData.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyqtgraph/opengl/MeshData.py b/pyqtgraph/opengl/MeshData.py index 3e5938d1..170074b9 100644 --- a/pyqtgraph/opengl/MeshData.py +++ b/pyqtgraph/opengl/MeshData.py @@ -436,7 +436,7 @@ class MeshData(object): elif self._faceColorsIndexedByFaces is not None: names.append('_faceColorsIndexedByFaces') - state = {n:getattr(self, n) for n in names} + state = dict([(n,getattr(self, n)) for n in names]) return pickle.dumps(state) def restore(self, state): From 86861b5a061b0733a56a23fcacf9624216f82098 Mon Sep 17 00:00:00 2001 From: Luke Campagnola Date: Fri, 15 Feb 2013 15:22:05 -0500 Subject: [PATCH 03/11] Fixed dock dragging on pyside Added imageview.setImage argument documentation --- pyqtgraph/dockarea/Dock.py | 14 ++++++++++++++ pyqtgraph/dockarea/DockArea.py | 14 ++++++++++++++ pyqtgraph/imageview/ImageView.py | 7 ++++++- 3 files changed, 34 insertions(+), 1 deletion(-) diff --git a/pyqtgraph/dockarea/Dock.py b/pyqtgraph/dockarea/Dock.py index 35781535..e07ae6a7 100644 --- a/pyqtgraph/dockarea/Dock.py +++ b/pyqtgraph/dockarea/Dock.py @@ -186,6 +186,7 @@ class Dock(QtGui.QWidget, DockDrop): def startDrag(self): + print('startDrag') self.drag = QtGui.QDrag(self) mime = QtCore.QMimeData() #mime.setPlainText("asd") @@ -212,6 +213,19 @@ class Dock(QtGui.QWidget, DockDrop): def __repr__(self): return "" % (self.name(), self.stretch()) + ## PySide bug: We need to explicitly redefine these methods + ## or else drag/drop events will not be delivered. + def dragEnterEvent(self, *args): + DockDrop.dragEnterEvent(self, *args) + + def dragMoveEvent(self, *args): + DockDrop.dragMoveEvent(self, *args) + + def dragLeaveEvent(self, *args): + DockDrop.dragLeaveEvent(self, *args) + + def dropEvent(self, *args): + DockDrop.dropEvent(self, *args) class DockLabel(VerticalLabel): diff --git a/pyqtgraph/dockarea/DockArea.py b/pyqtgraph/dockarea/DockArea.py index 78d512f3..50769ce6 100644 --- a/pyqtgraph/dockarea/DockArea.py +++ b/pyqtgraph/dockarea/DockArea.py @@ -293,5 +293,19 @@ class DockArea(Container, QtGui.QWidget, DockDrop): self.home.removeTempArea(self) #self.close() + ## PySide bug: We need to explicitly redefine these methods + ## or else drag/drop events will not be delivered. + def dragEnterEvent(self, *args): + DockDrop.dragEnterEvent(self, *args) + + def dragMoveEvent(self, *args): + DockDrop.dragMoveEvent(self, *args) + + def dragLeaveEvent(self, *args): + DockDrop.dragLeaveEvent(self, *args) + + def dropEvent(self, *args): + DockDrop.dropEvent(self, *args) + \ No newline at end of file diff --git a/pyqtgraph/imageview/ImageView.py b/pyqtgraph/imageview/ImageView.py index 5c6573e3..f0c13a60 100644 --- a/pyqtgraph/imageview/ImageView.py +++ b/pyqtgraph/imageview/ImageView.py @@ -205,7 +205,12 @@ class ImageView(QtGui.QWidget): *axes* Dictionary indicating the interpretation for each axis. This is only needed to override the default guess. Format is:: - {'t':0, 'x':1, 'y':2, 'c':3}; + {'t':0, 'x':1, 'y':2, 'c':3}; + + *pos* Change the position of the displayed image + *scale* Change the scale of the displayed image + *transform* Set the transform of the dispalyed image. This option overrides *pos* + and *scale*. ============== ======================================================================= """ prof = debug.Profiler('ImageView.setImage', disabled=True) From 412e1d2ec8c907430a1e2e21d4ceec1c26997213 Mon Sep 17 00:00:00 2001 From: Luke Campagnola Date: Wed, 20 Feb 2013 11:13:50 -0500 Subject: [PATCH 04/11] doc updates ViewBox: made padding more consistent for all auto-ranging methods, deprecated autoRange(item=) in favor of autoRange(items=) --- doc/source/how_to_use.rst | 2 +- doc/source/qtcrashcourse.rst | 10 +++- examples/ImageView.py | 16 +++++-- examples/PlotWidget.py | 1 + pyqtgraph/PlotData.py | 2 +- pyqtgraph/graphicsItems/ViewBox/ViewBox.py | 55 +++++++++++++++------- 6 files changed, 62 insertions(+), 24 deletions(-) diff --git a/doc/source/how_to_use.rst b/doc/source/how_to_use.rst index 53a3d2b0..0e00af59 100644 --- a/doc/source/how_to_use.rst +++ b/doc/source/how_to_use.rst @@ -17,7 +17,7 @@ Pyqtgraph makes it very easy to visualize data from the command line. Observe:: import pyqtgraph as pg pg.plot(data) # data can be a list of values or a numpy array -The example above would open a window displaying a line plot of the data given. The call to :func:`pg.plot ` returns a handle to the :class:`plot widget ` that is created, allowing more data to be added to the same window. +The example above would open a window displaying a line plot of the data given. The call to :func:`pg.plot ` returns a handle to the :class:`plot widget ` that is created, allowing more data to be added to the same window. **Note:** interactive plotting from the python prompt is only available with PyQt; PySide does not run the Qt event loop while the interactive prompt is running. If you wish to use pyqtgraph interactively with PySide, see the 'console' :ref:`example `. Further examples:: diff --git a/doc/source/qtcrashcourse.rst b/doc/source/qtcrashcourse.rst index ca2da797..23a561b9 100644 --- a/doc/source/qtcrashcourse.rst +++ b/doc/source/qtcrashcourse.rst @@ -66,6 +66,12 @@ Signals, Slots, and Events [ to be continued.. please post a request on the pyqtgraph forum if you'd like to read more ] +Qt detects and reacts to user interaction by executing its *event loop*. + + - what happens in the event loop? + - when do I need to use QApplication.exec_() ? + - what control do I have over event loop execution? (QApplication.processEvents) + GraphicsView and GraphicsItems ------------------------------ @@ -79,8 +85,8 @@ Mouse and Keyboard Input ------------------------ -QTimer, the Event Loop, and Multi-Threading -------------------------------------------- +QTimer, Multi-Threading +----------------------- Multi-threading vs Multi-processing in Qt diff --git a/examples/ImageView.py b/examples/ImageView.py index 5edae00b..f11ce0f7 100644 --- a/examples/ImageView.py +++ b/examples/ImageView.py @@ -1,4 +1,15 @@ # -*- coding: utf-8 -*- +""" +This example demonstrates the use of ImageView, which is a high-level widget for +displaying and analyzing 2D and 3D data. ImageView provides: + + 1. A zoomable region (ViewBox) for displaying the image + 2. A combination histogram and gradient editor (HistogramLUTItem) for + controlling the visual appearance of the image + 3. A timeline for selecting the currently displayed frame (for 3D data only). + 4. Tools for very basic analysis of image data (see ROI and Norm buttons) + +""" ## Add path to library (just for examples; you do not need this) import initExample @@ -22,9 +33,6 @@ img = img[np.newaxis,:,:] decay = np.exp(-np.linspace(0,0.3,100))[:,np.newaxis,np.newaxis] data = np.random.normal(size=(100, 200, 200)) data += img * decay - -#for i in range(data.shape[0]): - #data[i] += 10*exp(-(2.*i)/data.shape[0]) data += 2 ## Add time-varying signal @@ -37,7 +45,7 @@ sig = sig[:,np.newaxis,np.newaxis] * 3 data[:,50:60,50:60] += sig -## Display the data +## Display the data and assign each frame a time value from 1.0 to 3.0 imv.setImage(data, xvals=np.linspace(1., 3., data.shape[0])) ## Start Qt event loop unless running in interactive mode. diff --git a/examples/PlotWidget.py b/examples/PlotWidget.py index 3cca8f7a..2aa118f2 100644 --- a/examples/PlotWidget.py +++ b/examples/PlotWidget.py @@ -66,6 +66,7 @@ for i in range(0, 5): ## Test large numbers curve = pw3.plot(np.random.normal(size=100)*1e0, clickable=True) +curve.curve.setClickable(True) curve.setPen('w') ## white pen curve.setShadowPen(pg.mkPen((70,70,30), width=6, cosmetic=True)) diff --git a/pyqtgraph/PlotData.py b/pyqtgraph/PlotData.py index 18531c14..0bf13ca8 100644 --- a/pyqtgraph/PlotData.py +++ b/pyqtgraph/PlotData.py @@ -22,7 +22,7 @@ class PlotData(object): self.maxVals = {} ## cache for max/min self.minVals = {} - def addFields(self, fields): + def addFields(self, **fields): for f in fields: if f not in self.fields: self.fields[f] = None diff --git a/pyqtgraph/graphicsItems/ViewBox/ViewBox.py b/pyqtgraph/graphicsItems/ViewBox/ViewBox.py index ce1d61f9..b562132c 100644 --- a/pyqtgraph/graphicsItems/ViewBox/ViewBox.py +++ b/pyqtgraph/graphicsItems/ViewBox/ViewBox.py @@ -336,7 +336,7 @@ class ViewBox(GraphicsWidget): print("make qrectf failed:", self.state['targetRange']) raise - def setRange(self, rect=None, xRange=None, yRange=None, padding=0.02, update=True, disableAutoRange=True): + def setRange(self, rect=None, xRange=None, yRange=None, padding=None, update=True, disableAutoRange=True): """ Set the visible range of the ViewBox. Must specify at least one of *range*, *xRange*, or *yRange*. @@ -347,7 +347,8 @@ class ViewBox(GraphicsWidget): *xRange* (min,max) The range that should be visible along the x-axis. *yRange* (min,max) The range that should be visible along the y-axis. *padding* (float) Expand the view by a fraction of the requested range. - By default, this value is 0.02 (2%) + By default, this value is set between 0.02 and 0.1 depending on + the size of the ViewBox. ============= ===================================================================== """ @@ -367,6 +368,10 @@ class ViewBox(GraphicsWidget): changed = [False, False] for ax, range in changes.items(): + if padding is None: + xpad = self.suggestPadding(ax) + else: + xpad = padding mn = min(range) mx = max(range) if mn == mx: ## If we requested 0 range, try to preserve previous scale. Otherwise just pick an arbitrary scale. @@ -375,11 +380,11 @@ class ViewBox(GraphicsWidget): dy = 1 mn -= dy*0.5 mx += dy*0.5 - padding = 0.0 + xpad = 0.0 if any(np.isnan([mn, mx])) or any(np.isinf([mn, mx])): raise Exception("Not setting range [%s, %s]" % (str(mn), str(mx))) - p = (mx-mn) * padding + p = (mx-mn) * xpad mn -= p mx += p @@ -412,34 +417,53 @@ class ViewBox(GraphicsWidget): elif changed[1] and self.state['autoVisibleOnly'][0]: self.updateAutoRange() - def setYRange(self, min, max, padding=0.02, update=True): + def setYRange(self, min, max, padding=None, update=True): """ Set the visible Y range of the view to [*min*, *max*]. The *padding* argument causes the range to be set larger by the fraction specified. + (by default, this value is between 0.02 and 0.1 depending on the size of the ViewBox) """ self.setRange(yRange=[min, max], update=update, padding=padding) - def setXRange(self, min, max, padding=0.02, update=True): + def setXRange(self, min, max, padding=None, update=True): """ Set the visible X range of the view to [*min*, *max*]. The *padding* argument causes the range to be set larger by the fraction specified. + (by default, this value is between 0.02 and 0.1 depending on the size of the ViewBox) """ self.setRange(xRange=[min, max], update=update, padding=padding) - def autoRange(self, padding=0.02, item=None): + def autoRange(self, padding=None, items=None, 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. + + =========== ============================================================ + Arguments + padding The fraction of the total data range to add on to the final + visible range. By default, this value is set between 0.02 + and 0.1 depending on the size of the ViewBox. + items If specified, this is a list of items to consider when + determining the visible range. + =========== ============================================================ """ if item is None: - bounds = self.childrenBoundingRect() + bounds = self.childrenBoundingRect(items=items) else: + print "Warning: ViewBox.autoRange(item=__) is deprecated. Use 'items' argument instead." bounds = self.mapFromItemToView(item, item.boundingRect()).boundingRect() if bounds is not None: self.setRange(bounds, padding=padding) + def suggestPadding(self, axis): + l = self.width() if axis==0 else self.height() + if l > 0: + padding = np.clip(1./(l**0.5), 0.02, 0.1) + else: + padding = 0.02 + return padding def scaleBy(self, s, center=None): """ @@ -577,12 +601,10 @@ class ViewBox(GraphicsWidget): w2 = (targetRect[ax][1]-targetRect[ax][0]) / 2. childRange[ax] = [x-w2, x+w2] else: - l = self.width() if ax==0 else self.height() - if l > 0: - padding = np.clip(1./(l**0.5), 0.02, 0.1) - wp = (xr[1] - xr[0]) * padding - childRange[ax][0] -= wp - childRange[ax][1] += wp + padding = self.suggestPadding(ax) + wp = (xr[1] - xr[0]) * padding + childRange[ax][0] -= wp + childRange[ax][1] += wp targetRect[ax] = childRange[ax] args['xRange' if ax == 0 else 'yRange'] = targetRect[ax] if len(args) == 0: @@ -995,13 +1017,14 @@ class ViewBox(GraphicsWidget): - def childrenBounds(self, frac=None, orthoRange=(None,None)): + def childrenBounds(self, frac=None, orthoRange=(None,None), items=None): """Return the bounding range of all children. [[xmin, xmax], [ymin, ymax]] Values may be None if there are no specific bounds for an axis. """ prof = debug.Profiler('updateAutoRange', disabled=True) - items = self.addedItems + if items is None: + items = self.addedItems ## measure pixel dimensions in view box px, py = [v.length() if v is not None else 0 for v in self.childGroup.pixelVectors()] From 8e5133c87398249722546d58e68a9f0378728c5a Mon Sep 17 00:00:00 2001 From: Luke Campagnola <> Date: Sun, 24 Feb 2013 11:32:35 -0500 Subject: [PATCH 05/11] minor fixes from acq4 --- pyqtgraph/dockarea/DockArea.py | 12 ++++++++++-- pyqtgraph/flowchart/Flowchart.py | 8 -------- pyqtgraph/flowchart/library/Data.py | 3 +-- pyqtgraph/flowchart/library/Display.py | 2 +- 4 files changed, 12 insertions(+), 13 deletions(-) diff --git a/pyqtgraph/dockarea/DockArea.py b/pyqtgraph/dockarea/DockArea.py index 78d512f3..811bdd7a 100644 --- a/pyqtgraph/dockarea/DockArea.py +++ b/pyqtgraph/dockarea/DockArea.py @@ -33,12 +33,13 @@ class DockArea(Container, QtGui.QWidget, DockDrop): def type(self): return "top" - def addDock(self, dock, position='bottom', relativeTo=None): + def addDock(self, dock=None, position='bottom', relativeTo=None, **kwds): """Adds a dock to this area. =========== ================================================================= Arguments: - dock The new Dock object to add. + dock The new Dock object to add. If None, then a new Dock will be + created. position 'bottom', 'top', 'left', 'right', 'over', or 'under' relativeTo If relativeTo is None, then the new Dock is added to fill an entire edge of the window. If relativeTo is another Dock, then @@ -46,7 +47,12 @@ class DockArea(Container, QtGui.QWidget, DockDrop): configuration for 'over' and 'under'). =========== ================================================================= + All extra keyword arguments are passed to Dock.__init__() if *dock* is + None. """ + if dock is None: + dock = Dock(**kwds) + ## Determine the container to insert this dock into. ## If there is no neighbor, then the container is the top. @@ -100,6 +106,8 @@ class DockArea(Container, QtGui.QWidget, DockDrop): dock.area = self self.docks[dock.name()] = dock + return dock + def moveDock(self, dock, position, neighbor): """ Move an existing Dock to a new location. diff --git a/pyqtgraph/flowchart/Flowchart.py b/pyqtgraph/flowchart/Flowchart.py index 12d6a97c..a68cf542 100644 --- a/pyqtgraph/flowchart/Flowchart.py +++ b/pyqtgraph/flowchart/Flowchart.py @@ -206,17 +206,12 @@ class Flowchart(Node): item = node.graphicsItem() item.setZValue(self.nextZVal*2) self.nextZVal += 1 - #item.setParentItem(self.chartGraphicsItem()) self.viewBox.addItem(item) - #item.setPos(pos2.x(), pos2.y()) item.moveBy(*pos) self._nodes[name] = node self.widget().addNode(node) - #QtCore.QObject.connect(node, QtCore.SIGNAL('closed'), self.nodeClosed) node.sigClosed.connect(self.nodeClosed) - #QtCore.QObject.connect(node, QtCore.SIGNAL('renamed'), self.nodeRenamed) node.sigRenamed.connect(self.nodeRenamed) - #QtCore.QObject.connect(node, QtCore.SIGNAL('outputChanged'), self.nodeOutputChanged) node.sigOutputChanged.connect(self.nodeOutputChanged) def removeNode(self, node): @@ -225,17 +220,14 @@ class Flowchart(Node): def nodeClosed(self, node): del self._nodes[node.name()] self.widget().removeNode(node) - #QtCore.QObject.disconnect(node, QtCore.SIGNAL('closed'), self.nodeClosed) try: node.sigClosed.disconnect(self.nodeClosed) except TypeError: pass - #QtCore.QObject.disconnect(node, QtCore.SIGNAL('renamed'), self.nodeRenamed) try: node.sigRenamed.disconnect(self.nodeRenamed) except TypeError: pass - #QtCore.QObject.disconnect(node, QtCore.SIGNAL('outputChanged'), self.nodeOutputChanged) try: node.sigOutputChanged.disconnect(self.nodeOutputChanged) except TypeError: diff --git a/pyqtgraph/flowchart/library/Data.py b/pyqtgraph/flowchart/library/Data.py index 1c612e08..cbef848a 100644 --- a/pyqtgraph/flowchart/library/Data.py +++ b/pyqtgraph/flowchart/library/Data.py @@ -152,7 +152,7 @@ class RegionSelectNode(CtrlNode): #print " new rgn:", c, region #self.items[c].setYRange([0., 0.2], relative=True) - if self.selected.isConnected(): + if self['selected'].isConnected(): if data is None: sliced = None elif (hasattr(data, 'implements') and data.implements('MetaArray')): @@ -219,7 +219,6 @@ class EvalNode(Node): text = str(self.text.toPlainText()) if text != self.lastText: self.lastText = text - print("eval node update") self.update() return QtGui.QTextEdit.focusOutEvent(self.text, ev) diff --git a/pyqtgraph/flowchart/library/Display.py b/pyqtgraph/flowchart/library/Display.py index 7979d7a7..9068c0ec 100644 --- a/pyqtgraph/flowchart/library/Display.py +++ b/pyqtgraph/flowchart/library/Display.py @@ -21,7 +21,7 @@ class PlotWidgetNode(Node): self.items = {} def disconnected(self, localTerm, remoteTerm): - if localTerm is self.In and remoteTerm in self.items: + if localTerm is self['In'] and remoteTerm in self.items: self.plot.removeItem(self.items[remoteTerm]) del self.items[remoteTerm] From 3c6081f3a45b233ef6e1c79b7be71878f7b10b58 Mon Sep 17 00:00:00 2001 From: Luke Campagnola Date: Sun, 24 Feb 2013 11:58:39 -0500 Subject: [PATCH 06/11] fixed ScatterPlotItem.setSize and setData --- pyqtgraph/graphicsItems/ScatterPlotItem.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/pyqtgraph/graphicsItems/ScatterPlotItem.py b/pyqtgraph/graphicsItems/ScatterPlotItem.py index 18d9ebf3..a69131ef 100644 --- a/pyqtgraph/graphicsItems/ScatterPlotItem.py +++ b/pyqtgraph/graphicsItems/ScatterPlotItem.py @@ -495,8 +495,8 @@ class ScatterPlotItem(GraphicsObject): if isinstance(size, np.ndarray) or isinstance(size, list): sizes = size - if kargs['mask'] is not None: - sizes = sizes[kargs['mask']] + if mask is not None: + sizes = sizes[mask] if len(sizes) != len(dataSet): raise Exception("Number of sizes does not match number of points (%d != %d)" % (len(sizes), len(dataSet))) dataSet['size'] = sizes @@ -508,13 +508,13 @@ class ScatterPlotItem(GraphicsObject): if update: self.updateSpots(dataSet) - def setPointData(self, data, dataSet=None): + def setPointData(self, data, dataSet=None, mask=None): if dataSet is None: dataSet = self.data if isinstance(data, np.ndarray) or isinstance(data, list): - if kargs['mask'] is not None: - data = data[kargs['mask']] + if mask is not None: + data = data[mask] if len(data) != len(dataSet): raise Exception("Length of meta data does not match number of points (%d != %d)" % (len(data), len(dataSet))) From 1d2d7be733f435f60e650ac2a2d15d9eca446c4d Mon Sep 17 00:00:00 2001 From: Luke Campagnola Date: Sun, 24 Feb 2013 14:31:11 -0500 Subject: [PATCH 07/11] When exporting, prefer to select PlotItem rather than ViewBox if possible CSV exporter gets 'precision' option --- pyqtgraph/GraphicsScene/exportDialog.py | 4 ++++ pyqtgraph/exporters/CSVExporter.py | 12 +++++------- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/pyqtgraph/GraphicsScene/exportDialog.py b/pyqtgraph/GraphicsScene/exportDialog.py index 73a8c83f..436d5e42 100644 --- a/pyqtgraph/GraphicsScene/exportDialog.py +++ b/pyqtgraph/GraphicsScene/exportDialog.py @@ -34,8 +34,12 @@ class ExportDialog(QtGui.QWidget): def show(self, item=None): if item is not None: + ## Select next exportable parent of the item originally clicked on while not isinstance(item, pg.ViewBox) and not isinstance(item, pg.PlotItem) and item is not None: item = item.parentItem() + ## if this is a ViewBox inside a PlotItem, select the parent instead. + if isinstance(item, pg.ViewBox) and isinstance(item.parentItem(), pg.PlotItem): + item = item.parentItem() self.updateItemList(select=item) self.setVisible(True) self.activateWindow() diff --git a/pyqtgraph/exporters/CSVExporter.py b/pyqtgraph/exporters/CSVExporter.py index 629b2789..0439fc35 100644 --- a/pyqtgraph/exporters/CSVExporter.py +++ b/pyqtgraph/exporters/CSVExporter.py @@ -14,6 +14,7 @@ class CSVExporter(Exporter): Exporter.__init__(self, item) self.params = Parameter(name='params', type='group', children=[ {'name': 'separator', 'type': 'list', 'value': 'comma', 'values': ['comma', 'tab']}, + {'name': 'precision', 'type': 'int', 'value': 10, 'limits': [0, None]}, ]) def parameters(self): @@ -42,18 +43,15 @@ class CSVExporter(Exporter): fd.write(sep.join(header) + '\n') i = 0 - while True: - done = True + numFormat = '%%0.%dg' % self.params['precision'] + numRows = reduce(max, [len(d[0]) for d in data]) + for i in range(numRows): for d in data: if i < len(d[0]): - fd.write('%g%s%g%s'%(d[0][i], sep, d[1][i], sep)) - done = False + fd.write(numFormat % d[0][i] + sep + numFormat % d[1][i] + sep) else: fd.write(' %s %s' % (sep, sep)) fd.write('\n') - if done: - break - i += 1 fd.close() From d33fe054797bab1b1f36b44ac7911bcf3a393330 Mon Sep 17 00:00:00 2001 From: Luke Campagnola <> Date: Sun, 24 Feb 2013 15:24:42 -0500 Subject: [PATCH 08/11] fixed python2.x print statements --- examples/multiplePlotSpeedTest.py | 6 +++--- pyqtgraph/graphicsItems/ViewBox/ViewBox.py | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/multiplePlotSpeedTest.py b/examples/multiplePlotSpeedTest.py index bc54bb51..cea59a35 100644 --- a/examples/multiplePlotSpeedTest.py +++ b/examples/multiplePlotSpeedTest.py @@ -39,7 +39,7 @@ def plot(): #plt.addItem(item) dt = pg.ptime.time() - start - print "Create plots took: %0.3fms" % (dt*1000) + print("Create plots took: %0.3fms" % (dt*1000)) ## Plot and clear 5 times, printing the time it took for i in range(5): @@ -72,7 +72,7 @@ def fastPlot(): plt.addItem(item) dt = pg.ptime.time() - start - print "Create plots took: %0.3fms" % (dt*1000) + print("Create plots took: %0.3fms" % (dt*1000)) ## Plot and clear 5 times, printing the time it took @@ -82,7 +82,7 @@ if hasattr(pg, 'arrayToQPath'): fastPlot() app.processEvents() else: - print "Skipping fast tests--arrayToQPath function is missing." + print("Skipping fast tests--arrayToQPath function is missing.") plt.autoRange() diff --git a/pyqtgraph/graphicsItems/ViewBox/ViewBox.py b/pyqtgraph/graphicsItems/ViewBox/ViewBox.py index b562132c..87b687bd 100644 --- a/pyqtgraph/graphicsItems/ViewBox/ViewBox.py +++ b/pyqtgraph/graphicsItems/ViewBox/ViewBox.py @@ -451,7 +451,7 @@ class ViewBox(GraphicsWidget): if item is None: bounds = self.childrenBoundingRect(items=items) else: - print "Warning: ViewBox.autoRange(item=__) is deprecated. Use 'items' argument instead." + print("Warning: ViewBox.autoRange(item=__) is deprecated. Use 'items' argument instead.") bounds = self.mapFromItemToView(item, item.boundingRect()).boundingRect() if bounds is not None: From 491aee0fe2873c10bd1ce1a2297920491a7b9568 Mon Sep 17 00:00:00 2001 From: Luke Campagnola Date: Sun, 24 Feb 2013 23:09:03 -0500 Subject: [PATCH 09/11] python3 fixes cleaned up examples --- examples/Arrow.py | 14 +++++++------ examples/CLIexample.py | 17 +++++++++------ examples/ColorButton.py | 6 ++++-- examples/ConsoleWidget.py | 7 +++++++ examples/DataSlicing.py | 9 ++++++++ examples/DataTreeWidget.py | 3 +-- examples/Draw.py | 7 +++++++ examples/ErrorBarItem.py | 1 + examples/Flowchart.py | 1 + examples/FlowchartCustomNode.py | 1 + examples/GLImageItem.py | 7 +++++++ examples/GLIsosurface.py | 8 ++++--- examples/GLLinePlotItem.py | 5 +++++ examples/GLMeshItem.py | 2 +- examples/GLScatterPlotItem.py | 6 ++++++ examples/GLSurfacePlot.py | 1 + examples/GLViewWidget.py | 5 +++++ examples/GLVolumeItem.py | 7 ++++++- examples/GLshaders.py | 5 +++-- examples/GradientWidget.py | 6 ++++++ examples/GraphItem.py | 3 ++- examples/GraphicsLayout.py | 8 +++++++ examples/HistogramLUT.py | 5 +++++ examples/ImageItem.py | 16 +++++++------- examples/ImageView.py | 1 + examples/JoystickButton.py | 7 +++++-- examples/Legend.py | 6 +++++- examples/LogPlotTest.py | 13 ++++-------- examples/MultiPlotSpeedTest.py | 5 +++++ examples/PlotAutoRange.py | 7 ++++--- examples/PlotSpeedTest.py | 8 ++++--- examples/PlotWidget.py | 7 +++++++ examples/Plotting.py | 11 +++++----- examples/ROIExamples.py | 7 +++++++ examples/RemoteGraphicsView.py | 11 ++++++++-- examples/RemoteSpeedTest.py | 1 + examples/ScatterPlot.py | 7 +++++++ examples/ScatterPlotSpeedTest.py | 9 ++++++++ examples/SpinBox.py | 10 +++++++++ examples/TreeWidget.py | 5 +++++ examples/VideoSpeedTest.py | 1 + examples/ViewBox.py | 19 +++++++++-------- examples/__main__.py | 5 ++++- examples/crosshair.py | 10 ++++++++- examples/customGraphicsItem.py | 21 ++++++++++++++++++- examples/customPlot.py | 9 ++++---- examples/dockarea.py | 1 + examples/histogram.py | 3 ++- examples/isocurve.py | 1 + examples/linkedViews.py | 11 +++++----- examples/logAxis.py | 5 ++++- examples/multiplePlotSpeedTest.py | 6 +++--- examples/parametertree.py | 1 + examples/template.py | 8 +++++++ examples/text.py | 9 +++++++- pyqtgraph/configfile.py | 4 ++-- pyqtgraph/flowchart/FlowchartTemplate.ui | 2 +- pyqtgraph/flowchart/FlowchartTemplate_pyqt.py | 6 +++--- .../flowchart/FlowchartTemplate_pyside.py | 6 +++--- pyqtgraph/graphicsItems/ViewBox/ViewBox.py | 2 +- 60 files changed, 302 insertions(+), 93 deletions(-) diff --git a/examples/Arrow.py b/examples/Arrow.py index 665bbab1..2cbff113 100644 --- a/examples/Arrow.py +++ b/examples/Arrow.py @@ -1,11 +1,12 @@ # -*- coding: utf-8 -*- +""" +Display an animated arrowhead following a curve. +This example uses the CurveArrow class, which is a combination +of ArrowItem and CurvePoint. -## Display an animated arrowhead following a curve. -## This example uses the CurveArrow class, which is a combination -## of ArrowItem and CurvePoint. -## -## To place a static arrow anywhere in a scene, use ArrowItem. -## To attach other types of item to a curve, use CurvePoint. +To place a static arrow anywhere in a scene, use ArrowItem. +To attach other types of item to a curve, use CurvePoint. +""" import initExample ## Add path to library (just for examples; you do not need this) @@ -21,6 +22,7 @@ cw = pg.GraphicsLayoutWidget() w.show() w.resize(400,600) w.setCentralWidget(cw) +w.setWindowTitle('pyqtgraph example: Arrow') p = cw.addPlot(row=0, col=0) p2 = cw.addPlot(row=1, col=0) diff --git a/examples/CLIexample.py b/examples/CLIexample.py index a412698f..f32cf81c 100644 --- a/examples/CLIexample.py +++ b/examples/CLIexample.py @@ -1,21 +1,26 @@ +""" +Display a plot and an image with minimal setup. + +pg.plot() and pg.image() are indended to be used from an interactive prompt +to allow easy data inspection (but note that PySide unfortunately does not +call the Qt event loop while the interactive prompt is running, in this case +it is necessary to call QApplication.exec_() to make the windows appear). +""" import initExample ## Add path to library (just for examples; you do not need this) -from pyqtgraph.Qt import QtGui, QtCore + import numpy as np import pyqtgraph as pg -app = QtGui.QApplication([]) - - data = np.random.normal(size=1000) pg.plot(data, title="Simplest possible plotting example") data = np.random.normal(size=(500,500)) -pg.show(data, title="Simplest possible image example") +pg.image(data, title="Simplest possible image example") ## Start Qt event loop unless running in interactive mode or using pyside. if __name__ == '__main__': import sys if sys.flags.interactive != 1 or not hasattr(QtCore, 'PYQT_VERSION'): - app.exec_() + pg.QtGui.QApplication.exec_() diff --git a/examples/ColorButton.py b/examples/ColorButton.py index 4199c8bc..321ee735 100644 --- a/examples/ColorButton.py +++ b/examples/ColorButton.py @@ -1,11 +1,12 @@ # -*- coding: utf-8 -*- -import initExample ## Add path to library (just for examples; you do not need this) - """ Simple example demonstrating a button which displays a colored rectangle and allows the user to select a new color by clicking on the button. """ +import initExample ## Add path to library (just for examples; you do not need this) + + import pyqtgraph as pg from pyqtgraph.Qt import QtCore, QtGui import numpy as np @@ -15,6 +16,7 @@ win = QtGui.QMainWindow() btn = pg.ColorButton() win.setCentralWidget(btn) win.show() +win.setWindowTitle('pyqtgraph example: ColorButton') def change(btn): print("change", btn.color()) diff --git a/examples/ConsoleWidget.py b/examples/ConsoleWidget.py index 52fc022e..8234269d 100644 --- a/examples/ConsoleWidget.py +++ b/examples/ConsoleWidget.py @@ -1,4 +1,10 @@ # -*- coding: utf-8 -*- +""" +ConsoleWidget is used to allow execution of user-supplied python commands +in an application. It also includes a command history and functionality for trapping +and inspecting stack traces. + +""" import initExample ## Add path to library (just for examples; you do not need this) import pyqtgraph as pg @@ -21,6 +27,7 @@ Go, play. """ c = pyqtgraph.console.ConsoleWidget(namespace=namespace, text=text) c.show() +c.setWindowTitle('pyqtgraph example: ConsoleWidget') ## Start Qt event loop unless running in interactive mode or using pyside. if __name__ == '__main__': diff --git a/examples/DataSlicing.py b/examples/DataSlicing.py index 6b83a592..bd201832 100644 --- a/examples/DataSlicing.py +++ b/examples/DataSlicing.py @@ -1,4 +1,12 @@ # -*- coding: utf-8 -*- +""" +Demonstrate a simple data-slicing task: given 3D data (displayed at top), select +a 2D plane and interpolate data along that plane to generate a slice image +(displayed at bottom). + + +""" + ## Add path to library (just for examples; you do not need this) import initExample @@ -12,6 +20,7 @@ app = QtGui.QApplication([]) ## Create window with two ImageView widgets win = QtGui.QMainWindow() win.resize(800,800) +win.setWindowTitle('pyqtgraph example: DataSlicing') cw = QtGui.QWidget() win.setCentralWidget(cw) l = QtGui.QGridLayout() diff --git a/examples/DataTreeWidget.py b/examples/DataTreeWidget.py index 01c66b2a..8365db2a 100644 --- a/examples/DataTreeWidget.py +++ b/examples/DataTreeWidget.py @@ -4,8 +4,6 @@ Simple use of DataTreeWidget to display a structure of nested dicts, lists, and arrays """ - - import initExample ## Add path to library (just for examples; you do not need this) import pyqtgraph as pg @@ -26,6 +24,7 @@ d = { tree = pg.DataTreeWidget(data=d) tree.show() +tree.setWindowTitle('pyqtgraph example: DataTreeWidget') tree.resize(600,600) diff --git a/examples/Draw.py b/examples/Draw.py index 2abf0280..cc137db3 100644 --- a/examples/Draw.py +++ b/examples/Draw.py @@ -1,4 +1,10 @@ # -*- coding: utf-8 -*- +""" +Demonstrate ability of ImageItem to be used as a canvas for painting with +the mouse. + +""" + import initExample ## Add path to library (just for examples; you do not need this) @@ -12,6 +18,7 @@ app = QtGui.QApplication([]) w = pg.GraphicsView() w.show() w.resize(800,800) +w.setWindowTitle('pyqtgraph example: Draw') view = pg.ViewBox() w.setCentralItem(view) diff --git a/examples/ErrorBarItem.py b/examples/ErrorBarItem.py index 816e8474..3bbf06d1 100644 --- a/examples/ErrorBarItem.py +++ b/examples/ErrorBarItem.py @@ -21,6 +21,7 @@ top = np.linspace(1.0, 3.0, 10) bottom = np.linspace(2, 0.5, 10) plt = pg.plot() +plt.setWindowTitle('pyqtgraph example: ErrorBarItem') err = pg.ErrorBarItem(x=x, y=y, top=top, bottom=bottom, beam=0.5) plt.addItem(err) plt.plot(x, y, symbol='o', pen={'color': 0.8, 'width': 2}) diff --git a/examples/Flowchart.py b/examples/Flowchart.py index ade647fc..09ea1f93 100644 --- a/examples/Flowchart.py +++ b/examples/Flowchart.py @@ -23,6 +23,7 @@ app = QtGui.QApplication([]) ## Create main window with grid layout win = QtGui.QMainWindow() +win.setWindowTitle('pyqtgraph example: Flowchart') cw = QtGui.QWidget() win.setCentralWidget(cw) layout = QtGui.QGridLayout() diff --git a/examples/FlowchartCustomNode.py b/examples/FlowchartCustomNode.py index 9ed3d6da..bce37982 100644 --- a/examples/FlowchartCustomNode.py +++ b/examples/FlowchartCustomNode.py @@ -18,6 +18,7 @@ app = QtGui.QApplication([]) ## Create main window with a grid layout inside win = QtGui.QMainWindow() +win.setWindowTitle('pyqtgraph example: FlowchartCustomNode') cw = QtGui.QWidget() win.setCentralWidget(cw) layout = QtGui.QGridLayout() diff --git a/examples/GLImageItem.py b/examples/GLImageItem.py index 1d8faa3f..8b52ac09 100644 --- a/examples/GLImageItem.py +++ b/examples/GLImageItem.py @@ -1,4 +1,10 @@ # -*- coding: utf-8 -*- +""" +Use GLImageItem to display image data on rectangular planes. + +In this example, the image data is sampled from a volume and the image planes +placed as if they slice through the volume. +""" ## Add path to library (just for examples; you do not need this) import initExample @@ -12,6 +18,7 @@ app = QtGui.QApplication([]) w = gl.GLViewWidget() w.opts['distance'] = 200 w.show() +w.setWindowTitle('pyqtgraph example: GLImageItem') ## create volume data set to slice three images from shape = (100,100,70) diff --git a/examples/GLIsosurface.py b/examples/GLIsosurface.py index 97fc4874..a9403ffb 100644 --- a/examples/GLIsosurface.py +++ b/examples/GLIsosurface.py @@ -1,7 +1,8 @@ # -*- coding: utf-8 -*- - -## This example uses the isosurface function to convert a scalar field -## (a hydrogen orbital) into a mesh for 3D display. +""" +This example uses the isosurface function to convert a scalar field +(a hydrogen orbital) into a mesh for 3D display. +""" ## Add path to library (just for examples; you do not need this) import initExample @@ -13,6 +14,7 @@ import pyqtgraph.opengl as gl app = QtGui.QApplication([]) w = gl.GLViewWidget() w.show() +w.setWindowTitle('pyqtgraph example: GLIsosurface') w.setCameraPosition(distance=40) diff --git a/examples/GLLinePlotItem.py b/examples/GLLinePlotItem.py index 2194a51f..ab2fd75b 100644 --- a/examples/GLLinePlotItem.py +++ b/examples/GLLinePlotItem.py @@ -1,4 +1,8 @@ # -*- coding: utf-8 -*- +""" +Demonstrate use of GLLinePlotItem to draw cross-sections of a surface. + +""" ## Add path to library (just for examples; you do not need this) import initExample @@ -11,6 +15,7 @@ app = QtGui.QApplication([]) w = gl.GLViewWidget() w.opts['distance'] = 40 w.show() +w.setWindowTitle('pyqtgraph example: GLLinePlotItem') gx = gl.GLGridItem() gx.rotate(90, 0, 1, 0) diff --git a/examples/GLMeshItem.py b/examples/GLMeshItem.py index 49923913..9056fbd6 100644 --- a/examples/GLMeshItem.py +++ b/examples/GLMeshItem.py @@ -14,7 +14,7 @@ import pyqtgraph.opengl as gl app = QtGui.QApplication([]) w = gl.GLViewWidget() w.show() - +w.setWindowTitle('pyqtgraph example: GLMeshItem') w.setCameraPosition(distance=40) g = gl.GLGridItem() diff --git a/examples/GLScatterPlotItem.py b/examples/GLScatterPlotItem.py index 2d25ae12..53a9a752 100644 --- a/examples/GLScatterPlotItem.py +++ b/examples/GLScatterPlotItem.py @@ -1,4 +1,9 @@ # -*- coding: utf-8 -*- +""" +Demonstrates use of GLScatterPlotItem with rapidly-updating plots. + +""" + ## Add path to library (just for examples; you do not need this) import initExample @@ -10,6 +15,7 @@ app = QtGui.QApplication([]) w = gl.GLViewWidget() w.opts['distance'] = 20 w.show() +w.setWindowTitle('pyqtgraph example: GLScatterPlotItem') g = gl.GLGridItem() w.addItem(g) diff --git a/examples/GLSurfacePlot.py b/examples/GLSurfacePlot.py index d2151c46..963cf4cf 100644 --- a/examples/GLSurfacePlot.py +++ b/examples/GLSurfacePlot.py @@ -17,6 +17,7 @@ import numpy as np app = QtGui.QApplication([]) w = gl.GLViewWidget() w.show() +w.setWindowTitle('pyqtgraph example: GLSurfacePlot') w.setCameraPosition(distance=50) ## Add a grid to the view diff --git a/examples/GLViewWidget.py b/examples/GLViewWidget.py index 4989e8a2..a5207838 100644 --- a/examples/GLViewWidget.py +++ b/examples/GLViewWidget.py @@ -1,4 +1,8 @@ # -*- coding: utf-8 -*- +""" +Very basic 3D graphics example; create a view widget and add a few items. + +""" ## Add path to library (just for examples; you do not need this) import initExample @@ -9,6 +13,7 @@ app = QtGui.QApplication([]) w = gl.GLViewWidget() w.opts['distance'] = 20 w.show() +w.setWindowTitle('pyqtgraph example: GLViewWidget') ax = gl.GLAxisItem() ax.setSize(5,5,5) diff --git a/examples/GLVolumeItem.py b/examples/GLVolumeItem.py index d11730a5..ca20b127 100644 --- a/examples/GLVolumeItem.py +++ b/examples/GLVolumeItem.py @@ -1,4 +1,9 @@ # -*- coding: utf-8 -*- +""" +Demonstrates GLVolumeItem for displaying volumetric data. + +""" + ## Add path to library (just for examples; you do not need this) import initExample @@ -9,7 +14,7 @@ app = QtGui.QApplication([]) w = gl.GLViewWidget() w.opts['distance'] = 200 w.show() - +w.setWindowTitle('pyqtgraph example: GLVolumeItem') #b = gl.GLBoxItem() #w.addItem(b) diff --git a/examples/GLshaders.py b/examples/GLshaders.py index d9d6f00c..ce00fc7a 100644 --- a/examples/GLshaders.py +++ b/examples/GLshaders.py @@ -1,6 +1,7 @@ # -*- coding: utf-8 -*- """ -Demonstration of some of the shader programs included with pyqtgraph. +Demonstration of some of the shader programs included with pyqtgraph that can be +used to affect the appearance of a surface. """ @@ -15,7 +16,7 @@ import pyqtgraph.opengl as gl app = QtGui.QApplication([]) w = gl.GLViewWidget() w.show() - +w.setWindowTitle('pyqtgraph example: GL Shaders') w.setCameraPosition(distance=15, azimuth=-90) g = gl.GLGridItem() diff --git a/examples/GradientWidget.py b/examples/GradientWidget.py index 1a6458ce..ef7d0fa6 100644 --- a/examples/GradientWidget.py +++ b/examples/GradientWidget.py @@ -1,4 +1,9 @@ # -*- coding: utf-8 -*- +""" +Demonstrates the appearance / interactivity of GradientWidget +(without actually doing anything useful with it) + +""" import initExample ## Add path to library (just for examples; you do not need this) import pyqtgraph as pg @@ -10,6 +15,7 @@ import numpy as np app = QtGui.QApplication([]) w = QtGui.QMainWindow() w.show() +w.setWindowTitle('pyqtgraph example: GradientWidget') w.resize(400,400) cw = QtGui.QWidget() w.setCentralWidget(cw) diff --git a/examples/GraphItem.py b/examples/GraphItem.py index baeaf6c4..effa6b0b 100644 --- a/examples/GraphItem.py +++ b/examples/GraphItem.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- """ -Simple example of GridItem use. +Simple example of GraphItem use. """ @@ -11,6 +11,7 @@ from pyqtgraph.Qt import QtCore, QtGui import numpy as np w = pg.GraphicsWindow() +w.setWindowTitle('pyqtgraph example: GraphItem') v = w.addViewBox() v.setAspectLocked() diff --git a/examples/GraphicsLayout.py b/examples/GraphicsLayout.py index 90e773c7..70da7e5c 100644 --- a/examples/GraphicsLayout.py +++ b/examples/GraphicsLayout.py @@ -1,3 +1,10 @@ +""" +Demonstrate the use of layouts to control placement of multiple plots / views / +labels + + +""" + ## Add path to library (just for examples; you do not need this) import initExample @@ -10,6 +17,7 @@ view = pg.GraphicsView() l = pg.GraphicsLayout(border=(100,100,100)) view.setCentralItem(l) view.show() +view.setWindowTitle('pyqtgraph example: GraphicsLayout') view.resize(800,600) ## Title at top diff --git a/examples/HistogramLUT.py b/examples/HistogramLUT.py index 9f606457..5d66cb5d 100644 --- a/examples/HistogramLUT.py +++ b/examples/HistogramLUT.py @@ -1,4 +1,8 @@ # -*- coding: utf-8 -*- +""" +Use a HistogramLUTWidget to control the contrast / coloration of an image. +""" + ## Add path to library (just for examples; you do not need this) import initExample @@ -12,6 +16,7 @@ app = QtGui.QApplication([]) win = QtGui.QMainWindow() win.resize(800,600) win.show() +win.setWindowTitle('pyqtgraph example: Histogram LUT') cw = QtGui.QWidget() win.setCentralWidget(cw) diff --git a/examples/ImageItem.py b/examples/ImageItem.py index 4e40f56e..a2dc7af3 100644 --- a/examples/ImageItem.py +++ b/examples/ImageItem.py @@ -1,4 +1,8 @@ # -*- coding: utf-8 -*- +""" +Demonstrates very basic use of ImageItem to display image data inside a ViewBox. +""" + ## Add path to library (just for examples; you do not need this) import initExample @@ -10,19 +14,17 @@ import pyqtgraph.ptime as ptime app = QtGui.QApplication([]) ## Create window with GraphicsView widget -view = pg.GraphicsView() -view.show() ## show view alone in its own window - -## Allow mouse scale/pan. Normally we use a ViewBox for this, but -## for simple examples this is easier. -view.enableMouse() +win = pg.GraphicsLayoutWidget() +win.show() ## show widget alone in its own window +win.setWindowTitle('pyqtgraph example: ImageItem') +view = win.addViewBox() ## lock the aspect ratio so pixels are always square view.setAspectLocked(True) ## Create image item img = pg.ImageItem(border='w') -view.scene().addItem(img) +view.addItem(img) ## Set initial view bounds view.setRange(QtCore.QRectF(0, 0, 600, 600)) diff --git a/examples/ImageView.py b/examples/ImageView.py index f11ce0f7..d0bbd31b 100644 --- a/examples/ImageView.py +++ b/examples/ImageView.py @@ -26,6 +26,7 @@ win.resize(800,800) imv = pg.ImageView() win.setCentralWidget(imv) win.show() +win.setWindowTitle('pyqtgraph example: ImageView') ## Create random 3D data set with noisy signals img = scipy.ndimage.gaussian_filter(np.random.normal(size=(200, 200)), (5, 5)) * 20 + 100 diff --git a/examples/JoystickButton.py b/examples/JoystickButton.py index 49d310a0..03c79706 100644 --- a/examples/JoystickButton.py +++ b/examples/JoystickButton.py @@ -1,7 +1,9 @@ # -*- coding: utf-8 -*- """ -JoystickButton is a button with x/y values. When the button is depressed and the mouse dragged, the x/y values change to follow the mouse. -When the mouse button is released, the x/y values change to 0,0 (rather like litting go of the joystick). +JoystickButton is a button with x/y values. When the button is depressed and the +mouse dragged, the x/y values change to follow the mouse. +When the mouse button is released, the x/y values change to 0,0 (rather like +letting go of the joystick). """ import initExample ## Add path to library (just for examples; you do not need this) @@ -13,6 +15,7 @@ import pyqtgraph as pg app = QtGui.QApplication([]) mw = QtGui.QMainWindow() mw.resize(300,50) +mw.setWindowTitle('pyqtgraph example: JoystickButton') cw = QtGui.QWidget() mw.setCentralWidget(cw) layout = QtGui.QGridLayout() diff --git a/examples/Legend.py b/examples/Legend.py index 3d6d5730..2cd982ea 100644 --- a/examples/Legend.py +++ b/examples/Legend.py @@ -1,11 +1,15 @@ # -*- coding: utf-8 -*- +""" +Demonstrates basic use of LegendItem + +""" import initExample ## Add path to library (just for examples; you do not need this) import pyqtgraph as pg from pyqtgraph.Qt import QtCore, QtGui plt = pg.plot() - +plt.setWindowTitle('pyqtgraph example: Legend') plt.addLegend() #l = pg.LegendItem((100,60), offset=(70,30)) # args are (size, offset) #l.setParentItem(plt.graphicsItem()) # Note we do NOT call plt.addItem in this case diff --git a/examples/LogPlotTest.py b/examples/LogPlotTest.py index a5b07520..d408a2b4 100644 --- a/examples/LogPlotTest.py +++ b/examples/LogPlotTest.py @@ -1,9 +1,7 @@ # -*- coding: utf-8 -*- - -## This example demonstrates many of the 2D plotting capabilities -## in pyqtgraph. All of the plots may be panned/scaled by dragging with -## the left/right mouse buttons. Right click on any plot to show a context menu. - +""" +Simple logarithmic plotting test +""" import initExample ## Add path to library (just for examples; you do not need this) @@ -12,14 +10,11 @@ from pyqtgraph.Qt import QtGui, QtCore import numpy as np import pyqtgraph as pg -#QtGui.QApplication.setGraphicsSystem('raster') app = QtGui.QApplication([]) -#mw = QtGui.QMainWindow() -#mw.resize(800,800) win = pg.GraphicsWindow(title="Basic plotting examples") win.resize(1000,600) - +win.setWindowTitle('pyqtgraph example: LogPlotTest') p5 = win.addPlot(title="Scatter plot, axis labels, log scale") diff --git a/examples/MultiPlotSpeedTest.py b/examples/MultiPlotSpeedTest.py index e25de42e..e38c90e2 100644 --- a/examples/MultiPlotSpeedTest.py +++ b/examples/MultiPlotSpeedTest.py @@ -1,5 +1,9 @@ #!/usr/bin/python # -*- coding: utf-8 -*- +""" +Test the speed of rapidly updating multiple plot curves +""" + ## Add path to library (just for examples; you do not need this) import initExample @@ -14,6 +18,7 @@ app = QtGui.QApplication([]) #mw.resize(800,800) p = pg.plot() +p.setWindowTitle('pyqtgraph example: MultiPlotSpeedTest') #p.setRange(QtCore.QRectF(0, -10, 5000, 20)) p.setLabel('bottom', 'Index', units='B') diff --git a/examples/PlotAutoRange.py b/examples/PlotAutoRange.py index 3c25b193..46aa3a44 100644 --- a/examples/PlotAutoRange.py +++ b/examples/PlotAutoRange.py @@ -1,7 +1,8 @@ # -*- coding: utf-8 -*- -## This example demonstrates the different auto-ranging capabilities of ViewBoxes - +""" +This example demonstrates the different auto-ranging capabilities of ViewBoxes +""" import initExample ## Add path to library (just for examples; you do not need this) @@ -17,7 +18,7 @@ app = QtGui.QApplication([]) win = pg.GraphicsWindow(title="Plot auto-range examples") win.resize(800,600) - +win.setWindowTitle('pyqtgraph example: PlotAutoRange') d = np.random.normal(size=100) d[50:54] += 10 diff --git a/examples/PlotSpeedTest.py b/examples/PlotSpeedTest.py index cb200429..03c9537f 100644 --- a/examples/PlotSpeedTest.py +++ b/examples/PlotSpeedTest.py @@ -1,5 +1,9 @@ #!/usr/bin/python # -*- coding: utf-8 -*- +""" +Update a simple plot as rapidly as possible to measure speed. +""" + ## Add path to library (just for examples; you do not need this) import initExample @@ -8,12 +12,10 @@ from pyqtgraph.Qt import QtGui, QtCore import numpy as np import pyqtgraph as pg from pyqtgraph.ptime import time -#QtGui.QApplication.setGraphicsSystem('raster') app = QtGui.QApplication([]) -#mw = QtGui.QMainWindow() -#mw.resize(800,800) p = pg.plot() +p.setWindowTitle('pyqtgraph example: PlotSpeedTest') p.setRange(QtCore.QRectF(0, -10, 5000, 20)) p.setLabel('bottom', 'Index', units='B') curve = p.plot() diff --git a/examples/PlotWidget.py b/examples/PlotWidget.py index 2aa118f2..88236ba0 100644 --- a/examples/PlotWidget.py +++ b/examples/PlotWidget.py @@ -1,4 +1,10 @@ # -*- coding: utf-8 -*- +""" +Demonstrates use of PlotWidget class. This is little more than a +GraphicsView with a PlotItem placed in its center. +""" + + import initExample ## Add path to library (just for examples; you do not need this) @@ -9,6 +15,7 @@ import pyqtgraph as pg #QtGui.QApplication.setGraphicsSystem('raster') app = QtGui.QApplication([]) mw = QtGui.QMainWindow() +mw.setWindowTitle('pyqtgraph example: PlotWidget') mw.resize(800,800) cw = QtGui.QWidget() mw.setCentralWidget(cw) diff --git a/examples/Plotting.py b/examples/Plotting.py index 7842ad3d..6a3a1d11 100644 --- a/examples/Plotting.py +++ b/examples/Plotting.py @@ -1,9 +1,9 @@ # -*- coding: utf-8 -*- - -## This example demonstrates many of the 2D plotting capabilities -## in pyqtgraph. All of the plots may be panned/scaled by dragging with -## the left/right mouse buttons. Right click on any plot to show a context menu. - +""" +This example demonstrates many of the 2D plotting capabilities +in pyqtgraph. All of the plots may be panned/scaled by dragging with +the left/right mouse buttons. Right click on any plot to show a context menu. +""" import initExample ## Add path to library (just for examples; you do not need this) @@ -19,6 +19,7 @@ app = QtGui.QApplication([]) win = pg.GraphicsWindow(title="Basic plotting examples") win.resize(1000,600) +win.setWindowTitle('pyqtgraph example: Plotting') diff --git a/examples/ROIExamples.py b/examples/ROIExamples.py index d8ad3dd0..56d6b13c 100644 --- a/examples/ROIExamples.py +++ b/examples/ROIExamples.py @@ -1,4 +1,10 @@ # -*- coding: utf-8 -*- +""" +Demonstrates a variety of uses for ROI. This class provides a user-adjustable +region of interest marker. It is possible to customize the layout and +function of the scale/rotate handles in very flexible ways. +""" + import initExample ## Add path to library (just for examples; you do not need this) import pyqtgraph as pg @@ -22,6 +28,7 @@ arr += np.random.normal(size=(100,100)) ## create GUI app = QtGui.QApplication([]) w = pg.GraphicsWindow(size=(800,800), border=True) +w.setWindowTitle('pyqtgraph example: ROI Examples') text = """Data Selection From Image.
\n Drag an ROI or its handles to update the selected image.
diff --git a/examples/RemoteGraphicsView.py b/examples/RemoteGraphicsView.py index 137b5e87..5b4e7ef4 100644 --- a/examples/RemoteGraphicsView.py +++ b/examples/RemoteGraphicsView.py @@ -1,18 +1,25 @@ # -*- coding: utf-8 -*- +""" +Very simple example demonstrating RemoteGraphicsView +""" import initExample ## Add path to library (just for examples; you do not need this) from pyqtgraph.Qt import QtGui, QtCore import pyqtgraph as pg +from pyqtgraph.widgets.RemoteGraphicsView import RemoteGraphicsView app = pg.mkQApp() -v = pg.RemoteGraphicsView() +v = RemoteGraphicsView() v.show() +v.setWindowTitle('pyqtgraph example: RemoteGraphicsView') +## v.pg is a proxy to the remote process' pyqtgraph module. All attribute +## requests and function calls made with this object are forwarded to the +## remote process and executed there. plt = v.pg.PlotItem() v.setCentralItem(plt) plt.plot([1,4,2,3,6,2,3,4,2,3], pen='g') - ## Start Qt event loop unless running in interactive mode or using pyside. if __name__ == '__main__': import sys diff --git a/examples/RemoteSpeedTest.py b/examples/RemoteSpeedTest.py index b3415a9d..03b4430b 100644 --- a/examples/RemoteSpeedTest.py +++ b/examples/RemoteSpeedTest.py @@ -22,6 +22,7 @@ app = pg.mkQApp() view = pg.widgets.RemoteGraphicsView.RemoteGraphicsView() pg.setConfigOptions(antialias=True) ## this will be expensive for the local plot view.pg.setConfigOptions(antialias=True) ## prettier plots at no cost to the main process! +view.setWindowTitle('pyqtgraph example: RemoteSpeedTest') label = QtGui.QLabel() rcheck = QtGui.QCheckBox('plot remote') diff --git a/examples/ScatterPlot.py b/examples/ScatterPlot.py index e72e2631..805cf09f 100644 --- a/examples/ScatterPlot.py +++ b/examples/ScatterPlot.py @@ -1,4 +1,10 @@ # -*- coding: utf-8 -*- +""" +Example demonstrating a variety of scatter plot features. +""" + + + ## Add path to library (just for examples; you do not need this) import initExample @@ -12,6 +18,7 @@ mw.resize(800,800) view = pg.GraphicsLayoutWidget() ## GraphicsView with GraphicsLayout inserted by default mw.setCentralWidget(view) mw.show() +mw.setWindowTitle('pyqtgraph example: ScatterPlot') ## create four areas to add plots w1 = view.addPlot() diff --git a/examples/ScatterPlotSpeedTest.py b/examples/ScatterPlotSpeedTest.py index 545071b1..b79c6641 100644 --- a/examples/ScatterPlotSpeedTest.py +++ b/examples/ScatterPlotSpeedTest.py @@ -1,5 +1,13 @@ #!/usr/bin/python # -*- coding: utf-8 -*- +""" +For testing rapid updates of ScatterPlotItem under various conditions. + +(Scatter plots are still rather slow to draw; expect about 20fps) +""" + + + ## Add path to library (just for examples; you do not need this) import initExample @@ -18,6 +26,7 @@ else: from ScatterPlotSpeedTestTemplate_pyqt import Ui_Form win = QtGui.QWidget() +win.setWindowTitle('pyqtgraph example: ScatterPlotSpeedTest') ui = Ui_Form() ui.setupUi(win) win.show() diff --git a/examples/SpinBox.py b/examples/SpinBox.py index 488e995b..ef20e757 100644 --- a/examples/SpinBox.py +++ b/examples/SpinBox.py @@ -1,4 +1,13 @@ # -*- coding: utf-8 -*- +""" +This example demonstrates the SpinBox widget, which is an extension of +QDoubleSpinBox providing some advanced features: + + * SI-prefixed units + * Non-linear stepping modes + * Bounded/unbounded values + +""" import initExample ## Add path to library (just for examples; you do not need this) import pyqtgraph as pg @@ -20,6 +29,7 @@ spins = [ win = QtGui.QMainWindow() +win.setWindowTitle('pyqtgraph example: SpinBox') cw = QtGui.QWidget() layout = QtGui.QGridLayout() cw.setLayout(layout) diff --git a/examples/TreeWidget.py b/examples/TreeWidget.py index 80e9bd24..b1ad3847 100644 --- a/examples/TreeWidget.py +++ b/examples/TreeWidget.py @@ -1,4 +1,8 @@ # -*- coding: utf-8 -*- +""" +Simple demonstration of TreeWidget, which is an extension of QTreeWidget +that allows widgets to be added and dragged within the tree more easily. +""" import initExample ## Add path to library (just for examples; you do not need this) import pyqtgraph as pg @@ -11,6 +15,7 @@ app = QtGui.QApplication([]) w = pg.TreeWidget() w.setColumnCount(2) w.show() +w.setWindowTitle('pyqtgraph example: TreeWidget') i1 = QtGui.QTreeWidgetItem(["Item 1"]) i11 = QtGui.QTreeWidgetItem(["Item 1.1"]) diff --git a/examples/VideoSpeedTest.py b/examples/VideoSpeedTest.py index 1d0fa58c..dd392189 100644 --- a/examples/VideoSpeedTest.py +++ b/examples/VideoSpeedTest.py @@ -29,6 +29,7 @@ app = QtGui.QApplication([]) #mw.resize(800,800) win = QtGui.QMainWindow() +win.setWindowTitle('pyqtgraph example: VideoSpeedTest') ui = VideoTemplate.Ui_MainWindow() ui.setupUi(win) win.show() diff --git a/examples/ViewBox.py b/examples/ViewBox.py index f2269176..c8487148 100644 --- a/examples/ViewBox.py +++ b/examples/ViewBox.py @@ -1,5 +1,14 @@ #!/usr/bin/python # -*- coding: utf-8 -*- +""" +ViewBox is the general-purpose graphical container that allows the user to +zoom / pan to inspect any area of a 2D coordinate system. + +This unimaginative example demonstrates the constrution of a ViewBox-based +plot area with axes, very similar to the way PlotItem is built. +""" + + ## Add path to library (just for examples; you do not need this) import initExample @@ -12,25 +21,17 @@ import pyqtgraph as pg app = QtGui.QApplication([]) mw = QtGui.QMainWindow() -#cw = QtGui.QWidget() -#vl = QtGui.QVBoxLayout() -#cw.setLayout(vl) -#mw.setCentralWidget(cw) +mw.setWindowTitle('pyqtgraph example: ViewBox') mw.show() mw.resize(800, 600) gv = pg.GraphicsView() mw.setCentralWidget(gv) -#gv.enableMouse(False) ## Mouse interaction will be handled by the ViewBox l = QtGui.QGraphicsGridLayout() l.setHorizontalSpacing(0) l.setVerticalSpacing(0) -#vl.addWidget(gv) - vb = pg.ViewBox() -#grid = pg.GridItem() -#vb.addItem(grid) p1 = pg.PlotDataItem() vb.addItem(p1) diff --git a/examples/__main__.py b/examples/__main__.py index 096edba0..9b9e7b57 100644 --- a/examples/__main__.py +++ b/examples/__main__.py @@ -22,6 +22,7 @@ examples = OrderedDict([ ('Dock widgets', 'dockarea.py'), ('Console', 'ConsoleWidget.py'), ('Histograms', 'histogram.py'), + ('Auto-range', 'PlotAutoRange.py'), ('Remote Plotting', 'RemoteSpeedTest.py'), ('GraphicsItems', OrderedDict([ ('Scatter Plot', 'ScatterPlot.py'), @@ -38,6 +39,7 @@ examples = OrderedDict([ ('Linked Views', 'linkedViews.py'), ('Arrow', 'Arrow.py'), ('ViewBox', 'ViewBox.py'), + ('Custom Graphics', 'customGraphicsItem.py'), ])), ('Benchmarks', OrderedDict([ ('Video speed test', 'VideoSpeedTest.py'), @@ -58,6 +60,7 @@ examples = OrderedDict([ ('PlotWidget', 'PlotWidget.py'), ('SpinBox', 'SpinBox.py'), ('ConsoleWidget', 'ConsoleWidget.py'), + ('Histogram / lookup table', 'HistogramLUT.py'), ('TreeWidget', 'TreeWidget.py'), ('DataTreeWidget', 'DataTreeWidget.py'), ('GradientWidget', 'GradientWidget.py'), @@ -68,7 +71,7 @@ examples = OrderedDict([ ('JoystickButton', 'JoystickButton.py'), ])), - ('GraphicsScene', 'GraphicsScene.py'), + #('GraphicsScene', 'GraphicsScene.py'), ('Flowcharts', 'Flowchart.py'), ('Custom Flowchart Nodes', 'FlowchartCustomNode.py'), #('Canvas', '../canvas'), diff --git a/examples/crosshair.py b/examples/crosshair.py index a99f097b..c41dfff1 100644 --- a/examples/crosshair.py +++ b/examples/crosshair.py @@ -1,3 +1,10 @@ +""" +Demonstrates some customized mouse interaction by drawing a crosshair that follows +the mouse. + + +""" + import initExample ## Add path to library (just for examples; you do not need this) import numpy as np import scipy.ndimage as ndi @@ -5,9 +12,10 @@ import pyqtgraph as pg from pyqtgraph.Qt import QtGui, QtCore from pyqtgraph.Point import Point -#genearte layout +#generate layout app = QtGui.QApplication([]) win = pg.GraphicsWindow() +win.setWindowTitle('pyqtgraph example: crosshair') label = pg.LabelItem(justify='right') win.addItem(label) p1 = win.addPlot(row=1, col=0) diff --git a/examples/customGraphicsItem.py b/examples/customGraphicsItem.py index 263ce0c5..9723b83a 100644 --- a/examples/customGraphicsItem.py +++ b/examples/customGraphicsItem.py @@ -1,6 +1,15 @@ +""" +Demonstrate creation of a custom graphic (a candlestick plot) + +""" +import initExample ## Add path to library (just for examples; you do not need this) + import pyqtgraph as pg from pyqtgraph import QtCore, QtGui +## Create a subclass of GraphicsObject. +## The only required methods are paint() and boundingRect() +## (see QGraphicsItem documentation) class CandlestickItem(pg.GraphicsObject): def __init__(self, data): pg.GraphicsObject.__init__(self) @@ -8,6 +17,8 @@ class CandlestickItem(pg.GraphicsObject): self.generatePicture() def generatePicture(self): + ## pre-computing a QPicture object allows paint() to run much more quickly, + ## rather than re-drawing the shapes every time. self.picture = QtGui.QPicture() p = QtGui.QPainter(self.picture) p.setPen(pg.mkPen('w')) @@ -25,6 +36,9 @@ class CandlestickItem(pg.GraphicsObject): p.drawPicture(0, 0, self.picture) def boundingRect(self): + ## boundingRect _must_ indicate the entire area that will be drawn on + ## or else we will get artifacts and possibly crashing. + ## (in this case, QPicture does all the work of computing the bouning rect for us) return QtCore.QRectF(self.picture.boundingRect()) data = [ ## fields are (time, open, close, min, max). @@ -38,5 +52,10 @@ data = [ ## fields are (time, open, close, min, max). item = CandlestickItem(data) plt = pg.plot() plt.addItem(item) +plt.setWindowTitle('pyqtgraph example: customGraphicsItem') -QtGui.QApplication.exec_() \ No newline at end of file +## Start Qt event loop unless running in interactive mode or using pyside. +if __name__ == '__main__': + import sys + if (sys.flags.interactive != 1) or not hasattr(QtCore, 'PYQT_VERSION'): + QtGui.QApplication.instance().exec_() diff --git a/examples/customPlot.py b/examples/customPlot.py index 1c3b2489..b523fd17 100644 --- a/examples/customPlot.py +++ b/examples/customPlot.py @@ -1,8 +1,8 @@ # -*- coding: utf-8 -*- -## -## This example demonstrates the creation of a plot with a customized -## AxisItem and ViewBox. -## +""" +This example demonstrates the creation of a plot with a customized +AxisItem and ViewBox. +""" import initExample ## Add path to library (just for examples; you do not need this) @@ -72,6 +72,7 @@ pw = pg.PlotWidget(viewBox=vb, axisItems={'bottom': axis}, enableMenu=False, tit dates = np.arange(8) * (3600*24*356) pw.plot(x=dates, y=[1,6,2,4,3,5,6,8], symbol='o') pw.show() +pw.setWindowTitle('pyqtgraph example: customPlot') r = pg.PolyLineROI([(0,0), (10, 10)]) pw.addItem(r) diff --git a/examples/dockarea.py b/examples/dockarea.py index 8b668cf1..2b33048d 100644 --- a/examples/dockarea.py +++ b/examples/dockarea.py @@ -29,6 +29,7 @@ win = QtGui.QMainWindow() area = DockArea() win.setCentralWidget(area) win.resize(1000,500) +win.setWindowTitle('pyqtgraph example: dockarea') ## Create docks, place them into the window one at a time. ## Note that size arguments are only a suggestion; docks will still have to diff --git a/examples/histogram.py b/examples/histogram.py index fdde7da1..057abffd 100644 --- a/examples/histogram.py +++ b/examples/histogram.py @@ -12,13 +12,14 @@ import numpy as np win = pg.GraphicsWindow() win.resize(800,350) +win.setWindowTitle('pyqtgraph example: Histogram') plt1 = win.addPlot() plt2 = win.addPlot() ## make interesting distribution of values vals = np.hstack([np.random.normal(size=500), np.random.normal(size=260, loc=4)]) -## draw standard histogram +## compute standard histogram y,x = np.histogram(vals, bins=np.linspace(-3, 8, 40)) ## notice that len(x) == len(y)+1 diff --git a/examples/isocurve.py b/examples/isocurve.py index 14a3e56a..fa451063 100644 --- a/examples/isocurve.py +++ b/examples/isocurve.py @@ -22,6 +22,7 @@ data = ndi.gaussian_filter(data, (10, 10, 10))[frames/2:frames + frames/2] data[:, 15:16, 15:17] += 1 win = pg.GraphicsWindow() +win.setWindowTitle('pyqtgraph example: Isocurve') vb = win.addViewBox() img = pg.ImageItem(data[0]) vb.addItem(img) diff --git a/examples/linkedViews.py b/examples/linkedViews.py index 9d9cd7f5..e7eb18af 100644 --- a/examples/linkedViews.py +++ b/examples/linkedViews.py @@ -1,8 +1,9 @@ # -*- coding: utf-8 -*- - -## This example demonstrates the ability to link the axes of views together -## Views can be linked manually using the context menu, but only if they are given names. - +""" +This example demonstrates the ability to link the axes of views together +Views can be linked manually using the context menu, but only if they are given +names. +""" import initExample ## Add path to library (just for examples; you do not need this) @@ -19,7 +20,7 @@ app = QtGui.QApplication([]) x = np.linspace(-50, 50, 1000) y = np.sin(x) / x -win = pg.GraphicsWindow(title="View Linking Examples") +win = pg.GraphicsWindow(title="pyqtgraph example: Linked Views") win.resize(800,600) win.addLabel("Linked Views", colspan=2) diff --git a/examples/logAxis.py b/examples/logAxis.py index 77ee66e5..a0c7fc53 100644 --- a/examples/logAxis.py +++ b/examples/logAxis.py @@ -1,5 +1,7 @@ # -*- coding: utf-8 -*- - +""" +Test programmatically setting log transformation modes. +""" import initExample ## Add path to library (just for examples; you do not need this) import numpy as np @@ -10,6 +12,7 @@ import pyqtgraph as pg app = QtGui.QApplication([]) w = pg.GraphicsWindow() +w.setWindowTitle('pyqtgraph example: logAxis') p1 = w.addPlot(0,0, title="X Semilog") p2 = w.addPlot(1,0, title="Y Semilog") p3 = w.addPlot(2,0, title="XY Log") diff --git a/examples/multiplePlotSpeedTest.py b/examples/multiplePlotSpeedTest.py index bc54bb51..cea59a35 100644 --- a/examples/multiplePlotSpeedTest.py +++ b/examples/multiplePlotSpeedTest.py @@ -39,7 +39,7 @@ def plot(): #plt.addItem(item) dt = pg.ptime.time() - start - print "Create plots took: %0.3fms" % (dt*1000) + print("Create plots took: %0.3fms" % (dt*1000)) ## Plot and clear 5 times, printing the time it took for i in range(5): @@ -72,7 +72,7 @@ def fastPlot(): plt.addItem(item) dt = pg.ptime.time() - start - print "Create plots took: %0.3fms" % (dt*1000) + print("Create plots took: %0.3fms" % (dt*1000)) ## Plot and clear 5 times, printing the time it took @@ -82,7 +82,7 @@ if hasattr(pg, 'arrayToQPath'): fastPlot() app.processEvents() else: - print "Skipping fast tests--arrayToQPath function is missing." + print("Skipping fast tests--arrayToQPath function is missing.") plt.autoRange() diff --git a/examples/parametertree.py b/examples/parametertree.py index 9bcbc5d2..4c5d7275 100644 --- a/examples/parametertree.py +++ b/examples/parametertree.py @@ -140,6 +140,7 @@ p.param('Save/Restore functionality', 'Restore State').sigActivated.connect(rest 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) diff --git a/examples/template.py b/examples/template.py index 76b14361..1198e317 100644 --- a/examples/template.py +++ b/examples/template.py @@ -1,10 +1,18 @@ # -*- coding: utf-8 -*- +""" + +Description of example + + +""" import initExample ## Add path to library (just for examples; you do not need this) import pyqtgraph as pg from pyqtgraph.Qt import QtCore, QtGui import numpy as np +# win.setWindowTitle('pyqtgraph example: ____') + ## Start Qt event loop unless running in interactive mode or using pyside. if __name__ == '__main__': import sys diff --git a/examples/text.py b/examples/text.py index f9300064..23f527e3 100644 --- a/examples/text.py +++ b/examples/text.py @@ -1,6 +1,12 @@ # -*- coding: utf-8 -*- -## This example shows how to insert text into a scene using QTextItem +""" +This example shows how to insert text into a scene using TextItem. This class +is for displaying text that is anchored to a particular location in the data +coordinate system, but which is always displayed unscaled. +For text that scales with the data, use QTextItem. +For text that can be placed in a layout, use LabelItem. +""" import initExample ## Add path to library (just for examples; you do not need this) @@ -13,6 +19,7 @@ x = np.linspace(-20, 20, 1000) y = np.sin(x) / x plot = pg.plot() ## create an empty plot widget plot.setYRange(-1, 2) +plot.setWindowTitle('pyqtgraph example: text') curve = plot.plot(x,y) ## add a single curve ## Create text object, use HTML tags to specify color/size diff --git a/pyqtgraph/configfile.py b/pyqtgraph/configfile.py index db7dc732..f709c786 100644 --- a/pyqtgraph/configfile.py +++ b/pyqtgraph/configfile.py @@ -10,7 +10,7 @@ as it can be converted to/from a string using repr and eval. """ import re, os, sys -from pgcollections import OrderedDict +from .pgcollections import OrderedDict GLOBAL_PATH = None # so not thread safe. from . import units from .python2_3 import asUnicode @@ -199,4 +199,4 @@ key2: ##comment print("============") data = readConfigFile(fn) print(data) - os.remove(fn) \ No newline at end of file + os.remove(fn) diff --git a/pyqtgraph/flowchart/FlowchartTemplate.ui b/pyqtgraph/flowchart/FlowchartTemplate.ui index e4530800..31b1359c 100644 --- a/pyqtgraph/flowchart/FlowchartTemplate.ui +++ b/pyqtgraph/flowchart/FlowchartTemplate.ui @@ -90,7 +90,7 @@ FlowchartGraphicsView QGraphicsView -
FlowchartGraphicsView
+
pyqtgraph.flowchart.FlowchartGraphicsView
diff --git a/pyqtgraph/flowchart/FlowchartTemplate_pyqt.py b/pyqtgraph/flowchart/FlowchartTemplate_pyqt.py index 2e9ea312..c07dd734 100644 --- a/pyqtgraph/flowchart/FlowchartTemplate_pyqt.py +++ b/pyqtgraph/flowchart/FlowchartTemplate_pyqt.py @@ -2,8 +2,8 @@ # Form implementation generated from reading ui file './flowchart/FlowchartTemplate.ui' # -# Created: Sun Sep 9 14:41:29 2012 -# by: PyQt4 UI code generator 4.9.1 +# Created: Sun Feb 24 19:47:29 2013 +# by: PyQt4 UI code generator 4.9.3 # # WARNING! All changes made in this file will be lost! @@ -56,4 +56,4 @@ class Ui_Form(object): Form.setWindowTitle(QtGui.QApplication.translate("Form", "Form", None, QtGui.QApplication.UnicodeUTF8)) from pyqtgraph.widgets.DataTreeWidget import DataTreeWidget -from FlowchartGraphicsView import FlowchartGraphicsView +from pyqtgraph.flowchart.FlowchartGraphicsView import FlowchartGraphicsView diff --git a/pyqtgraph/flowchart/FlowchartTemplate_pyside.py b/pyqtgraph/flowchart/FlowchartTemplate_pyside.py index d49d3083..c73f3c00 100644 --- a/pyqtgraph/flowchart/FlowchartTemplate_pyside.py +++ b/pyqtgraph/flowchart/FlowchartTemplate_pyside.py @@ -2,8 +2,8 @@ # Form implementation generated from reading ui file './flowchart/FlowchartTemplate.ui' # -# Created: Sun Sep 9 14:41:30 2012 -# by: pyside-uic 0.2.13 running on PySide 1.1.0 +# Created: Sun Feb 24 19:47:30 2013 +# by: pyside-uic 0.2.13 running on PySide 1.1.1 # # WARNING! All changes made in this file will be lost! @@ -51,4 +51,4 @@ class Ui_Form(object): Form.setWindowTitle(QtGui.QApplication.translate("Form", "Form", None, QtGui.QApplication.UnicodeUTF8)) from pyqtgraph.widgets.DataTreeWidget import DataTreeWidget -from FlowchartGraphicsView import FlowchartGraphicsView +from pyqtgraph.flowchart.FlowchartGraphicsView import FlowchartGraphicsView diff --git a/pyqtgraph/graphicsItems/ViewBox/ViewBox.py b/pyqtgraph/graphicsItems/ViewBox/ViewBox.py index b562132c..87b687bd 100644 --- a/pyqtgraph/graphicsItems/ViewBox/ViewBox.py +++ b/pyqtgraph/graphicsItems/ViewBox/ViewBox.py @@ -451,7 +451,7 @@ class ViewBox(GraphicsWidget): if item is None: bounds = self.childrenBoundingRect(items=items) else: - print "Warning: ViewBox.autoRange(item=__) is deprecated. Use 'items' argument instead." + print("Warning: ViewBox.autoRange(item=__) is deprecated. Use 'items' argument instead.") bounds = self.mapFromItemToView(item, item.boundingRect()).boundingRect() if bounds is not None: From 475006f508d320dcf6d298114cc87140f3e0edb9 Mon Sep 17 00:00:00 2001 From: Luke Campagnola Date: Mon, 25 Feb 2013 13:03:21 -0500 Subject: [PATCH 10/11] example loader allows editing code Workaround for PySide bug; fixes GradientEditorItem --- examples/ViewBox.py | 3 +- examples/__main__.py | 45 +++++++++++++---- examples/exampleLoaderTemplate.ui | 43 ++++++++++++----- examples/exampleLoaderTemplate_pyqt.py | 48 ++++++++++++------- examples/exampleLoaderTemplate_pyside.py | 48 ++++++++++++------- examples/initExample.py | 5 +- pyqtgraph/graphicsItems/GradientEditorItem.py | 5 +- {pyqtgraph => tools}/rebuildUi.py | 0 8 files changed, 139 insertions(+), 58 deletions(-) rename {pyqtgraph => tools}/rebuildUi.py (100%) diff --git a/examples/ViewBox.py b/examples/ViewBox.py index c8487148..2dcbb758 100644 --- a/examples/ViewBox.py +++ b/examples/ViewBox.py @@ -36,6 +36,7 @@ vb = pg.ViewBox() p1 = pg.PlotDataItem() vb.addItem(p1) +## Just something to play with inside the ViewBox class movableRect(QtGui.QGraphicsRectItem): def __init__(self, *args): QtGui.QGraphicsRectItem.__init__(self, *args) @@ -56,8 +57,6 @@ class movableRect(QtGui.QGraphicsRectItem): def mouseMoveEvent(self, ev): self.setPos(self.mapToParent(ev.pos()) - self.pressDelta) - -#rect = QtGui.QGraphicsRectItem(QtCore.QRectF(0, 0, 1, 1)) rect = movableRect(QtCore.QRectF(0, 0, 1, 1)) rect.setPen(QtGui.QPen(QtGui.QColor(100, 200, 100))) vb.addItem(rect) diff --git a/examples/__main__.py b/examples/__main__.py index 9b9e7b57..8d60714c 100644 --- a/examples/__main__.py +++ b/examples/__main__.py @@ -88,6 +88,13 @@ class ExampleLoader(QtGui.QMainWindow): self.setCentralWidget(self.cw) self.ui.setupUi(self.cw) + self.codeBtn = QtGui.QPushButton('Run Edited Code') + self.codeLayout = QtGui.QGridLayout() + self.ui.codeView.setLayout(self.codeLayout) + self.codeLayout.addItem(QtGui.QSpacerItem(100,100,QtGui.QSizePolicy.Expanding,QtGui.QSizePolicy.Expanding), 0, 0) + self.codeLayout.addWidget(self.codeBtn, 1, 1) + self.codeBtn.hide() + global examples self.populateTree(self.ui.exampleTree.invisibleRootItem(), examples) self.ui.exampleTree.expandAll() @@ -100,6 +107,8 @@ class ExampleLoader(QtGui.QMainWindow): self.ui.exampleTree.itemDoubleClicked.connect(self.loadFile) self.ui.pyqtCheck.toggled.connect(self.pyqtToggled) self.ui.pysideCheck.toggled.connect(self.pysideToggled) + self.ui.codeView.textChanged.connect(self.codeEdited) + self.codeBtn.clicked.connect(self.runEditedCode) def pyqtToggled(self, b): if b: @@ -127,8 +136,8 @@ class ExampleLoader(QtGui.QMainWindow): return os.path.join(path, item.file) return None - def loadFile(self): - fn = self.currentFile() + def loadFile(self, edited=False): + extra = [] if self.ui.pyqtCheck.isChecked(): extra.append('pyqt') @@ -138,13 +147,25 @@ class ExampleLoader(QtGui.QMainWindow): if self.ui.forceGraphicsCheck.isChecked(): extra.append(str(self.ui.forceGraphicsCombo.currentText())) - if fn is None: - return - if sys.platform.startswith('win'): - os.spawnl(os.P_NOWAIT, sys.executable, '"'+sys.executable+'"', '"' + fn + '"', *extra) - else: - os.spawnl(os.P_NOWAIT, sys.executable, sys.executable, fn, *extra) + #if sys.platform.startswith('win'): + #os.spawnl(os.P_NOWAIT, sys.executable, '"'+sys.executable+'"', '"' + fn + '"', *extra) + #else: + #os.spawnl(os.P_NOWAIT, sys.executable, sys.executable, fn, *extra) + + if edited: + proc = subprocess.Popen([sys.executable, '-'] + extra, stdin=subprocess.PIPE) + code = str(self.ui.codeView.toPlainText()).encode('UTF-8') + proc.stdin.write(code) + proc.stdin.close() + else: + fn = self.currentFile() + if fn is None: + return + if sys.platform.startswith('win'): + os.spawnl(os.P_NOWAIT, sys.executable, '"'+sys.executable+'"', '"' + fn + '"', *extra) + else: + os.spawnl(os.P_NOWAIT, sys.executable, sys.executable, fn, *extra) def showFile(self): fn = self.currentFile() @@ -155,6 +176,14 @@ class ExampleLoader(QtGui.QMainWindow): fn = os.path.join(fn, '__main__.py') text = open(fn).read() self.ui.codeView.setPlainText(text) + self.ui.loadedFileLabel.setText(fn) + self.codeBtn.hide() + + def codeEdited(self): + self.codeBtn.show() + + def runEditedCode(self): + self.loadFile(edited=True) def run(): app = QtGui.QApplication([]) diff --git a/examples/exampleLoaderTemplate.ui b/examples/exampleLoaderTemplate.ui index cd5ce921..2da57800 100644 --- a/examples/exampleLoaderTemplate.ui +++ b/examples/exampleLoaderTemplate.ui @@ -6,8 +6,8 @@ 0 0 - 762 - 302 + 623 + 380 @@ -25,7 +25,7 @@ Qt::Horizontal - + @@ -90,19 +90,40 @@ - Load Example + Run Example - - - - Monospace - 10 - - + + + + + + + 75 + true + + + + + + + Qt::AlignCenter + + + + + + + + FreeMono + + + + + diff --git a/examples/exampleLoaderTemplate_pyqt.py b/examples/exampleLoaderTemplate_pyqt.py index f359cc32..836640c6 100644 --- a/examples/exampleLoaderTemplate_pyqt.py +++ b/examples/exampleLoaderTemplate_pyqt.py @@ -1,9 +1,9 @@ # -*- coding: utf-8 -*- -# Form implementation generated from reading ui file './examples/exampleLoaderTemplate.ui' +# Form implementation generated from reading ui file './exampleLoaderTemplate.ui' # -# Created: Mon Dec 24 00:33:38 2012 -# by: PyQt4 UI code generator 4.9.1 +# Created: Mon Feb 25 09:02:09 2013 +# by: PyQt4 UI code generator 4.9.3 # # WARNING! All changes made in this file will be lost! @@ -17,7 +17,7 @@ except AttributeError: class Ui_Form(object): def setupUi(self, Form): Form.setObjectName(_fromUtf8("Form")) - Form.resize(762, 302) + Form.resize(623, 380) self.gridLayout = QtGui.QGridLayout(Form) self.gridLayout.setMargin(0) self.gridLayout.setSpacing(0) @@ -25,46 +25,60 @@ class Ui_Form(object): self.splitter = QtGui.QSplitter(Form) self.splitter.setOrientation(QtCore.Qt.Horizontal) self.splitter.setObjectName(_fromUtf8("splitter")) - self.layoutWidget = QtGui.QWidget(self.splitter) - self.layoutWidget.setObjectName(_fromUtf8("layoutWidget")) - self.verticalLayout = QtGui.QVBoxLayout(self.layoutWidget) + self.widget = QtGui.QWidget(self.splitter) + self.widget.setObjectName(_fromUtf8("widget")) + self.verticalLayout = QtGui.QVBoxLayout(self.widget) self.verticalLayout.setMargin(0) self.verticalLayout.setObjectName(_fromUtf8("verticalLayout")) - self.exampleTree = QtGui.QTreeWidget(self.layoutWidget) + self.exampleTree = QtGui.QTreeWidget(self.widget) self.exampleTree.setObjectName(_fromUtf8("exampleTree")) self.exampleTree.headerItem().setText(0, _fromUtf8("1")) self.exampleTree.header().setVisible(False) self.verticalLayout.addWidget(self.exampleTree) self.horizontalLayout = QtGui.QHBoxLayout() self.horizontalLayout.setObjectName(_fromUtf8("horizontalLayout")) - self.pyqtCheck = QtGui.QCheckBox(self.layoutWidget) + self.pyqtCheck = QtGui.QCheckBox(self.widget) self.pyqtCheck.setObjectName(_fromUtf8("pyqtCheck")) self.horizontalLayout.addWidget(self.pyqtCheck) - self.pysideCheck = QtGui.QCheckBox(self.layoutWidget) + self.pysideCheck = QtGui.QCheckBox(self.widget) self.pysideCheck.setObjectName(_fromUtf8("pysideCheck")) self.horizontalLayout.addWidget(self.pysideCheck) self.verticalLayout.addLayout(self.horizontalLayout) self.horizontalLayout_2 = QtGui.QHBoxLayout() self.horizontalLayout_2.setObjectName(_fromUtf8("horizontalLayout_2")) - self.forceGraphicsCheck = QtGui.QCheckBox(self.layoutWidget) + self.forceGraphicsCheck = QtGui.QCheckBox(self.widget) self.forceGraphicsCheck.setObjectName(_fromUtf8("forceGraphicsCheck")) self.horizontalLayout_2.addWidget(self.forceGraphicsCheck) - self.forceGraphicsCombo = QtGui.QComboBox(self.layoutWidget) + self.forceGraphicsCombo = QtGui.QComboBox(self.widget) self.forceGraphicsCombo.setObjectName(_fromUtf8("forceGraphicsCombo")) self.forceGraphicsCombo.addItem(_fromUtf8("")) self.forceGraphicsCombo.addItem(_fromUtf8("")) self.forceGraphicsCombo.addItem(_fromUtf8("")) self.horizontalLayout_2.addWidget(self.forceGraphicsCombo) self.verticalLayout.addLayout(self.horizontalLayout_2) - self.loadBtn = QtGui.QPushButton(self.layoutWidget) + self.loadBtn = QtGui.QPushButton(self.widget) self.loadBtn.setObjectName(_fromUtf8("loadBtn")) self.verticalLayout.addWidget(self.loadBtn) - self.codeView = QtGui.QTextBrowser(self.splitter) + self.widget1 = QtGui.QWidget(self.splitter) + self.widget1.setObjectName(_fromUtf8("widget1")) + self.verticalLayout_2 = QtGui.QVBoxLayout(self.widget1) + self.verticalLayout_2.setMargin(0) + self.verticalLayout_2.setObjectName(_fromUtf8("verticalLayout_2")) + self.loadedFileLabel = QtGui.QLabel(self.widget1) font = QtGui.QFont() - font.setFamily(_fromUtf8("Monospace")) - font.setPointSize(10) + font.setBold(True) + font.setWeight(75) + self.loadedFileLabel.setFont(font) + self.loadedFileLabel.setText(_fromUtf8("")) + self.loadedFileLabel.setAlignment(QtCore.Qt.AlignCenter) + self.loadedFileLabel.setObjectName(_fromUtf8("loadedFileLabel")) + self.verticalLayout_2.addWidget(self.loadedFileLabel) + self.codeView = QtGui.QPlainTextEdit(self.widget1) + font = QtGui.QFont() + font.setFamily(_fromUtf8("FreeMono")) self.codeView.setFont(font) self.codeView.setObjectName(_fromUtf8("codeView")) + self.verticalLayout_2.addWidget(self.codeView) self.gridLayout.addWidget(self.splitter, 0, 0, 1, 1) self.retranslateUi(Form) @@ -78,5 +92,5 @@ class Ui_Form(object): self.forceGraphicsCombo.setItemText(0, QtGui.QApplication.translate("Form", "native", None, QtGui.QApplication.UnicodeUTF8)) self.forceGraphicsCombo.setItemText(1, QtGui.QApplication.translate("Form", "raster", None, QtGui.QApplication.UnicodeUTF8)) self.forceGraphicsCombo.setItemText(2, QtGui.QApplication.translate("Form", "opengl", None, QtGui.QApplication.UnicodeUTF8)) - self.loadBtn.setText(QtGui.QApplication.translate("Form", "Load Example", None, QtGui.QApplication.UnicodeUTF8)) + self.loadBtn.setText(QtGui.QApplication.translate("Form", "Run Example", None, QtGui.QApplication.UnicodeUTF8)) diff --git a/examples/exampleLoaderTemplate_pyside.py b/examples/exampleLoaderTemplate_pyside.py index 113c1654..f596e566 100644 --- a/examples/exampleLoaderTemplate_pyside.py +++ b/examples/exampleLoaderTemplate_pyside.py @@ -1,9 +1,9 @@ # -*- coding: utf-8 -*- -# Form implementation generated from reading ui file './examples/exampleLoaderTemplate.ui' +# Form implementation generated from reading ui file './exampleLoaderTemplate.ui' # -# Created: Mon Dec 24 00:33:39 2012 -# by: pyside-uic 0.2.13 running on PySide 1.1.2 +# Created: Mon Feb 25 09:02:09 2013 +# by: pyside-uic 0.2.13 running on PySide 1.1.1 # # WARNING! All changes made in this file will be lost! @@ -12,7 +12,7 @@ from PySide import QtCore, QtGui class Ui_Form(object): def setupUi(self, Form): Form.setObjectName("Form") - Form.resize(762, 302) + Form.resize(623, 380) self.gridLayout = QtGui.QGridLayout(Form) self.gridLayout.setContentsMargins(0, 0, 0, 0) self.gridLayout.setSpacing(0) @@ -20,46 +20,60 @@ class Ui_Form(object): self.splitter = QtGui.QSplitter(Form) self.splitter.setOrientation(QtCore.Qt.Horizontal) self.splitter.setObjectName("splitter") - self.layoutWidget = QtGui.QWidget(self.splitter) - self.layoutWidget.setObjectName("layoutWidget") - self.verticalLayout = QtGui.QVBoxLayout(self.layoutWidget) + self.widget = QtGui.QWidget(self.splitter) + self.widget.setObjectName("widget") + self.verticalLayout = QtGui.QVBoxLayout(self.widget) self.verticalLayout.setContentsMargins(0, 0, 0, 0) self.verticalLayout.setObjectName("verticalLayout") - self.exampleTree = QtGui.QTreeWidget(self.layoutWidget) + self.exampleTree = QtGui.QTreeWidget(self.widget) self.exampleTree.setObjectName("exampleTree") self.exampleTree.headerItem().setText(0, "1") self.exampleTree.header().setVisible(False) self.verticalLayout.addWidget(self.exampleTree) self.horizontalLayout = QtGui.QHBoxLayout() self.horizontalLayout.setObjectName("horizontalLayout") - self.pyqtCheck = QtGui.QCheckBox(self.layoutWidget) + self.pyqtCheck = QtGui.QCheckBox(self.widget) self.pyqtCheck.setObjectName("pyqtCheck") self.horizontalLayout.addWidget(self.pyqtCheck) - self.pysideCheck = QtGui.QCheckBox(self.layoutWidget) + self.pysideCheck = QtGui.QCheckBox(self.widget) self.pysideCheck.setObjectName("pysideCheck") self.horizontalLayout.addWidget(self.pysideCheck) self.verticalLayout.addLayout(self.horizontalLayout) self.horizontalLayout_2 = QtGui.QHBoxLayout() self.horizontalLayout_2.setObjectName("horizontalLayout_2") - self.forceGraphicsCheck = QtGui.QCheckBox(self.layoutWidget) + self.forceGraphicsCheck = QtGui.QCheckBox(self.widget) self.forceGraphicsCheck.setObjectName("forceGraphicsCheck") self.horizontalLayout_2.addWidget(self.forceGraphicsCheck) - self.forceGraphicsCombo = QtGui.QComboBox(self.layoutWidget) + self.forceGraphicsCombo = QtGui.QComboBox(self.widget) self.forceGraphicsCombo.setObjectName("forceGraphicsCombo") self.forceGraphicsCombo.addItem("") self.forceGraphicsCombo.addItem("") self.forceGraphicsCombo.addItem("") self.horizontalLayout_2.addWidget(self.forceGraphicsCombo) self.verticalLayout.addLayout(self.horizontalLayout_2) - self.loadBtn = QtGui.QPushButton(self.layoutWidget) + self.loadBtn = QtGui.QPushButton(self.widget) self.loadBtn.setObjectName("loadBtn") self.verticalLayout.addWidget(self.loadBtn) - self.codeView = QtGui.QTextBrowser(self.splitter) + self.widget1 = QtGui.QWidget(self.splitter) + self.widget1.setObjectName("widget1") + self.verticalLayout_2 = QtGui.QVBoxLayout(self.widget1) + self.verticalLayout_2.setContentsMargins(0, 0, 0, 0) + self.verticalLayout_2.setObjectName("verticalLayout_2") + self.loadedFileLabel = QtGui.QLabel(self.widget1) font = QtGui.QFont() - font.setFamily("Monospace") - font.setPointSize(10) + font.setWeight(75) + font.setBold(True) + self.loadedFileLabel.setFont(font) + self.loadedFileLabel.setText("") + self.loadedFileLabel.setAlignment(QtCore.Qt.AlignCenter) + self.loadedFileLabel.setObjectName("loadedFileLabel") + self.verticalLayout_2.addWidget(self.loadedFileLabel) + self.codeView = QtGui.QPlainTextEdit(self.widget1) + font = QtGui.QFont() + font.setFamily("FreeMono") self.codeView.setFont(font) self.codeView.setObjectName("codeView") + self.verticalLayout_2.addWidget(self.codeView) self.gridLayout.addWidget(self.splitter, 0, 0, 1, 1) self.retranslateUi(Form) @@ -73,5 +87,5 @@ class Ui_Form(object): self.forceGraphicsCombo.setItemText(0, QtGui.QApplication.translate("Form", "native", None, QtGui.QApplication.UnicodeUTF8)) self.forceGraphicsCombo.setItemText(1, QtGui.QApplication.translate("Form", "raster", None, QtGui.QApplication.UnicodeUTF8)) self.forceGraphicsCombo.setItemText(2, QtGui.QApplication.translate("Form", "opengl", None, QtGui.QApplication.UnicodeUTF8)) - self.loadBtn.setText(QtGui.QApplication.translate("Form", "Load Example", None, QtGui.QApplication.UnicodeUTF8)) + self.loadBtn.setText(QtGui.QApplication.translate("Form", "Run Example", None, QtGui.QApplication.UnicodeUTF8)) diff --git a/examples/initExample.py b/examples/initExample.py index 204a1ead..d8022aba 100644 --- a/examples/initExample.py +++ b/examples/initExample.py @@ -4,7 +4,10 @@ import sys, os if not hasattr(sys, 'frozen'): - path = os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) + if __file__ == '': + path = os.getcwd() + else: + path = os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) path.rstrip(os.path.sep) if 'pyqtgraph' in os.listdir(path): sys.path.insert(0, path) ## examples adjacent to pyqtgraph (as in source tree) diff --git a/pyqtgraph/graphicsItems/GradientEditorItem.py b/pyqtgraph/graphicsItems/GradientEditorItem.py index 5439c731..955106d8 100644 --- a/pyqtgraph/graphicsItems/GradientEditorItem.py +++ b/pyqtgraph/graphicsItems/GradientEditorItem.py @@ -782,7 +782,8 @@ class GradientEditorItem(TickSliderItem): self.sigGradientChangeFinished.emit(self) -class Tick(GraphicsObject): +class Tick(QtGui.QGraphicsObject): ## NOTE: Making this a subclass of GraphicsObject instead results in + ## activating this bug: https://bugreports.qt-project.org/browse/PYSIDE-86 ## private class sigMoving = QtCore.Signal(object) @@ -802,7 +803,7 @@ class Tick(GraphicsObject): self.pg.lineTo(QtCore.QPointF(scale/3**0.5, scale)) self.pg.closeSubpath() - GraphicsObject.__init__(self) + QtGui.QGraphicsObject.__init__(self) self.setPos(pos[0], pos[1]) if self.movable: self.setZValue(1) diff --git a/pyqtgraph/rebuildUi.py b/tools/rebuildUi.py similarity index 100% rename from pyqtgraph/rebuildUi.py rename to tools/rebuildUi.py From 4cf9ef70ba9f4569b631865ece9c83150ed5da54 Mon Sep 17 00:00:00 2001 From: Luke Campagnola <> Date: Mon, 25 Feb 2013 13:45:24 -0500 Subject: [PATCH 11/11] Fixed modified example code execution --- examples/__main__.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/examples/__main__.py b/examples/__main__.py index 8d60714c..f885920f 100644 --- a/examples/__main__.py +++ b/examples/__main__.py @@ -154,7 +154,8 @@ class ExampleLoader(QtGui.QMainWindow): #os.spawnl(os.P_NOWAIT, sys.executable, sys.executable, fn, *extra) if edited: - proc = subprocess.Popen([sys.executable, '-'] + extra, stdin=subprocess.PIPE) + path = os.path.abspath(os.path.dirname(__file__)) + proc = subprocess.Popen([sys.executable, '-'] + extra, stdin=subprocess.PIPE, cwd=path) code = str(self.ui.codeView.toPlainText()).encode('UTF-8') proc.stdin.write(code) proc.stdin.close()