merged with inp branch

This commit is contained in:
Luke Campagnola 2013-03-07 15:33:59 -05:00
commit 4839998574
75 changed files with 673 additions and 215 deletions

View File

@ -1,11 +1,12 @@
# -*- coding: utf-8 -*- # -*- 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. To place a static arrow anywhere in a scene, use ArrowItem.
## This example uses the CurveArrow class, which is a combination To attach other types of item to a curve, use CurvePoint.
## 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.
import initExample ## Add path to library (just for examples; you do not need this) import initExample ## Add path to library (just for examples; you do not need this)
@ -21,6 +22,7 @@ cw = pg.GraphicsLayoutWidget()
w.show() w.show()
w.resize(400,600) w.resize(400,600)
w.setCentralWidget(cw) w.setCentralWidget(cw)
w.setWindowTitle('pyqtgraph example: Arrow')
p = cw.addPlot(row=0, col=0) p = cw.addPlot(row=0, col=0)
p2 = cw.addPlot(row=1, col=0) p2 = cw.addPlot(row=1, col=0)

View File

@ -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) 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 numpy as np
import pyqtgraph as pg import pyqtgraph as pg
app = QtGui.QApplication([])
data = np.random.normal(size=1000) data = np.random.normal(size=1000)
pg.plot(data, title="Simplest possible plotting example") pg.plot(data, title="Simplest possible plotting example")
data = np.random.normal(size=(500,500)) 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. ## Start Qt event loop unless running in interactive mode or using pyside.
if __name__ == '__main__': if __name__ == '__main__':
import sys import sys
if sys.flags.interactive != 1 or not hasattr(QtCore, 'PYQT_VERSION'): if sys.flags.interactive != 1 or not hasattr(QtCore, 'PYQT_VERSION'):
app.exec_() pg.QtGui.QApplication.exec_()

View File

@ -1,11 +1,12 @@
# -*- coding: utf-8 -*- # -*- 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 Simple example demonstrating a button which displays a colored rectangle
and allows the user to select a new color by clicking on the button. 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 import pyqtgraph as pg
from pyqtgraph.Qt import QtCore, QtGui from pyqtgraph.Qt import QtCore, QtGui
import numpy as np import numpy as np
@ -15,6 +16,7 @@ win = QtGui.QMainWindow()
btn = pg.ColorButton() btn = pg.ColorButton()
win.setCentralWidget(btn) win.setCentralWidget(btn)
win.show() win.show()
win.setWindowTitle('pyqtgraph example: ColorButton')
def change(btn): def change(btn):
print("change", btn.color()) print("change", btn.color())

View File

@ -1,4 +1,10 @@
# -*- coding: utf-8 -*- # -*- 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 initExample ## Add path to library (just for examples; you do not need this)
import pyqtgraph as pg import pyqtgraph as pg
@ -21,6 +27,7 @@ Go, play.
""" """
c = pyqtgraph.console.ConsoleWidget(namespace=namespace, text=text) c = pyqtgraph.console.ConsoleWidget(namespace=namespace, text=text)
c.show() c.show()
c.setWindowTitle('pyqtgraph example: ConsoleWidget')
## Start Qt event loop unless running in interactive mode or using pyside. ## Start Qt event loop unless running in interactive mode or using pyside.
if __name__ == '__main__': if __name__ == '__main__':

View File

@ -1,4 +1,12 @@
# -*- coding: utf-8 -*- # -*- 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) ## Add path to library (just for examples; you do not need this)
import initExample import initExample
@ -12,6 +20,7 @@ app = QtGui.QApplication([])
## Create window with two ImageView widgets ## Create window with two ImageView widgets
win = QtGui.QMainWindow() win = QtGui.QMainWindow()
win.resize(800,800) win.resize(800,800)
win.setWindowTitle('pyqtgraph example: DataSlicing')
cw = QtGui.QWidget() cw = QtGui.QWidget()
win.setCentralWidget(cw) win.setCentralWidget(cw)
l = QtGui.QGridLayout() l = QtGui.QGridLayout()

View File

@ -4,8 +4,6 @@
Simple use of DataTreeWidget to display a structure of nested dicts, lists, and arrays 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 initExample ## Add path to library (just for examples; you do not need this)
import pyqtgraph as pg import pyqtgraph as pg
@ -26,6 +24,7 @@ d = {
tree = pg.DataTreeWidget(data=d) tree = pg.DataTreeWidget(data=d)
tree.show() tree.show()
tree.setWindowTitle('pyqtgraph example: DataTreeWidget')
tree.resize(600,600) tree.resize(600,600)

View File

@ -1,4 +1,10 @@
# -*- coding: utf-8 -*- # -*- 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) 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 = pg.GraphicsView()
w.show() w.show()
w.resize(800,800) w.resize(800,800)
w.setWindowTitle('pyqtgraph example: Draw')
view = pg.ViewBox() view = pg.ViewBox()
w.setCentralItem(view) w.setCentralItem(view)

View File

@ -21,6 +21,7 @@ top = np.linspace(1.0, 3.0, 10)
bottom = np.linspace(2, 0.5, 10) bottom = np.linspace(2, 0.5, 10)
plt = pg.plot() plt = pg.plot()
plt.setWindowTitle('pyqtgraph example: ErrorBarItem')
err = pg.ErrorBarItem(x=x, y=y, top=top, bottom=bottom, beam=0.5) err = pg.ErrorBarItem(x=x, y=y, top=top, bottom=bottom, beam=0.5)
plt.addItem(err) plt.addItem(err)
plt.plot(x, y, symbol='o', pen={'color': 0.8, 'width': 2}) plt.plot(x, y, symbol='o', pen={'color': 0.8, 'width': 2})

View File

@ -23,6 +23,7 @@ app = QtGui.QApplication([])
## Create main window with grid layout ## Create main window with grid layout
win = QtGui.QMainWindow() win = QtGui.QMainWindow()
win.setWindowTitle('pyqtgraph example: Flowchart')
cw = QtGui.QWidget() cw = QtGui.QWidget()
win.setCentralWidget(cw) win.setCentralWidget(cw)
layout = QtGui.QGridLayout() layout = QtGui.QGridLayout()

View File

@ -18,6 +18,7 @@ app = QtGui.QApplication([])
## Create main window with a grid layout inside ## Create main window with a grid layout inside
win = QtGui.QMainWindow() win = QtGui.QMainWindow()
win.setWindowTitle('pyqtgraph example: FlowchartCustomNode')
cw = QtGui.QWidget() cw = QtGui.QWidget()
win.setCentralWidget(cw) win.setCentralWidget(cw)
layout = QtGui.QGridLayout() layout = QtGui.QGridLayout()

View File

@ -1,4 +1,10 @@
# -*- coding: utf-8 -*- # -*- 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) ## Add path to library (just for examples; you do not need this)
import initExample import initExample
@ -12,6 +18,7 @@ app = QtGui.QApplication([])
w = gl.GLViewWidget() w = gl.GLViewWidget()
w.opts['distance'] = 200 w.opts['distance'] = 200
w.show() w.show()
w.setWindowTitle('pyqtgraph example: GLImageItem')
## create volume data set to slice three images from ## create volume data set to slice three images from
shape = (100,100,70) shape = (100,100,70)

View File

@ -1,7 +1,8 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
"""
## This example uses the isosurface function to convert a scalar field This example uses the isosurface function to convert a scalar field
## (a hydrogen orbital) into a mesh for 3D display. (a hydrogen orbital) into a mesh for 3D display.
"""
## Add path to library (just for examples; you do not need this) ## Add path to library (just for examples; you do not need this)
import initExample import initExample
@ -13,6 +14,7 @@ import pyqtgraph.opengl as gl
app = QtGui.QApplication([]) app = QtGui.QApplication([])
w = gl.GLViewWidget() w = gl.GLViewWidget()
w.show() w.show()
w.setWindowTitle('pyqtgraph example: GLIsosurface')
w.setCameraPosition(distance=40) w.setCameraPosition(distance=40)

View File

@ -1,4 +1,8 @@
# -*- coding: utf-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) ## Add path to library (just for examples; you do not need this)
import initExample import initExample
@ -11,6 +15,7 @@ app = QtGui.QApplication([])
w = gl.GLViewWidget() w = gl.GLViewWidget()
w.opts['distance'] = 40 w.opts['distance'] = 40
w.show() w.show()
w.setWindowTitle('pyqtgraph example: GLLinePlotItem')
gx = gl.GLGridItem() gx = gl.GLGridItem()
gx.rotate(90, 0, 1, 0) gx.rotate(90, 0, 1, 0)

View File

@ -14,7 +14,7 @@ import pyqtgraph.opengl as gl
app = QtGui.QApplication([]) app = QtGui.QApplication([])
w = gl.GLViewWidget() w = gl.GLViewWidget()
w.show() w.show()
w.setWindowTitle('pyqtgraph example: GLMeshItem')
w.setCameraPosition(distance=40) w.setCameraPosition(distance=40)
g = gl.GLGridItem() g = gl.GLGridItem()

View File

@ -1,4 +1,9 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
"""
Demonstrates use of GLScatterPlotItem with rapidly-updating plots.
"""
## Add path to library (just for examples; you do not need this) ## Add path to library (just for examples; you do not need this)
import initExample import initExample
@ -10,6 +15,7 @@ app = QtGui.QApplication([])
w = gl.GLViewWidget() w = gl.GLViewWidget()
w.opts['distance'] = 20 w.opts['distance'] = 20
w.show() w.show()
w.setWindowTitle('pyqtgraph example: GLScatterPlotItem')
g = gl.GLGridItem() g = gl.GLGridItem()
w.addItem(g) w.addItem(g)

View File

@ -17,6 +17,7 @@ import numpy as np
app = QtGui.QApplication([]) app = QtGui.QApplication([])
w = gl.GLViewWidget() w = gl.GLViewWidget()
w.show() w.show()
w.setWindowTitle('pyqtgraph example: GLSurfacePlot')
w.setCameraPosition(distance=50) w.setCameraPosition(distance=50)
## Add a grid to the view ## Add a grid to the view

View File

@ -1,4 +1,8 @@
# -*- coding: utf-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) ## Add path to library (just for examples; you do not need this)
import initExample import initExample
@ -9,6 +13,7 @@ app = QtGui.QApplication([])
w = gl.GLViewWidget() w = gl.GLViewWidget()
w.opts['distance'] = 20 w.opts['distance'] = 20
w.show() w.show()
w.setWindowTitle('pyqtgraph example: GLViewWidget')
ax = gl.GLAxisItem() ax = gl.GLAxisItem()
ax.setSize(5,5,5) ax.setSize(5,5,5)

View File

@ -1,4 +1,9 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
"""
Demonstrates GLVolumeItem for displaying volumetric data.
"""
## Add path to library (just for examples; you do not need this) ## Add path to library (just for examples; you do not need this)
import initExample import initExample
@ -9,7 +14,7 @@ app = QtGui.QApplication([])
w = gl.GLViewWidget() w = gl.GLViewWidget()
w.opts['distance'] = 200 w.opts['distance'] = 200
w.show() w.show()
w.setWindowTitle('pyqtgraph example: GLVolumeItem')
#b = gl.GLBoxItem() #b = gl.GLBoxItem()
#w.addItem(b) #w.addItem(b)

View File

@ -1,6 +1,7 @@
# -*- coding: utf-8 -*- # -*- 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([]) app = QtGui.QApplication([])
w = gl.GLViewWidget() w = gl.GLViewWidget()
w.show() w.show()
w.setWindowTitle('pyqtgraph example: GL Shaders')
w.setCameraPosition(distance=15, azimuth=-90) w.setCameraPosition(distance=15, azimuth=-90)
g = gl.GLGridItem() g = gl.GLGridItem()

View File

@ -1,4 +1,9 @@
# -*- coding: utf-8 -*- # -*- 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 initExample ## Add path to library (just for examples; you do not need this)
import pyqtgraph as pg import pyqtgraph as pg
@ -10,6 +15,7 @@ import numpy as np
app = QtGui.QApplication([]) app = QtGui.QApplication([])
w = QtGui.QMainWindow() w = QtGui.QMainWindow()
w.show() w.show()
w.setWindowTitle('pyqtgraph example: GradientWidget')
w.resize(400,400) w.resize(400,400)
cw = QtGui.QWidget() cw = QtGui.QWidget()
w.setCentralWidget(cw) w.setCentralWidget(cw)

View File

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*- # -*- 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 import numpy as np
w = pg.GraphicsWindow() w = pg.GraphicsWindow()
w.setWindowTitle('pyqtgraph example: GraphItem')
v = w.addViewBox() v = w.addViewBox()
v.setAspectLocked() v.setAspectLocked()

View File

@ -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) ## Add path to library (just for examples; you do not need this)
import initExample import initExample
@ -10,6 +17,7 @@ view = pg.GraphicsView()
l = pg.GraphicsLayout(border=(100,100,100)) l = pg.GraphicsLayout(border=(100,100,100))
view.setCentralItem(l) view.setCentralItem(l)
view.show() view.show()
view.setWindowTitle('pyqtgraph example: GraphicsLayout')
view.resize(800,600) view.resize(800,600)
## Title at top ## Title at top

View File

@ -1,4 +1,8 @@
# -*- coding: utf-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) ## Add path to library (just for examples; you do not need this)
import initExample import initExample
@ -12,6 +16,7 @@ app = QtGui.QApplication([])
win = QtGui.QMainWindow() win = QtGui.QMainWindow()
win.resize(800,600) win.resize(800,600)
win.show() win.show()
win.setWindowTitle('pyqtgraph example: Histogram LUT')
cw = QtGui.QWidget() cw = QtGui.QWidget()
win.setCentralWidget(cw) win.setCentralWidget(cw)

View File

@ -1,4 +1,8 @@
# -*- coding: utf-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) ## Add path to library (just for examples; you do not need this)
import initExample import initExample
@ -10,19 +14,17 @@ import pyqtgraph.ptime as ptime
app = QtGui.QApplication([]) app = QtGui.QApplication([])
## Create window with GraphicsView widget ## Create window with GraphicsView widget
view = pg.GraphicsView() win = pg.GraphicsLayoutWidget()
view.show() ## show view alone in its own window win.show() ## show widget alone in its own window
win.setWindowTitle('pyqtgraph example: ImageItem')
## Allow mouse scale/pan. Normally we use a ViewBox for this, but view = win.addViewBox()
## for simple examples this is easier.
view.enableMouse()
## lock the aspect ratio so pixels are always square ## lock the aspect ratio so pixels are always square
view.setAspectLocked(True) view.setAspectLocked(True)
## Create image item ## Create image item
img = pg.ImageItem(border='w') img = pg.ImageItem(border='w')
view.scene().addItem(img) view.addItem(img)
## Set initial view bounds ## Set initial view bounds
view.setRange(QtCore.QRectF(0, 0, 600, 600)) view.setRange(QtCore.QRectF(0, 0, 600, 600))

View File

@ -26,6 +26,7 @@ win.resize(800,800)
imv = pg.ImageView() imv = pg.ImageView()
win.setCentralWidget(imv) win.setCentralWidget(imv)
win.show() win.show()
win.setWindowTitle('pyqtgraph example: ImageView')
## Create random 3D data set with noisy signals ## Create random 3D data set with noisy signals
img = scipy.ndimage.gaussian_filter(np.random.normal(size=(200, 200)), (5, 5)) * 20 + 100 img = scipy.ndimage.gaussian_filter(np.random.normal(size=(200, 200)), (5, 5)) * 20 + 100

View File

@ -1,7 +1,9 @@
# -*- coding: utf-8 -*- # -*- 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. JoystickButton is a button with x/y values. When the button is depressed and the
When the mouse button is released, the x/y values change to 0,0 (rather like litting go of the joystick). 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) 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([]) app = QtGui.QApplication([])
mw = QtGui.QMainWindow() mw = QtGui.QMainWindow()
mw.resize(300,50) mw.resize(300,50)
mw.setWindowTitle('pyqtgraph example: JoystickButton')
cw = QtGui.QWidget() cw = QtGui.QWidget()
mw.setCentralWidget(cw) mw.setCentralWidget(cw)
layout = QtGui.QGridLayout() layout = QtGui.QGridLayout()

View File

@ -1,11 +1,15 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
"""
Demonstrates basic use of LegendItem
"""
import initExample ## Add path to library (just for examples; you do not need this) import initExample ## Add path to library (just for examples; you do not need this)
import pyqtgraph as pg import pyqtgraph as pg
from pyqtgraph.Qt import QtCore, QtGui from pyqtgraph.Qt import QtCore, QtGui
plt = pg.plot() plt = pg.plot()
plt.setWindowTitle('pyqtgraph example: Legend')
plt.addLegend() plt.addLegend()
#l = pg.LegendItem((100,60), offset=(70,30)) # args are (size, offset) #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 #l.setParentItem(plt.graphicsItem()) # Note we do NOT call plt.addItem in this case

View File

@ -1,9 +1,7 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
"""
## This example demonstrates many of the 2D plotting capabilities Simple logarithmic plotting test
## 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) 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 numpy as np
import pyqtgraph as pg import pyqtgraph as pg
#QtGui.QApplication.setGraphicsSystem('raster')
app = QtGui.QApplication([]) app = QtGui.QApplication([])
#mw = QtGui.QMainWindow()
#mw.resize(800,800)
win = pg.GraphicsWindow(title="Basic plotting examples") win = pg.GraphicsWindow(title="Basic plotting examples")
win.resize(1000,600) win.resize(1000,600)
win.setWindowTitle('pyqtgraph example: LogPlotTest')
p5 = win.addPlot(title="Scatter plot, axis labels, log scale") p5 = win.addPlot(title="Scatter plot, axis labels, log scale")

View File

@ -1,5 +1,9 @@
#!/usr/bin/python #!/usr/bin/python
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
"""
Test the speed of rapidly updating multiple plot curves
"""
## Add path to library (just for examples; you do not need this) ## Add path to library (just for examples; you do not need this)
import initExample import initExample
@ -14,6 +18,7 @@ app = QtGui.QApplication([])
#mw.resize(800,800) #mw.resize(800,800)
p = pg.plot() p = pg.plot()
p.setWindowTitle('pyqtgraph example: MultiPlotSpeedTest')
#p.setRange(QtCore.QRectF(0, -10, 5000, 20)) #p.setRange(QtCore.QRectF(0, -10, 5000, 20))
p.setLabel('bottom', 'Index', units='B') p.setLabel('bottom', 'Index', units='B')

View File

@ -1,7 +1,8 @@
# -*- coding: utf-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) 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 = pg.GraphicsWindow(title="Plot auto-range examples")
win.resize(800,600) win.resize(800,600)
win.setWindowTitle('pyqtgraph example: PlotAutoRange')
d = np.random.normal(size=100) d = np.random.normal(size=100)
d[50:54] += 10 d[50:54] += 10

View File

@ -1,5 +1,9 @@
#!/usr/bin/python #!/usr/bin/python
# -*- coding: utf-8 -*- # -*- 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) ## Add path to library (just for examples; you do not need this)
import initExample import initExample
@ -8,12 +12,10 @@ from pyqtgraph.Qt import QtGui, QtCore
import numpy as np import numpy as np
import pyqtgraph as pg import pyqtgraph as pg
from pyqtgraph.ptime import time from pyqtgraph.ptime import time
#QtGui.QApplication.setGraphicsSystem('raster')
app = QtGui.QApplication([]) app = QtGui.QApplication([])
#mw = QtGui.QMainWindow()
#mw.resize(800,800)
p = pg.plot() p = pg.plot()
p.setWindowTitle('pyqtgraph example: PlotSpeedTest')
p.setRange(QtCore.QRectF(0, -10, 5000, 20)) p.setRange(QtCore.QRectF(0, -10, 5000, 20))
p.setLabel('bottom', 'Index', units='B') p.setLabel('bottom', 'Index', units='B')
curve = p.plot() curve = p.plot()

View File

@ -1,4 +1,10 @@
# -*- coding: utf-8 -*- # -*- 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) 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') #QtGui.QApplication.setGraphicsSystem('raster')
app = QtGui.QApplication([]) app = QtGui.QApplication([])
mw = QtGui.QMainWindow() mw = QtGui.QMainWindow()
mw.setWindowTitle('pyqtgraph example: PlotWidget')
mw.resize(800,800) mw.resize(800,800)
cw = QtGui.QWidget() cw = QtGui.QWidget()
mw.setCentralWidget(cw) mw.setCentralWidget(cw)

View File

@ -1,9 +1,9 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
"""
## This example demonstrates many of the 2D plotting capabilities This example demonstrates many of the 2D plotting capabilities
## in pyqtgraph. All of the plots may be panned/scaled by dragging with 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. 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) 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 = pg.GraphicsWindow(title="Basic plotting examples")
win.resize(1000,600) win.resize(1000,600)
win.setWindowTitle('pyqtgraph example: Plotting')

View File

@ -1,4 +1,10 @@
# -*- coding: utf-8 -*- # -*- 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 initExample ## Add path to library (just for examples; you do not need this)
import pyqtgraph as pg import pyqtgraph as pg
@ -22,6 +28,7 @@ arr += np.random.normal(size=(100,100))
## create GUI ## create GUI
app = QtGui.QApplication([]) app = QtGui.QApplication([])
w = pg.GraphicsWindow(size=(800,800), border=True) w = pg.GraphicsWindow(size=(800,800), border=True)
w.setWindowTitle('pyqtgraph example: ROI Examples')
text = """Data Selection From Image.<br>\n text = """Data Selection From Image.<br>\n
Drag an ROI or its handles to update the selected image.<br> Drag an ROI or its handles to update the selected image.<br>

View File

@ -1,18 +1,25 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
"""
Very simple example demonstrating RemoteGraphicsView
"""
import initExample ## Add path to library (just for examples; you do not need this) import initExample ## Add path to library (just for examples; you do not need this)
from pyqtgraph.Qt import QtGui, QtCore from pyqtgraph.Qt import QtGui, QtCore
import pyqtgraph as pg import pyqtgraph as pg
from pyqtgraph.widgets.RemoteGraphicsView import RemoteGraphicsView
app = pg.mkQApp() app = pg.mkQApp()
v = pg.RemoteGraphicsView() v = RemoteGraphicsView()
v.show() 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() plt = v.pg.PlotItem()
v.setCentralItem(plt) v.setCentralItem(plt)
plt.plot([1,4,2,3,6,2,3,4,2,3], pen='g') 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. ## Start Qt event loop unless running in interactive mode or using pyside.
if __name__ == '__main__': if __name__ == '__main__':
import sys import sys

View File

@ -22,6 +22,7 @@ app = pg.mkQApp()
view = pg.widgets.RemoteGraphicsView.RemoteGraphicsView() view = pg.widgets.RemoteGraphicsView.RemoteGraphicsView()
pg.setConfigOptions(antialias=True) ## this will be expensive for the local plot 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.pg.setConfigOptions(antialias=True) ## prettier plots at no cost to the main process!
view.setWindowTitle('pyqtgraph example: RemoteSpeedTest')
label = QtGui.QLabel() label = QtGui.QLabel()
rcheck = QtGui.QCheckBox('plot remote') rcheck = QtGui.QCheckBox('plot remote')

View File

@ -1,4 +1,10 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
"""
Example demonstrating a variety of scatter plot features.
"""
## Add path to library (just for examples; you do not need this) ## Add path to library (just for examples; you do not need this)
import initExample import initExample
@ -12,6 +18,7 @@ mw.resize(800,800)
view = pg.GraphicsLayoutWidget() ## GraphicsView with GraphicsLayout inserted by default view = pg.GraphicsLayoutWidget() ## GraphicsView with GraphicsLayout inserted by default
mw.setCentralWidget(view) mw.setCentralWidget(view)
mw.show() mw.show()
mw.setWindowTitle('pyqtgraph example: ScatterPlot')
## create four areas to add plots ## create four areas to add plots
w1 = view.addPlot() w1 = view.addPlot()

View File

@ -1,5 +1,13 @@
#!/usr/bin/python #!/usr/bin/python
# -*- coding: utf-8 -*- # -*- 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) ## Add path to library (just for examples; you do not need this)
import initExample import initExample
@ -18,6 +26,7 @@ else:
from ScatterPlotSpeedTestTemplate_pyqt import Ui_Form from ScatterPlotSpeedTestTemplate_pyqt import Ui_Form
win = QtGui.QWidget() win = QtGui.QWidget()
win.setWindowTitle('pyqtgraph example: ScatterPlotSpeedTest')
ui = Ui_Form() ui = Ui_Form()
ui.setupUi(win) ui.setupUi(win)
win.show() win.show()

View File

@ -1,4 +1,13 @@
# -*- coding: utf-8 -*- # -*- 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 initExample ## Add path to library (just for examples; you do not need this)
import pyqtgraph as pg import pyqtgraph as pg
@ -20,6 +29,7 @@ spins = [
win = QtGui.QMainWindow() win = QtGui.QMainWindow()
win.setWindowTitle('pyqtgraph example: SpinBox')
cw = QtGui.QWidget() cw = QtGui.QWidget()
layout = QtGui.QGridLayout() layout = QtGui.QGridLayout()
cw.setLayout(layout) cw.setLayout(layout)

34
examples/TableWidget.py Normal file
View File

@ -0,0 +1,34 @@
# -*- coding: utf-8 -*-
"""
Simple demonstration of TableWidget, which is an extension of QTableWidget
that automatically displays a variety of tabluar data formats.
"""
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
app = QtGui.QApplication([])
w = pg.TableWidget()
w.show()
w.resize(500,500)
w.setWindowTitle('pyqtgraph example: TableWidget')
data = np.array([
(1, 1.6, 'x'),
(3, 5.4, 'y'),
(8, 12.5, 'z'),
(443, 1e-12, 'w'),
], dtype=[('Column 1', int), ('Column 2', float), ('Column 3', object)])
w.setData(data)
## 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_()

View File

@ -1,4 +1,8 @@
# -*- coding: utf-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 initExample ## Add path to library (just for examples; you do not need this)
import pyqtgraph as pg import pyqtgraph as pg
@ -11,6 +15,7 @@ app = QtGui.QApplication([])
w = pg.TreeWidget() w = pg.TreeWidget()
w.setColumnCount(2) w.setColumnCount(2)
w.show() w.show()
w.setWindowTitle('pyqtgraph example: TreeWidget')
i1 = QtGui.QTreeWidgetItem(["Item 1"]) i1 = QtGui.QTreeWidgetItem(["Item 1"])
i11 = QtGui.QTreeWidgetItem(["Item 1.1"]) i11 = QtGui.QTreeWidgetItem(["Item 1.1"])

View File

@ -29,6 +29,7 @@ app = QtGui.QApplication([])
#mw.resize(800,800) #mw.resize(800,800)
win = QtGui.QMainWindow() win = QtGui.QMainWindow()
win.setWindowTitle('pyqtgraph example: VideoSpeedTest')
ui = VideoTemplate.Ui_MainWindow() ui = VideoTemplate.Ui_MainWindow()
ui.setupUi(win) ui.setupUi(win)
win.show() win.show()

View File

@ -1,5 +1,14 @@
#!/usr/bin/python #!/usr/bin/python
# -*- coding: utf-8 -*- # -*- 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) ## Add path to library (just for examples; you do not need this)
import initExample import initExample
@ -12,29 +21,22 @@ import pyqtgraph as pg
app = QtGui.QApplication([]) app = QtGui.QApplication([])
mw = QtGui.QMainWindow() mw = QtGui.QMainWindow()
#cw = QtGui.QWidget() mw.setWindowTitle('pyqtgraph example: ViewBox')
#vl = QtGui.QVBoxLayout()
#cw.setLayout(vl)
#mw.setCentralWidget(cw)
mw.show() mw.show()
mw.resize(800, 600) mw.resize(800, 600)
gv = pg.GraphicsView() gv = pg.GraphicsView()
mw.setCentralWidget(gv) mw.setCentralWidget(gv)
#gv.enableMouse(False) ## Mouse interaction will be handled by the ViewBox
l = QtGui.QGraphicsGridLayout() l = QtGui.QGraphicsGridLayout()
l.setHorizontalSpacing(0) l.setHorizontalSpacing(0)
l.setVerticalSpacing(0) l.setVerticalSpacing(0)
#vl.addWidget(gv)
vb = pg.ViewBox() vb = pg.ViewBox()
#grid = pg.GridItem()
#vb.addItem(grid)
p1 = pg.PlotDataItem() p1 = pg.PlotDataItem()
vb.addItem(p1) vb.addItem(p1)
## Just something to play with inside the ViewBox
class movableRect(QtGui.QGraphicsRectItem): class movableRect(QtGui.QGraphicsRectItem):
def __init__(self, *args): def __init__(self, *args):
QtGui.QGraphicsRectItem.__init__(self, *args) QtGui.QGraphicsRectItem.__init__(self, *args)
@ -55,8 +57,6 @@ class movableRect(QtGui.QGraphicsRectItem):
def mouseMoveEvent(self, ev): def mouseMoveEvent(self, ev):
self.setPos(self.mapToParent(ev.pos()) - self.pressDelta) 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 = movableRect(QtCore.QRectF(0, 0, 1, 1))
rect.setPen(QtGui.QPen(QtGui.QColor(100, 200, 100))) rect.setPen(QtGui.QPen(QtGui.QColor(100, 200, 100)))
vb.addItem(rect) vb.addItem(rect)

View File

@ -22,6 +22,7 @@ examples = OrderedDict([
('Dock widgets', 'dockarea.py'), ('Dock widgets', 'dockarea.py'),
('Console', 'ConsoleWidget.py'), ('Console', 'ConsoleWidget.py'),
('Histograms', 'histogram.py'), ('Histograms', 'histogram.py'),
('Auto-range', 'PlotAutoRange.py'),
('Remote Plotting', 'RemoteSpeedTest.py'), ('Remote Plotting', 'RemoteSpeedTest.py'),
('GraphicsItems', OrderedDict([ ('GraphicsItems', OrderedDict([
('Scatter Plot', 'ScatterPlot.py'), ('Scatter Plot', 'ScatterPlot.py'),
@ -38,6 +39,7 @@ examples = OrderedDict([
('Linked Views', 'linkedViews.py'), ('Linked Views', 'linkedViews.py'),
('Arrow', 'Arrow.py'), ('Arrow', 'Arrow.py'),
('ViewBox', 'ViewBox.py'), ('ViewBox', 'ViewBox.py'),
('Custom Graphics', 'customGraphicsItem.py'),
])), ])),
('Benchmarks', OrderedDict([ ('Benchmarks', OrderedDict([
('Video speed test', 'VideoSpeedTest.py'), ('Video speed test', 'VideoSpeedTest.py'),
@ -58,17 +60,18 @@ examples = OrderedDict([
('PlotWidget', 'PlotWidget.py'), ('PlotWidget', 'PlotWidget.py'),
('SpinBox', 'SpinBox.py'), ('SpinBox', 'SpinBox.py'),
('ConsoleWidget', 'ConsoleWidget.py'), ('ConsoleWidget', 'ConsoleWidget.py'),
('Histogram / lookup table', 'HistogramLUT.py'),
('TreeWidget', 'TreeWidget.py'), ('TreeWidget', 'TreeWidget.py'),
('DataTreeWidget', 'DataTreeWidget.py'), ('DataTreeWidget', 'DataTreeWidget.py'),
('GradientWidget', 'GradientWidget.py'), ('GradientWidget', 'GradientWidget.py'),
#('TableWidget', '../widgets/TableWidget.py'), ('TableWidget', 'TableWidget.py'),
('ColorButton', 'ColorButton.py'), ('ColorButton', 'ColorButton.py'),
#('CheckTable', '../widgets/CheckTable.py'), #('CheckTable', '../widgets/CheckTable.py'),
#('VerticalLabel', '../widgets/VerticalLabel.py'), #('VerticalLabel', '../widgets/VerticalLabel.py'),
('JoystickButton', 'JoystickButton.py'), ('JoystickButton', 'JoystickButton.py'),
])), ])),
('GraphicsScene', 'GraphicsScene.py'), #('GraphicsScene', 'GraphicsScene.py'),
('Flowcharts', 'Flowchart.py'), ('Flowcharts', 'Flowchart.py'),
('Custom Flowchart Nodes', 'FlowchartCustomNode.py'), ('Custom Flowchart Nodes', 'FlowchartCustomNode.py'),
#('Canvas', '../canvas'), #('Canvas', '../canvas'),
@ -85,7 +88,15 @@ class ExampleLoader(QtGui.QMainWindow):
self.setCentralWidget(self.cw) self.setCentralWidget(self.cw)
self.ui.setupUi(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 global examples
self.itemCache = []
self.populateTree(self.ui.exampleTree.invisibleRootItem(), examples) self.populateTree(self.ui.exampleTree.invisibleRootItem(), examples)
self.ui.exampleTree.expandAll() self.ui.exampleTree.expandAll()
@ -97,6 +108,8 @@ class ExampleLoader(QtGui.QMainWindow):
self.ui.exampleTree.itemDoubleClicked.connect(self.loadFile) self.ui.exampleTree.itemDoubleClicked.connect(self.loadFile)
self.ui.pyqtCheck.toggled.connect(self.pyqtToggled) self.ui.pyqtCheck.toggled.connect(self.pyqtToggled)
self.ui.pysideCheck.toggled.connect(self.pysideToggled) self.ui.pysideCheck.toggled.connect(self.pysideToggled)
self.ui.codeView.textChanged.connect(self.codeEdited)
self.codeBtn.clicked.connect(self.runEditedCode)
def pyqtToggled(self, b): def pyqtToggled(self, b):
if b: if b:
@ -110,6 +123,9 @@ class ExampleLoader(QtGui.QMainWindow):
def populateTree(self, root, examples): def populateTree(self, root, examples):
for key, val in examples.items(): for key, val in examples.items():
item = QtGui.QTreeWidgetItem([key]) item = QtGui.QTreeWidgetItem([key])
self.itemCache.append(item) # PyQt 4.9.6 no longer keeps references to these wrappers,
# so we need to make an explicit reference or else the .file
# attribute will disappear.
if isinstance(val, basestring): if isinstance(val, basestring):
item.file = val item.file = val
else: else:
@ -124,8 +140,8 @@ class ExampleLoader(QtGui.QMainWindow):
return os.path.join(path, item.file) return os.path.join(path, item.file)
return None return None
def loadFile(self): def loadFile(self, edited=False):
fn = self.currentFile()
extra = [] extra = []
if self.ui.pyqtCheck.isChecked(): if self.ui.pyqtCheck.isChecked():
extra.append('pyqt') extra.append('pyqt')
@ -135,13 +151,26 @@ class ExampleLoader(QtGui.QMainWindow):
if self.ui.forceGraphicsCheck.isChecked(): if self.ui.forceGraphicsCheck.isChecked():
extra.append(str(self.ui.forceGraphicsCombo.currentText())) 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:
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()
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): def showFile(self):
fn = self.currentFile() fn = self.currentFile()
@ -152,6 +181,14 @@ class ExampleLoader(QtGui.QMainWindow):
fn = os.path.join(fn, '__main__.py') fn = os.path.join(fn, '__main__.py')
text = open(fn).read() text = open(fn).read()
self.ui.codeView.setPlainText(text) 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(): def run():
app = QtGui.QApplication([]) app = QtGui.QApplication([])
@ -202,9 +239,13 @@ except:
""" % (import1, graphicsSystem, import2) """ % (import1, graphicsSystem, import2)
process = subprocess.Popen(['exec %s -i' % (exe)], shell=True, stdin=subprocess.PIPE, stderr=subprocess.PIPE, stdout=subprocess.PIPE) if sys.platform.startswith('win'):
process.stdin.write(code.encode('UTF-8')) process = subprocess.Popen([exe], stdin=subprocess.PIPE, stderr=subprocess.PIPE, stdout=subprocess.PIPE)
#process.stdin.close() process.stdin.write(code.encode('UTF-8'))
process.stdin.close()
else:
process = subprocess.Popen(['exec %s -i' % (exe)], shell=True, stdin=subprocess.PIPE, stderr=subprocess.PIPE, stdout=subprocess.PIPE)
process.stdin.write(code.encode('UTF-8'))
output = '' output = ''
fail = False fail = False
while True: while True:

View File

@ -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 initExample ## Add path to library (just for examples; you do not need this)
import numpy as np import numpy as np
import scipy.ndimage as ndi import scipy.ndimage as ndi
@ -5,9 +12,10 @@ import pyqtgraph as pg
from pyqtgraph.Qt import QtGui, QtCore from pyqtgraph.Qt import QtGui, QtCore
from pyqtgraph.Point import Point from pyqtgraph.Point import Point
#genearte layout #generate layout
app = QtGui.QApplication([]) app = QtGui.QApplication([])
win = pg.GraphicsWindow() win = pg.GraphicsWindow()
win.setWindowTitle('pyqtgraph example: crosshair')
label = pg.LabelItem(justify='right') label = pg.LabelItem(justify='right')
win.addItem(label) win.addItem(label)
p1 = win.addPlot(row=1, col=0) p1 = win.addPlot(row=1, col=0)

View File

@ -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 import pyqtgraph as pg
from pyqtgraph import QtCore, QtGui 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): class CandlestickItem(pg.GraphicsObject):
def __init__(self, data): def __init__(self, data):
pg.GraphicsObject.__init__(self) pg.GraphicsObject.__init__(self)
@ -8,6 +17,8 @@ class CandlestickItem(pg.GraphicsObject):
self.generatePicture() self.generatePicture()
def generatePicture(self): 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() self.picture = QtGui.QPicture()
p = QtGui.QPainter(self.picture) p = QtGui.QPainter(self.picture)
p.setPen(pg.mkPen('w')) p.setPen(pg.mkPen('w'))
@ -25,6 +36,9 @@ class CandlestickItem(pg.GraphicsObject):
p.drawPicture(0, 0, self.picture) p.drawPicture(0, 0, self.picture)
def boundingRect(self): 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()) return QtCore.QRectF(self.picture.boundingRect())
data = [ ## fields are (time, open, close, min, max). data = [ ## fields are (time, open, close, min, max).
@ -38,5 +52,10 @@ data = [ ## fields are (time, open, close, min, max).
item = CandlestickItem(data) item = CandlestickItem(data)
plt = pg.plot() plt = pg.plot()
plt.addItem(item) plt.addItem(item)
plt.setWindowTitle('pyqtgraph example: customGraphicsItem')
QtGui.QApplication.exec_() ## 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_()

View File

@ -1,8 +1,8 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
## """
## This example demonstrates the creation of a plot with a customized This example demonstrates the creation of a plot with a customized
## AxisItem and ViewBox. AxisItem and ViewBox.
## """
import initExample ## Add path to library (just for examples; you do not need this) 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) dates = np.arange(8) * (3600*24*356)
pw.plot(x=dates, y=[1,6,2,4,3,5,6,8], symbol='o') pw.plot(x=dates, y=[1,6,2,4,3,5,6,8], symbol='o')
pw.show() pw.show()
pw.setWindowTitle('pyqtgraph example: customPlot')
r = pg.PolyLineROI([(0,0), (10, 10)]) r = pg.PolyLineROI([(0,0), (10, 10)])
pw.addItem(r) pw.addItem(r)

View File

@ -29,6 +29,7 @@ win = QtGui.QMainWindow()
area = DockArea() area = DockArea()
win.setCentralWidget(area) win.setCentralWidget(area)
win.resize(1000,500) win.resize(1000,500)
win.setWindowTitle('pyqtgraph example: dockarea')
## Create docks, place them into the window one at a time. ## Create docks, place them into the window one at a time.
## Note that size arguments are only a suggestion; docks will still have to ## Note that size arguments are only a suggestion; docks will still have to

View File

@ -6,8 +6,8 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>762</width> <width>623</width>
<height>302</height> <height>380</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
@ -25,7 +25,7 @@
<property name="orientation"> <property name="orientation">
<enum>Qt::Horizontal</enum> <enum>Qt::Horizontal</enum>
</property> </property>
<widget class="QWidget" name="layoutWidget"> <widget class="QWidget" name="">
<layout class="QVBoxLayout" name="verticalLayout"> <layout class="QVBoxLayout" name="verticalLayout">
<item> <item>
<widget class="QTreeWidget" name="exampleTree"> <widget class="QTreeWidget" name="exampleTree">
@ -90,19 +90,40 @@
<item> <item>
<widget class="QPushButton" name="loadBtn"> <widget class="QPushButton" name="loadBtn">
<property name="text"> <property name="text">
<string>Load Example</string> <string>Run Example</string>
</property> </property>
</widget> </widget>
</item> </item>
</layout> </layout>
</widget> </widget>
<widget class="QTextBrowser" name="codeView"> <widget class="QWidget" name="">
<property name="font"> <layout class="QVBoxLayout" name="verticalLayout_2">
<font> <item>
<family>Monospace</family> <widget class="QLabel" name="loadedFileLabel">
<pointsize>10</pointsize> <property name="font">
</font> <font>
</property> <weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string/>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QPlainTextEdit" name="codeView">
<property name="font">
<font>
<family>FreeMono</family>
</font>
</property>
</widget>
</item>
</layout>
</widget> </widget>
</widget> </widget>
</item> </item>

View File

@ -1,9 +1,9 @@
# -*- coding: utf-8 -*- # -*- 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 # Created: Mon Feb 25 09:02:09 2013
# by: PyQt4 UI code generator 4.9.1 # by: PyQt4 UI code generator 4.9.3
# #
# WARNING! All changes made in this file will be lost! # WARNING! All changes made in this file will be lost!
@ -17,7 +17,7 @@ except AttributeError:
class Ui_Form(object): class Ui_Form(object):
def setupUi(self, Form): def setupUi(self, Form):
Form.setObjectName(_fromUtf8("Form")) Form.setObjectName(_fromUtf8("Form"))
Form.resize(762, 302) Form.resize(623, 380)
self.gridLayout = QtGui.QGridLayout(Form) self.gridLayout = QtGui.QGridLayout(Form)
self.gridLayout.setMargin(0) self.gridLayout.setMargin(0)
self.gridLayout.setSpacing(0) self.gridLayout.setSpacing(0)
@ -25,46 +25,60 @@ class Ui_Form(object):
self.splitter = QtGui.QSplitter(Form) self.splitter = QtGui.QSplitter(Form)
self.splitter.setOrientation(QtCore.Qt.Horizontal) self.splitter.setOrientation(QtCore.Qt.Horizontal)
self.splitter.setObjectName(_fromUtf8("splitter")) self.splitter.setObjectName(_fromUtf8("splitter"))
self.layoutWidget = QtGui.QWidget(self.splitter) self.widget = QtGui.QWidget(self.splitter)
self.layoutWidget.setObjectName(_fromUtf8("layoutWidget")) self.widget.setObjectName(_fromUtf8("widget"))
self.verticalLayout = QtGui.QVBoxLayout(self.layoutWidget) self.verticalLayout = QtGui.QVBoxLayout(self.widget)
self.verticalLayout.setMargin(0) self.verticalLayout.setMargin(0)
self.verticalLayout.setObjectName(_fromUtf8("verticalLayout")) self.verticalLayout.setObjectName(_fromUtf8("verticalLayout"))
self.exampleTree = QtGui.QTreeWidget(self.layoutWidget) self.exampleTree = QtGui.QTreeWidget(self.widget)
self.exampleTree.setObjectName(_fromUtf8("exampleTree")) self.exampleTree.setObjectName(_fromUtf8("exampleTree"))
self.exampleTree.headerItem().setText(0, _fromUtf8("1")) self.exampleTree.headerItem().setText(0, _fromUtf8("1"))
self.exampleTree.header().setVisible(False) self.exampleTree.header().setVisible(False)
self.verticalLayout.addWidget(self.exampleTree) self.verticalLayout.addWidget(self.exampleTree)
self.horizontalLayout = QtGui.QHBoxLayout() self.horizontalLayout = QtGui.QHBoxLayout()
self.horizontalLayout.setObjectName(_fromUtf8("horizontalLayout")) self.horizontalLayout.setObjectName(_fromUtf8("horizontalLayout"))
self.pyqtCheck = QtGui.QCheckBox(self.layoutWidget) self.pyqtCheck = QtGui.QCheckBox(self.widget)
self.pyqtCheck.setObjectName(_fromUtf8("pyqtCheck")) self.pyqtCheck.setObjectName(_fromUtf8("pyqtCheck"))
self.horizontalLayout.addWidget(self.pyqtCheck) self.horizontalLayout.addWidget(self.pyqtCheck)
self.pysideCheck = QtGui.QCheckBox(self.layoutWidget) self.pysideCheck = QtGui.QCheckBox(self.widget)
self.pysideCheck.setObjectName(_fromUtf8("pysideCheck")) self.pysideCheck.setObjectName(_fromUtf8("pysideCheck"))
self.horizontalLayout.addWidget(self.pysideCheck) self.horizontalLayout.addWidget(self.pysideCheck)
self.verticalLayout.addLayout(self.horizontalLayout) self.verticalLayout.addLayout(self.horizontalLayout)
self.horizontalLayout_2 = QtGui.QHBoxLayout() self.horizontalLayout_2 = QtGui.QHBoxLayout()
self.horizontalLayout_2.setObjectName(_fromUtf8("horizontalLayout_2")) 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.forceGraphicsCheck.setObjectName(_fromUtf8("forceGraphicsCheck"))
self.horizontalLayout_2.addWidget(self.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.setObjectName(_fromUtf8("forceGraphicsCombo"))
self.forceGraphicsCombo.addItem(_fromUtf8("")) self.forceGraphicsCombo.addItem(_fromUtf8(""))
self.forceGraphicsCombo.addItem(_fromUtf8("")) self.forceGraphicsCombo.addItem(_fromUtf8(""))
self.forceGraphicsCombo.addItem(_fromUtf8("")) self.forceGraphicsCombo.addItem(_fromUtf8(""))
self.horizontalLayout_2.addWidget(self.forceGraphicsCombo) self.horizontalLayout_2.addWidget(self.forceGraphicsCombo)
self.verticalLayout.addLayout(self.horizontalLayout_2) self.verticalLayout.addLayout(self.horizontalLayout_2)
self.loadBtn = QtGui.QPushButton(self.layoutWidget) self.loadBtn = QtGui.QPushButton(self.widget)
self.loadBtn.setObjectName(_fromUtf8("loadBtn")) self.loadBtn.setObjectName(_fromUtf8("loadBtn"))
self.verticalLayout.addWidget(self.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 = QtGui.QFont()
font.setFamily(_fromUtf8("Monospace")) font.setBold(True)
font.setPointSize(10) 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.setFont(font)
self.codeView.setObjectName(_fromUtf8("codeView")) self.codeView.setObjectName(_fromUtf8("codeView"))
self.verticalLayout_2.addWidget(self.codeView)
self.gridLayout.addWidget(self.splitter, 0, 0, 1, 1) self.gridLayout.addWidget(self.splitter, 0, 0, 1, 1)
self.retranslateUi(Form) 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(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(1, QtGui.QApplication.translate("Form", "raster", None, QtGui.QApplication.UnicodeUTF8))
self.forceGraphicsCombo.setItemText(2, QtGui.QApplication.translate("Form", "opengl", 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))

View File

@ -1,9 +1,9 @@
# -*- coding: utf-8 -*- # -*- 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 # Created: Mon Feb 25 09:02:09 2013
# by: pyside-uic 0.2.13 running on PySide 1.1.2 # by: pyside-uic 0.2.13 running on PySide 1.1.1
# #
# WARNING! All changes made in this file will be lost! # WARNING! All changes made in this file will be lost!
@ -12,7 +12,7 @@ from PySide import QtCore, QtGui
class Ui_Form(object): class Ui_Form(object):
def setupUi(self, Form): def setupUi(self, Form):
Form.setObjectName("Form") Form.setObjectName("Form")
Form.resize(762, 302) Form.resize(623, 380)
self.gridLayout = QtGui.QGridLayout(Form) self.gridLayout = QtGui.QGridLayout(Form)
self.gridLayout.setContentsMargins(0, 0, 0, 0) self.gridLayout.setContentsMargins(0, 0, 0, 0)
self.gridLayout.setSpacing(0) self.gridLayout.setSpacing(0)
@ -20,46 +20,60 @@ class Ui_Form(object):
self.splitter = QtGui.QSplitter(Form) self.splitter = QtGui.QSplitter(Form)
self.splitter.setOrientation(QtCore.Qt.Horizontal) self.splitter.setOrientation(QtCore.Qt.Horizontal)
self.splitter.setObjectName("splitter") self.splitter.setObjectName("splitter")
self.layoutWidget = QtGui.QWidget(self.splitter) self.widget = QtGui.QWidget(self.splitter)
self.layoutWidget.setObjectName("layoutWidget") self.widget.setObjectName("widget")
self.verticalLayout = QtGui.QVBoxLayout(self.layoutWidget) self.verticalLayout = QtGui.QVBoxLayout(self.widget)
self.verticalLayout.setContentsMargins(0, 0, 0, 0) self.verticalLayout.setContentsMargins(0, 0, 0, 0)
self.verticalLayout.setObjectName("verticalLayout") self.verticalLayout.setObjectName("verticalLayout")
self.exampleTree = QtGui.QTreeWidget(self.layoutWidget) self.exampleTree = QtGui.QTreeWidget(self.widget)
self.exampleTree.setObjectName("exampleTree") self.exampleTree.setObjectName("exampleTree")
self.exampleTree.headerItem().setText(0, "1") self.exampleTree.headerItem().setText(0, "1")
self.exampleTree.header().setVisible(False) self.exampleTree.header().setVisible(False)
self.verticalLayout.addWidget(self.exampleTree) self.verticalLayout.addWidget(self.exampleTree)
self.horizontalLayout = QtGui.QHBoxLayout() self.horizontalLayout = QtGui.QHBoxLayout()
self.horizontalLayout.setObjectName("horizontalLayout") self.horizontalLayout.setObjectName("horizontalLayout")
self.pyqtCheck = QtGui.QCheckBox(self.layoutWidget) self.pyqtCheck = QtGui.QCheckBox(self.widget)
self.pyqtCheck.setObjectName("pyqtCheck") self.pyqtCheck.setObjectName("pyqtCheck")
self.horizontalLayout.addWidget(self.pyqtCheck) self.horizontalLayout.addWidget(self.pyqtCheck)
self.pysideCheck = QtGui.QCheckBox(self.layoutWidget) self.pysideCheck = QtGui.QCheckBox(self.widget)
self.pysideCheck.setObjectName("pysideCheck") self.pysideCheck.setObjectName("pysideCheck")
self.horizontalLayout.addWidget(self.pysideCheck) self.horizontalLayout.addWidget(self.pysideCheck)
self.verticalLayout.addLayout(self.horizontalLayout) self.verticalLayout.addLayout(self.horizontalLayout)
self.horizontalLayout_2 = QtGui.QHBoxLayout() self.horizontalLayout_2 = QtGui.QHBoxLayout()
self.horizontalLayout_2.setObjectName("horizontalLayout_2") self.horizontalLayout_2.setObjectName("horizontalLayout_2")
self.forceGraphicsCheck = QtGui.QCheckBox(self.layoutWidget) self.forceGraphicsCheck = QtGui.QCheckBox(self.widget)
self.forceGraphicsCheck.setObjectName("forceGraphicsCheck") self.forceGraphicsCheck.setObjectName("forceGraphicsCheck")
self.horizontalLayout_2.addWidget(self.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.setObjectName("forceGraphicsCombo")
self.forceGraphicsCombo.addItem("") self.forceGraphicsCombo.addItem("")
self.forceGraphicsCombo.addItem("") self.forceGraphicsCombo.addItem("")
self.forceGraphicsCombo.addItem("") self.forceGraphicsCombo.addItem("")
self.horizontalLayout_2.addWidget(self.forceGraphicsCombo) self.horizontalLayout_2.addWidget(self.forceGraphicsCombo)
self.verticalLayout.addLayout(self.horizontalLayout_2) self.verticalLayout.addLayout(self.horizontalLayout_2)
self.loadBtn = QtGui.QPushButton(self.layoutWidget) self.loadBtn = QtGui.QPushButton(self.widget)
self.loadBtn.setObjectName("loadBtn") self.loadBtn.setObjectName("loadBtn")
self.verticalLayout.addWidget(self.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 = QtGui.QFont()
font.setFamily("Monospace") font.setWeight(75)
font.setPointSize(10) 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.setFont(font)
self.codeView.setObjectName("codeView") self.codeView.setObjectName("codeView")
self.verticalLayout_2.addWidget(self.codeView)
self.gridLayout.addWidget(self.splitter, 0, 0, 1, 1) self.gridLayout.addWidget(self.splitter, 0, 0, 1, 1)
self.retranslateUi(Form) 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(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(1, QtGui.QApplication.translate("Form", "raster", None, QtGui.QApplication.UnicodeUTF8))
self.forceGraphicsCombo.setItemText(2, QtGui.QApplication.translate("Form", "opengl", 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))

View File

@ -12,13 +12,14 @@ import numpy as np
win = pg.GraphicsWindow() win = pg.GraphicsWindow()
win.resize(800,350) win.resize(800,350)
win.setWindowTitle('pyqtgraph example: Histogram')
plt1 = win.addPlot() plt1 = win.addPlot()
plt2 = win.addPlot() plt2 = win.addPlot()
## make interesting distribution of values ## make interesting distribution of values
vals = np.hstack([np.random.normal(size=500), np.random.normal(size=260, loc=4)]) 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)) y,x = np.histogram(vals, bins=np.linspace(-3, 8, 40))
## notice that len(x) == len(y)+1 ## notice that len(x) == len(y)+1

View File

@ -4,7 +4,10 @@
import sys, os import sys, os
if not hasattr(sys, 'frozen'): if not hasattr(sys, 'frozen'):
path = os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) if __file__ == '<stdin>':
path = os.getcwd()
else:
path = os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))
path.rstrip(os.path.sep) path.rstrip(os.path.sep)
if 'pyqtgraph' in os.listdir(path): if 'pyqtgraph' in os.listdir(path):
sys.path.insert(0, path) ## examples adjacent to pyqtgraph (as in source tree) sys.path.insert(0, path) ## examples adjacent to pyqtgraph (as in source tree)

View File

@ -22,6 +22,7 @@ data = ndi.gaussian_filter(data, (10, 10, 10))[frames/2:frames + frames/2]
data[:, 15:16, 15:17] += 1 data[:, 15:16, 15:17] += 1
win = pg.GraphicsWindow() win = pg.GraphicsWindow()
win.setWindowTitle('pyqtgraph example: Isocurve')
vb = win.addViewBox() vb = win.addViewBox()
img = pg.ImageItem(data[0]) img = pg.ImageItem(data[0])
vb.addItem(img) vb.addItem(img)

View File

@ -1,8 +1,9 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
"""
## This example demonstrates the ability to link the axes of views together 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. 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) 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) x = np.linspace(-50, 50, 1000)
y = np.sin(x) / x 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.resize(800,600)
win.addLabel("Linked Views", colspan=2) win.addLabel("Linked Views", colspan=2)

View File

@ -1,5 +1,7 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
"""
Test programmatically setting log transformation modes.
"""
import initExample ## Add path to library (just for examples; you do not need this) import initExample ## Add path to library (just for examples; you do not need this)
import numpy as np import numpy as np
@ -10,6 +12,7 @@ import pyqtgraph as pg
app = QtGui.QApplication([]) app = QtGui.QApplication([])
w = pg.GraphicsWindow() w = pg.GraphicsWindow()
w.setWindowTitle('pyqtgraph example: logAxis')
p1 = w.addPlot(0,0, title="X Semilog") p1 = w.addPlot(0,0, title="X Semilog")
p2 = w.addPlot(1,0, title="Y Semilog") p2 = w.addPlot(1,0, title="Y Semilog")
p3 = w.addPlot(2,0, title="XY Log") p3 = w.addPlot(2,0, title="XY Log")

View File

@ -39,7 +39,7 @@ def plot():
#plt.addItem(item) #plt.addItem(item)
dt = pg.ptime.time() - start 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 ## Plot and clear 5 times, printing the time it took
for i in range(5): for i in range(5):
@ -72,7 +72,7 @@ def fastPlot():
plt.addItem(item) plt.addItem(item)
dt = pg.ptime.time() - start 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 ## Plot and clear 5 times, printing the time it took
@ -82,7 +82,7 @@ if hasattr(pg, 'arrayToQPath'):
fastPlot() fastPlot()
app.processEvents() app.processEvents()
else: else:
print "Skipping fast tests--arrayToQPath function is missing." print("Skipping fast tests--arrayToQPath function is missing.")
plt.autoRange() plt.autoRange()

View File

@ -140,6 +140,7 @@ p.param('Save/Restore functionality', 'Restore State').sigActivated.connect(rest
t = ParameterTree() t = ParameterTree()
t.setParameters(p, showTop=False) t.setParameters(p, showTop=False)
t.show() t.show()
t.setWindowTitle('pyqtgraph example: Parameter Tree')
t.resize(400,800) t.resize(400,800)
t2 = ParameterTree() t2 = ParameterTree()
t2.setParameters(p, showTop=False) t2.setParameters(p, showTop=False)

View File

@ -1,10 +1,18 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
"""
Description of example
"""
import initExample ## Add path to library (just for examples; you do not need this) import initExample ## Add path to library (just for examples; you do not need this)
import pyqtgraph as pg import pyqtgraph as pg
from pyqtgraph.Qt import QtCore, QtGui from pyqtgraph.Qt import QtCore, QtGui
import numpy as np import numpy as np
# win.setWindowTitle('pyqtgraph example: ____')
## Start Qt event loop unless running in interactive mode or using pyside. ## Start Qt event loop unless running in interactive mode or using pyside.
if __name__ == '__main__': if __name__ == '__main__':
import sys import sys

View File

@ -1,6 +1,12 @@
# -*- coding: utf-8 -*- # -*- 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) 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 y = np.sin(x) / x
plot = pg.plot() ## create an empty plot widget plot = pg.plot() ## create an empty plot widget
plot.setYRange(-1, 2) plot.setYRange(-1, 2)
plot.setWindowTitle('pyqtgraph example: text')
curve = plot.plot(x,y) ## add a single curve curve = plot.plot(x,y) ## add a single curve
## Create text object, use HTML tags to specify color/size ## Create text object, use HTML tags to specify color/size

View File

@ -34,8 +34,12 @@ class ExportDialog(QtGui.QWidget):
def show(self, item=None): def show(self, item=None):
if item is not 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: while not isinstance(item, pg.ViewBox) and not isinstance(item, pg.PlotItem) and item is not None:
item = item.parentItem() 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.updateItemList(select=item)
self.setVisible(True) self.setVisible(True)
self.activateWindow() self.activateWindow()

View File

@ -55,6 +55,7 @@ CONFIG_OPTIONS = {
'useWeave': True, ## Use weave to speed up some operations, if it is available 'useWeave': True, ## Use weave to speed up some operations, if it is available
'weaveDebug': False, ## Print full error message if weave compile fails 'weaveDebug': False, ## Print full error message if weave compile fails
'exitCleanup': True, ## Attempt to work around some exit crash bugs in PyQt and PySide 'exitCleanup': True, ## Attempt to work around some exit crash bugs in PyQt and PySide
'enableExperimental': False, ## Enable experimental features (the curious can search for this key in the code)
} }

View File

@ -10,7 +10,7 @@ as it can be converted to/from a string using repr and eval.
""" """
import re, os, sys import re, os, sys
from pgcollections import OrderedDict from .pgcollections import OrderedDict
GLOBAL_PATH = None # so not thread safe. GLOBAL_PATH = None # so not thread safe.
from . import units from . import units
from .python2_3 import asUnicode from .python2_3 import asUnicode
@ -199,4 +199,4 @@ key2: ##comment
print("============") print("============")
data = readConfigFile(fn) data = readConfigFile(fn)
print(data) print(data)
os.remove(fn) os.remove(fn)

View File

@ -14,6 +14,7 @@ class CSVExporter(Exporter):
Exporter.__init__(self, item) Exporter.__init__(self, item)
self.params = Parameter(name='params', type='group', children=[ self.params = Parameter(name='params', type='group', children=[
{'name': 'separator', 'type': 'list', 'value': 'comma', 'values': ['comma', 'tab']}, {'name': 'separator', 'type': 'list', 'value': 'comma', 'values': ['comma', 'tab']},
{'name': 'precision', 'type': 'int', 'value': 10, 'limits': [0, None]},
]) ])
def parameters(self): def parameters(self):
@ -42,18 +43,15 @@ class CSVExporter(Exporter):
fd.write(sep.join(header) + '\n') fd.write(sep.join(header) + '\n')
i = 0 i = 0
while True: numFormat = '%%0.%dg' % self.params['precision']
done = True numRows = reduce(max, [len(d[0]) for d in data])
for i in range(numRows):
for d in data: for d in data:
if i < len(d[0]): if i < len(d[0]):
fd.write('%g%s%g%s'%(d[0][i], sep, d[1][i], sep)) fd.write(numFormat % d[0][i] + sep + numFormat % d[1][i] + sep)
done = False
else: else:
fd.write(' %s %s' % (sep, sep)) fd.write(' %s %s' % (sep, sep))
fd.write('\n') fd.write('\n')
if done:
break
i += 1
fd.close() fd.close()

View File

@ -90,7 +90,7 @@
<customwidget> <customwidget>
<class>FlowchartGraphicsView</class> <class>FlowchartGraphicsView</class>
<extends>QGraphicsView</extends> <extends>QGraphicsView</extends>
<header>FlowchartGraphicsView</header> <header>pyqtgraph.flowchart.FlowchartGraphicsView</header>
</customwidget> </customwidget>
</customwidgets> </customwidgets>
<resources/> <resources/>

View File

@ -2,8 +2,8 @@
# Form implementation generated from reading ui file './flowchart/FlowchartTemplate.ui' # Form implementation generated from reading ui file './flowchart/FlowchartTemplate.ui'
# #
# Created: Sun Sep 9 14:41:29 2012 # Created: Sun Feb 24 19:47:29 2013
# by: PyQt4 UI code generator 4.9.1 # by: PyQt4 UI code generator 4.9.3
# #
# WARNING! All changes made in this file will be lost! # 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)) Form.setWindowTitle(QtGui.QApplication.translate("Form", "Form", None, QtGui.QApplication.UnicodeUTF8))
from pyqtgraph.widgets.DataTreeWidget import DataTreeWidget from pyqtgraph.widgets.DataTreeWidget import DataTreeWidget
from FlowchartGraphicsView import FlowchartGraphicsView from pyqtgraph.flowchart.FlowchartGraphicsView import FlowchartGraphicsView

View File

@ -2,8 +2,8 @@
# Form implementation generated from reading ui file './flowchart/FlowchartTemplate.ui' # Form implementation generated from reading ui file './flowchart/FlowchartTemplate.ui'
# #
# Created: Sun Sep 9 14:41:30 2012 # Created: Sun Feb 24 19:47:30 2013
# by: pyside-uic 0.2.13 running on PySide 1.1.0 # by: pyside-uic 0.2.13 running on PySide 1.1.1
# #
# WARNING! All changes made in this file will be lost! # 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)) Form.setWindowTitle(QtGui.QApplication.translate("Form", "Form", None, QtGui.QApplication.UnicodeUTF8))
from pyqtgraph.widgets.DataTreeWidget import DataTreeWidget from pyqtgraph.widgets.DataTreeWidget import DataTreeWidget
from FlowchartGraphicsView import FlowchartGraphicsView from pyqtgraph.flowchart.FlowchartGraphicsView import FlowchartGraphicsView

View File

@ -1109,10 +1109,15 @@ def arrayToQPath(x, y, connect='all'):
arr.data[lastInd:lastInd+4] = struct.pack('>i', 0) arr.data[lastInd:lastInd+4] = struct.pack('>i', 0)
#prof.mark('footer') #prof.mark('footer')
# create datastream object and stream into path # create datastream object and stream into path
buf = QtCore.QByteArray(arr.data[12:lastInd+4]) # I think one unnecessary copy happens here
## Avoiding this method because QByteArray(str) leaks memory in PySide
#buf = QtCore.QByteArray(arr.data[12:lastInd+4]) # I think one unnecessary copy happens here
path.strn = arr.data[12:lastInd+4] # make sure data doesn't run away
buf = QtCore.QByteArray.fromRawData(path.strn)
#prof.mark('create buffer') #prof.mark('create buffer')
ds = QtCore.QDataStream(buf) ds = QtCore.QDataStream(buf)
#prof.mark('create datastream')
ds >> path ds >> path
#prof.mark('load') #prof.mark('load')

View File

@ -309,10 +309,18 @@ class AxisItem(GraphicsWidget):
oldView.sigXRangeChanged.disconnect(self.linkedViewChanged) oldView.sigXRangeChanged.disconnect(self.linkedViewChanged)
view.sigXRangeChanged.connect(self.linkedViewChanged) view.sigXRangeChanged.connect(self.linkedViewChanged)
def linkedViewChanged(self, view, newRange): if oldView is not None:
oldView.sigResized.disconnect(self.linkedViewChanged)
view.sigResized.connect(self.linkedViewChanged)
def linkedViewChanged(self, view, newRange=None):
if self.orientation in ['right', 'left'] and view.yInverted(): if self.orientation in ['right', 'left'] and view.yInverted():
if newRange is None:
newRange = view.viewRange()[1]
self.setRange(*newRange[::-1]) self.setRange(*newRange[::-1])
else: else:
if newRange is None:
newRange = view.viewRange()[0]
self.setRange(*newRange) self.setRange(*newRange)
def boundingRect(self): def boundingRect(self):

View File

@ -782,7 +782,8 @@ class GradientEditorItem(TickSliderItem):
self.sigGradientChangeFinished.emit(self) 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 ## private class
sigMoving = QtCore.Signal(object) sigMoving = QtCore.Signal(object)
@ -802,7 +803,7 @@ class Tick(GraphicsObject):
self.pg.lineTo(QtCore.QPointF(scale/3**0.5, scale)) self.pg.lineTo(QtCore.QPointF(scale/3**0.5, scale))
self.pg.closeSubpath() self.pg.closeSubpath()
GraphicsObject.__init__(self) QtGui.QGraphicsObject.__init__(self)
self.setPos(pos[0], pos[1]) self.setPos(pos[0], pos[1])
if self.movable: if self.movable:
self.setZValue(1) self.setZValue(1)

View File

@ -1,4 +1,10 @@
from pyqtgraph.Qt import QtGui, QtCore from pyqtgraph.Qt import QtGui, QtCore
try:
from pyqtgraph.Qt import QtOpenGL
HAVE_OPENGL = True
except:
HAVE_OPENGL = False
from scipy.fftpack import fft from scipy.fftpack import fft
import numpy as np import numpy as np
import scipy.stats import scipy.stats
@ -370,12 +376,11 @@ class PlotCurveItem(GraphicsObject):
prof = debug.Profiler('PlotCurveItem.paint '+str(id(self)), disabled=True) prof = debug.Profiler('PlotCurveItem.paint '+str(id(self)), disabled=True)
if self.xData is None: if self.xData is None:
return return
#if self.opts['spectrumMode']:
#if self.specPath is None: if HAVE_OPENGL and pg.getConfigOption('enableExperimental') and isinstance(widget, QtOpenGL.QGLWidget):
self.paintGL(p, opt, widget)
#self.specPath = self.generatePath(*self.getData()) return
#path = self.specPath
#else:
x = None x = None
y = None y = None
if self.path is None: if self.path is None:
@ -385,7 +390,6 @@ class PlotCurveItem(GraphicsObject):
self.path = self.generatePath(x,y) self.path = self.generatePath(x,y)
self.fillPath = None self.fillPath = None
path = self.path path = self.path
prof.mark('generate path') prof.mark('generate path')
@ -440,6 +444,65 @@ class PlotCurveItem(GraphicsObject):
#p.setPen(QtGui.QPen(QtGui.QColor(255,0,0))) #p.setPen(QtGui.QPen(QtGui.QColor(255,0,0)))
#p.drawRect(self.boundingRect()) #p.drawRect(self.boundingRect())
def paintGL(self, p, opt, widget):
p.beginNativePainting()
import OpenGL.GL as gl
## set clipping viewport
view = self.getViewBox()
if view is not None:
rect = view.mapRectToItem(self, view.boundingRect())
#gl.glViewport(int(rect.x()), int(rect.y()), int(rect.width()), int(rect.height()))
#gl.glTranslate(-rect.x(), -rect.y(), 0)
gl.glEnable(gl.GL_STENCIL_TEST)
gl.glColorMask(gl.GL_FALSE, gl.GL_FALSE, gl.GL_FALSE, gl.GL_FALSE) # disable drawing to frame buffer
gl.glDepthMask(gl.GL_FALSE) # disable drawing to depth buffer
gl.glStencilFunc(gl.GL_NEVER, 1, 0xFF)
gl.glStencilOp(gl.GL_REPLACE, gl.GL_KEEP, gl.GL_KEEP)
## draw stencil pattern
gl.glStencilMask(0xFF);
gl.glClear(gl.GL_STENCIL_BUFFER_BIT)
gl.glBegin(gl.GL_TRIANGLES)
gl.glVertex2f(rect.x(), rect.y())
gl.glVertex2f(rect.x()+rect.width(), rect.y())
gl.glVertex2f(rect.x(), rect.y()+rect.height())
gl.glVertex2f(rect.x()+rect.width(), rect.y()+rect.height())
gl.glVertex2f(rect.x()+rect.width(), rect.y())
gl.glVertex2f(rect.x(), rect.y()+rect.height())
gl.glEnd()
gl.glColorMask(gl.GL_TRUE, gl.GL_TRUE, gl.GL_TRUE, gl.GL_TRUE)
gl.glDepthMask(gl.GL_TRUE)
gl.glStencilMask(0x00)
gl.glStencilFunc(gl.GL_EQUAL, 1, 0xFF)
try:
x, y = self.getData()
pos = np.empty((len(x), 2))
pos[:,0] = x
pos[:,1] = y
gl.glEnableClientState(gl.GL_VERTEX_ARRAY)
try:
gl.glVertexPointerf(pos)
pen = fn.mkPen(self.opts['pen'])
color = pen.color()
gl.glColor4f(color.red()/255., color.green()/255., color.blue()/255., color.alpha()/255.)
width = pen.width()
if pen.isCosmetic() and width < 1:
width = 1
gl.glPointSize(width)
gl.glEnable(gl.GL_LINE_SMOOTH)
gl.glEnable(gl.GL_BLEND)
gl.glBlendFunc(gl.GL_SRC_ALPHA, gl.GL_ONE_MINUS_SRC_ALPHA)
gl.glHint(gl.GL_LINE_SMOOTH_HINT, gl.GL_NICEST);
gl.glDrawArrays(gl.GL_LINE_STRIP, 0, pos.size / pos.shape[-1])
finally:
gl.glDisableClientState(gl.GL_VERTEX_ARRAY)
finally:
p.endNativePainting()
def clear(self): def clear(self):
self.xData = None ## raw values self.xData = None ## raw values

View File

@ -495,8 +495,8 @@ class ScatterPlotItem(GraphicsObject):
if isinstance(size, np.ndarray) or isinstance(size, list): if isinstance(size, np.ndarray) or isinstance(size, list):
sizes = size sizes = size
if kargs['mask'] is not None: if mask is not None:
sizes = sizes[kargs['mask']] sizes = sizes[mask]
if len(sizes) != len(dataSet): if len(sizes) != len(dataSet):
raise Exception("Number of sizes does not match number of points (%d != %d)" % (len(sizes), len(dataSet))) raise Exception("Number of sizes does not match number of points (%d != %d)" % (len(sizes), len(dataSet)))
dataSet['size'] = sizes dataSet['size'] = sizes
@ -508,13 +508,13 @@ class ScatterPlotItem(GraphicsObject):
if update: if update:
self.updateSpots(dataSet) self.updateSpots(dataSet)
def setPointData(self, data, dataSet=None): def setPointData(self, data, dataSet=None, mask=None):
if dataSet is None: if dataSet is None:
dataSet = self.data dataSet = self.data
if isinstance(data, np.ndarray) or isinstance(data, list): if isinstance(data, np.ndarray) or isinstance(data, list):
if kargs['mask'] is not None: if mask is not None:
data = data[kargs['mask']] data = data[mask]
if len(data) != len(dataSet): if len(data) != len(dataSet):
raise Exception("Length of meta data does not match number of points (%d != %d)" % (len(data), len(dataSet))) raise Exception("Length of meta data does not match number of points (%d != %d)" % (len(data), len(dataSet)))
@ -683,6 +683,9 @@ class ScatterPlotItem(GraphicsObject):
rec = self.data[i] rec = self.data[i]
pos = QtCore.QPointF(pts[0,i], pts[1,i]) pos = QtCore.QPointF(pts[0,i], pts[1,i])
x,y,w,h = rec['fragCoords'] x,y,w,h = rec['fragCoords']
if abs(w) > 10000 or abs(h) > 10000:
print self.data
raise Exception("fragment corrupt")
rect = QtCore.QRectF(y, x, h, w) rect = QtCore.QRectF(y, x, h, w)
self.fragments.append(QtGui.QPainter.PixmapFragment.create(pos, rect)) self.fragments.append(QtGui.QPainter.PixmapFragment.create(pos, rect))

View File

@ -50,6 +50,7 @@ class ViewBox(GraphicsWidget):
#sigActionPositionChanged = QtCore.Signal(object) #sigActionPositionChanged = QtCore.Signal(object)
sigStateChanged = QtCore.Signal(object) sigStateChanged = QtCore.Signal(object)
sigTransformChanged = QtCore.Signal(object) sigTransformChanged = QtCore.Signal(object)
sigResized = QtCore.Signal(object)
## mouse modes ## mouse modes
PanMode = 3 PanMode = 3
@ -304,6 +305,7 @@ class ViewBox(GraphicsWidget):
#self._itemBoundsCache.clear() #self._itemBoundsCache.clear()
#self.linkedXChanged() #self.linkedXChanged()
#self.linkedYChanged() #self.linkedYChanged()
self.sigResized.emit(self)
def viewRange(self): def viewRange(self):
"""Return a the view's visible range as a list: [[xmin, xmax], [ymin, ymax]]""" """Return a the view's visible range as a list: [[xmin, xmax], [ymin, ymax]]"""
@ -451,7 +453,7 @@ class ViewBox(GraphicsWidget):
if item is None: if item is None:
bounds = self.childrenBoundingRect(items=items) bounds = self.childrenBoundingRect(items=items)
else: 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() bounds = self.mapFromItemToView(item, item.boundingRect()).boundingRect()
if bounds is not None: if bounds is not None:
@ -1046,10 +1048,10 @@ class ViewBox(GraphicsWidget):
xr = item.dataBounds(0, frac=frac[0], orthoRange=orthoRange[0]) xr = item.dataBounds(0, frac=frac[0], orthoRange=orthoRange[0])
yr = item.dataBounds(1, frac=frac[1], orthoRange=orthoRange[1]) yr = item.dataBounds(1, frac=frac[1], orthoRange=orthoRange[1])
pxPad = 0 if not hasattr(item, 'pixelPadding') else item.pixelPadding() pxPad = 0 if not hasattr(item, 'pixelPadding') else item.pixelPadding()
if xr is None or (xr[0] is None and xr[1] is None): if xr is None or (xr[0] is None and xr[1] is None) or np.isnan(xr).any() or np.isinf(xr).any():
useX = False useX = False
xr = (0,0) xr = (0,0)
if yr is None or (yr[0] is None and yr[1] is None): if yr is None or (yr[0] is None and yr[1] is None) or np.isnan(yr).any() or np.isinf(yr).any():
useY = False useY = False
yr = (0,0) yr = (0,0)

View File

@ -6,27 +6,26 @@ import numpy as np
try: try:
import metaarray import metaarray
HAVE_METAARRAY = True HAVE_METAARRAY = True
except: except ImportError:
HAVE_METAARRAY = False HAVE_METAARRAY = False
__all__ = ['TableWidget'] __all__ = ['TableWidget']
class TableWidget(QtGui.QTableWidget): class TableWidget(QtGui.QTableWidget):
"""Extends QTableWidget with some useful functions for automatic data handling """Extends QTableWidget with some useful functions for automatic data handling
and copy / export context menu. Can automatically format and display: and copy / export context menu. Can automatically format and display a variety
of data types (see :func:`setData() <pyqtgraph.TableWidget.setData>` for more
- numpy arrays information.
- numpy record arrays
- metaarrays
- list-of-lists [[1,2,3], [4,5,6]]
- dict-of-lists {'x': [1,2,3], 'y': [4,5,6]}
- list-of-dicts [{'x': 1, 'y': 4}, {'x': 2, 'y': 5}, ...]
""" """
def __init__(self, *args): def __init__(self, *args, **kwds):
QtGui.QTableWidget.__init__(self, *args) QtGui.QTableWidget.__init__(self, *args)
self.setVerticalScrollMode(self.ScrollPerPixel) self.setVerticalScrollMode(self.ScrollPerPixel)
self.setSelectionMode(QtGui.QAbstractItemView.ContiguousSelection) self.setSelectionMode(QtGui.QAbstractItemView.ContiguousSelection)
self.setSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Preferred)
self.setSortingEnabled(True)
self.clear() self.clear()
editable = kwds.get('editable', False)
self.setEditable(editable)
self.contextMenu = QtGui.QMenu() self.contextMenu = QtGui.QMenu()
self.contextMenu.addAction('Copy Selection').triggered.connect(self.copySel) self.contextMenu.addAction('Copy Selection').triggered.connect(self.copySel)
self.contextMenu.addAction('Copy All').triggered.connect(self.copyAll) self.contextMenu.addAction('Copy All').triggered.connect(self.copyAll)
@ -34,6 +33,7 @@ class TableWidget(QtGui.QTableWidget):
self.contextMenu.addAction('Save All').triggered.connect(self.saveAll) self.contextMenu.addAction('Save All').triggered.connect(self.saveAll)
def clear(self): def clear(self):
"""Clear all contents from the table."""
QtGui.QTableWidget.clear(self) QtGui.QTableWidget.clear(self)
self.verticalHeadersSet = False self.verticalHeadersSet = False
self.horizontalHeadersSet = False self.horizontalHeadersSet = False
@ -42,8 +42,19 @@ class TableWidget(QtGui.QTableWidget):
self.setColumnCount(0) self.setColumnCount(0)
def setData(self, data): def setData(self, data):
"""Set the data displayed in the table.
Allowed formats are:
* numpy arrays
* numpy record arrays
* metaarrays
* list-of-lists [[1,2,3], [4,5,6]]
* dict-of-lists {'x': [1,2,3], 'y': [4,5,6]}
* list-of-dicts [{'x': 1, 'y': 4}, {'x': 2, 'y': 5}, ...]
"""
self.clear() self.clear()
self.appendData(data) self.appendData(data)
self.resizeColumnsToContents()
def appendData(self, data): def appendData(self, data):
"""Types allowed: """Types allowed:
@ -60,26 +71,19 @@ class TableWidget(QtGui.QTableWidget):
first = next(it0) first = next(it0)
except StopIteration: except StopIteration:
return return
#if type(first) == type(np.float64(1)):
# return
fn1, header1 = self.iteratorFn(first) fn1, header1 = self.iteratorFn(first)
if fn1 is None: if fn1 is None:
self.clear() self.clear()
return return
#print fn0, header0
#print fn1, header1
firstVals = [x for x in fn1(first)] firstVals = [x for x in fn1(first)]
self.setColumnCount(len(firstVals)) self.setColumnCount(len(firstVals))
#print header0, header1
if not self.verticalHeadersSet and header0 is not None: if not self.verticalHeadersSet and header0 is not None:
#print "set header 0:", header0
self.setRowCount(len(header0)) self.setRowCount(len(header0))
self.setVerticalHeaderLabels(header0) self.setVerticalHeaderLabels(header0)
self.verticalHeadersSet = True self.verticalHeadersSet = True
if not self.horizontalHeadersSet and header1 is not None: if not self.horizontalHeadersSet and header1 is not None:
#print "set header 1:", header1
self.setHorizontalHeaderLabels(header1) self.setHorizontalHeaderLabels(header1)
self.horizontalHeadersSet = True self.horizontalHeadersSet = True
@ -88,10 +92,15 @@ class TableWidget(QtGui.QTableWidget):
for row in it0: for row in it0:
self.setRow(i, [x for x in fn1(row)]) self.setRow(i, [x for x in fn1(row)])
i += 1 i += 1
def setEditable(self, editable=True):
self.editable = editable
for item in self.items:
item.setEditable(editable)
def iteratorFn(self, data): def iteratorFn(self, data):
"""Return 1) a function that will provide an iterator for data and 2) a list of header strings""" ## Return 1) a function that will provide an iterator for data and 2) a list of header strings
if isinstance(data, list): if isinstance(data, list) or isinstance(data, tuple):
return lambda d: d.__iter__(), None return lambda d: d.__iter__(), None
elif isinstance(data, dict): elif isinstance(data, dict):
return lambda d: iter(d.values()), list(map(str, data.keys())) return lambda d: iter(d.values()), list(map(str, data.keys()))
@ -110,13 +119,16 @@ class TableWidget(QtGui.QTableWidget):
elif data is None: elif data is None:
return (None,None) return (None,None)
else: else:
raise Exception("Don't know how to iterate over data type: %s" % str(type(data))) msg = "Don't know how to iterate over data type: {!s}".format(type(data))
raise TypeError(msg)
def iterFirstAxis(self, data): def iterFirstAxis(self, data):
for i in range(data.shape[0]): for i in range(data.shape[0]):
yield data[i] yield data[i]
def iterate(self, data): ## for numpy.void, which can be iterated but mysteriously has no __iter__ (??) def iterate(self, data):
# for numpy.void, which can be iterated but mysteriously
# has no __iter__ (??)
for x in data: for x in data:
yield x yield x
@ -124,32 +136,39 @@ class TableWidget(QtGui.QTableWidget):
self.appendData([data]) self.appendData([data])
def addRow(self, vals): def addRow(self, vals):
#print "add row:", vals
row = self.rowCount() row = self.rowCount()
self.setRowCount(row+1) self.setRowCount(row + 1)
self.setRow(row, vals) self.setRow(row, vals)
def setRow(self, row, vals): def setRow(self, row, vals):
if row > self.rowCount()-1: if row > self.rowCount() - 1:
self.setRowCount(row+1) self.setRowCount(row + 1)
for col in range(self.columnCount()): for col in range(len(vals)):
val = vals[col] val = vals[col]
if isinstance(val, float) or isinstance(val, np.floating): item = TableWidgetItem(val)
s = "%0.3g" % val item.setEditable(self.editable)
else:
s = str(val)
item = QtGui.QTableWidgetItem(s)
item.value = val
#print "add item to row %d:"%row, item, item.value
self.items.append(item) self.items.append(item)
self.setItem(row, col, item) self.setItem(row, col, item)
def sizeHint(self):
# based on http://stackoverflow.com/a/7195443/54056
width = sum(self.columnWidth(i) for i in range(self.columnCount()))
width += self.verticalHeader().sizeHint().width()
width += self.verticalScrollBar().sizeHint().width()
width += self.frameWidth() * 2
height = sum(self.rowHeight(i) for i in range(self.rowCount()))
height += self.verticalHeader().sizeHint().height()
height += self.horizontalScrollBar().sizeHint().height()
return QtCore.QSize(width, height)
def serialize(self, useSelection=False): def serialize(self, useSelection=False):
"""Convert entire table (or just selected area) into tab-separated text values""" """Convert entire table (or just selected area) into tab-separated text values"""
if useSelection: if useSelection:
selection = self.selectedRanges()[0] selection = self.selectedRanges()[0]
rows = list(range(selection.topRow(), selection.bottomRow()+1)) rows = list(range(selection.topRow(),
columns = list(range(selection.leftColumn(), selection.rightColumn()+1)) selection.bottomRow() + 1))
columns = list(range(selection.leftColumn(),
selection.rightColumn() + 1))
else: else:
rows = list(range(self.rowCount())) rows = list(range(self.rowCount()))
columns = list(range(self.columnCount())) columns = list(range(self.columnCount()))
@ -215,6 +234,28 @@ class TableWidget(QtGui.QTableWidget):
else: else:
ev.ignore() ev.ignore()
class TableWidgetItem(QtGui.QTableWidgetItem):
def __init__(self, val):
if isinstance(val, float) or isinstance(val, np.floating):
s = "%0.3g" % val
else:
s = str(val)
QtGui.QTableWidgetItem.__init__(self, s)
self.value = val
flags = QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled
self.setFlags(flags)
def setEditable(self, editable):
if editable:
self.setFlags(self.flags() | QtCore.Qt.ItemIsEditable)
else:
self.setFlags(self.flags() & ~QtCore.Qt.ItemIsEditable)
def __lt__(self, other):
if hasattr(other, 'value'):
return self.value < other.value
else:
return self.text() < other.text()
if __name__ == '__main__': if __name__ == '__main__':