From af592962310469e46b684b53d9d40e0e76091ce6 Mon Sep 17 00:00:00 2001 From: Luke Campagnola Date: Tue, 25 Dec 2012 00:43:31 -0500 Subject: [PATCH 1/6] Reorganized directory structure to be more standard Started new SVG exporter Merged updates from ACQ4 --- license.txt => LICENSE.txt | 0 README => README.txt | 0 {documentation => doc}/Makefile | 0 {documentation => doc}/listmissing.py | 0 {documentation => doc}/make.bat | 0 {documentation => doc}/source/3dgraphics.rst | 0 .../source/3dgraphics/glaxisitem.rst | 0 .../source/3dgraphics/glgraphicsitem.rst | 0 .../source/3dgraphics/glgriditem.rst | 0 .../source/3dgraphics/glimageitem.rst | 0 .../source/3dgraphics/glmeshitem.rst | 0 .../source/3dgraphics/glscatterplotitem.rst | 0 .../source/3dgraphics/glsurfaceplotitem.rst | 0 .../source/3dgraphics/glviewwidget.rst | 0 .../source/3dgraphics/glvolumeitem.rst | 0 .../source/3dgraphics/index.rst | 0 .../source/3dgraphics/meshdata.rst | 0 .../source/apireference.rst | 0 {documentation => doc}/source/conf.py | 0 {documentation => doc}/source/functions.rst | 0 .../source/graphicsItems/arrowitem.rst | 0 .../source/graphicsItems/axisitem.rst | 0 .../source/graphicsItems/buttonitem.rst | 0 .../source/graphicsItems/curvearrow.rst | 0 .../source/graphicsItems/curvepoint.rst | 0 .../source/graphicsItems/fillbetweenitem.rst | 0 .../graphicsItems/gradienteditoritem.rst | 0 .../source/graphicsItems/gradientlegend.rst | 0 .../source/graphicsItems/graphicsitem.rst | 0 .../source/graphicsItems/graphicslayout.rst | 0 .../source/graphicsItems/graphicsobject.rst | 0 .../source/graphicsItems/graphicswidget.rst | 0 .../graphicsItems/graphicswidgetanchor.rst | 0 .../source/graphicsItems/griditem.rst | 0 .../source/graphicsItems/histogramlutitem.rst | 0 .../source/graphicsItems/imageitem.rst | 0 .../source/graphicsItems/index.rst | 0 .../source/graphicsItems/infiniteline.rst | 0 .../source/graphicsItems/isocurveitem.rst | 0 .../source/graphicsItems/labelitem.rst | 0 .../source/graphicsItems/legenditem.rst | 0 .../source/graphicsItems/linearregionitem.rst | 0 .../source/graphicsItems/make | 0 .../source/graphicsItems/plotcurveitem.rst | 0 .../source/graphicsItems/plotdataitem.rst | 0 .../source/graphicsItems/plotitem.rst | 0 .../source/graphicsItems/roi.rst | 0 .../source/graphicsItems/scalebar.rst | 0 .../source/graphicsItems/scatterplotitem.rst | 0 .../source/graphicsItems/textitem.rst | 0 .../source/graphicsItems/uigraphicsitem.rst | 0 .../source/graphicsItems/viewbox.rst | 0 .../source/graphicsItems/vtickgroup.rst | 0 .../source/graphicsscene/graphicsscene.rst | 0 .../source/graphicsscene/hoverevent.rst | 0 .../source/graphicsscene/index.rst | 0 .../source/graphicsscene/mouseclickevent.rst | 0 .../source/graphicsscene/mousedragevent.rst | 0 .../source/graphicswindow.rst | 0 {documentation => doc}/source/how_to_use.rst | 0 {documentation => doc}/source/images.rst | 0 .../source/images/plottingClasses.png | Bin .../source/images/plottingClasses.svg | 0 {documentation => doc}/source/index.rst | 0 .../source/installation.rst | 0 {documentation => doc}/source/internals.rst | 0 .../source/introduction.rst | 0 .../source/mouse_interaction.rst | 0 .../source/parametertree/apiref.rst | 0 .../source/parametertree/index.rst | 0 .../source/parametertree/parameter.rst | 0 .../source/parametertree/parameteritem.rst | 0 .../source/parametertree/parametertree.rst | 0 .../source/parametertree/parametertypes.rst | 0 {documentation => doc}/source/plotting.rst | 0 {documentation => doc}/source/prototyping.rst | 0 .../source/region_of_interest.rst | 0 {documentation => doc}/source/style.rst | 0 .../source/widgets/busycursor.rst | 0 .../source/widgets/checktable.rst | 0 .../source/widgets/colorbutton.rst | 0 .../source/widgets/combobox.rst | 0 .../source/widgets/datatreewidget.rst | 0 .../source/widgets/dockarea.rst | 0 .../source/widgets/feedbackbutton.rst | 0 .../source/widgets/filedialog.rst | 0 .../source/widgets/gradientwidget.rst | 0 .../source/widgets/graphicslayoutwidget.rst | 0 .../source/widgets/graphicsview.rst | 0 .../source/widgets/histogramlutwidget.rst | 0 .../source/widgets/imageview.rst | 0 .../source/widgets/index.rst | 0 .../source/widgets/joystickbutton.rst | 0 .../source/widgets/layoutwidget.rst | 0 {documentation => doc}/source/widgets/make | 0 .../source/widgets/matplotlibwidget.rst | 0 .../source/widgets/multiplotwidget.rst | 0 .../source/widgets/parametertree.rst | 0 .../source/widgets/pathbutton.rst | 0 .../source/widgets/plotwidget.rst | 0 .../source/widgets/progressdialog.rst | 0 .../source/widgets/rawimagewidget.rst | 0 .../source/widgets/remotegraphicsview.rst | 0 .../source/widgets/spinbox.rst | 0 .../source/widgets/tablewidget.rst | 0 .../source/widgets/treewidget.rst | 0 .../source/widgets/valuelabel.rst | 0 .../source/widgets/verticallabel.rst | 0 examples/__main__.py | 15 +- examples/exampleLoaderTemplate.ui | 30 +++ examples/exampleLoaderTemplate_pyqt.py | 18 +- examples/exampleLoaderTemplate_pyside.py | 20 +- examples/initExample.py | 12 +- exporters/SVGExporter.py | 71 ------- .../GraphicsScene}/GraphicsScene.py | 0 .../GraphicsScene}/__init__.py | 0 .../GraphicsScene}/exportDialog.py | 0 .../GraphicsScene}/exportDialogTemplate.ui | 0 .../exportDialogTemplate_pyqt.py | 0 .../exportDialogTemplate_pyside.py | 0 .../GraphicsScene}/mouseEvents.py | 0 {PIL_Fix => pyqtgraph/PIL_Fix}/Image.py-1.6 | 0 {PIL_Fix => pyqtgraph/PIL_Fix}/Image.py-1.7 | 0 {PIL_Fix => pyqtgraph/PIL_Fix}/README | 0 Point.py => pyqtgraph/Point.py | 0 Qt.py => pyqtgraph/Qt.py | 0 SRTTransform.py => pyqtgraph/SRTTransform.py | 0 .../SRTTransform3D.py | 0 SignalProxy.py => pyqtgraph/SignalProxy.py | 0 .../ThreadsafeTimer.py | 0 Transform3D.py => pyqtgraph/Transform3D.py | 0 Vector.py => pyqtgraph/Vector.py | 0 WidgetGroup.py => pyqtgraph/WidgetGroup.py | 0 __init__.py => pyqtgraph/__init__.py | 3 + {canvas => pyqtgraph/canvas}/Canvas.py | 0 {canvas => pyqtgraph/canvas}/CanvasItem.py | 0 {canvas => pyqtgraph/canvas}/CanvasManager.py | 0 .../canvas}/CanvasTemplate.ui | 0 .../canvas}/CanvasTemplate_pyqt.py | 0 .../canvas}/CanvasTemplate_pyside.py | 0 .../canvas}/TransformGuiTemplate.ui | 0 .../canvas}/TransformGuiTemplate_pyqt.py | 0 .../canvas}/TransformGuiTemplate_pyside.py | 0 {canvas => pyqtgraph/canvas}/__init__.py | 0 configfile.py => pyqtgraph/configfile.py | 0 {console => pyqtgraph/console}/CmdInput.py | 0 {console => pyqtgraph/console}/Console.py | 0 {console => pyqtgraph/console}/__init__.py | 0 {console => pyqtgraph/console}/template.ui | 0 .../console}/template_pyqt.py | 0 .../console}/template_pyside.py | 0 debug.py => pyqtgraph/debug.py | 0 {dockarea => pyqtgraph/dockarea}/Container.py | 0 {dockarea => pyqtgraph/dockarea}/Dock.py | 0 {dockarea => pyqtgraph/dockarea}/DockArea.py | 0 {dockarea => pyqtgraph/dockarea}/DockDrop.py | 0 {dockarea => pyqtgraph/dockarea}/__init__.py | 0 .../exceptionHandling.py | 0 .../exporters}/CSVExporter.py | 0 .../exporters}/Exporter.py | 11 +- .../exporters}/ImageExporter.py | 18 +- .../exporters}/Matplotlib.py | 0 .../exporters}/PrintExporter.py | 16 +- pyqtgraph/exporters/SVGExporter.py | 178 ++++++++++++++++++ .../exporters}/__init__.py | 0 .../flowchart}/Flowchart.py | 0 .../flowchart}/FlowchartCtrlTemplate.ui | 0 .../flowchart}/FlowchartCtrlTemplate_pyqt.py | 0 .../FlowchartCtrlTemplate_pyside.py | 0 .../flowchart}/FlowchartGraphicsView.py | 0 .../flowchart}/FlowchartTemplate.ui | 0 .../flowchart}/FlowchartTemplate_pyqt.py | 0 .../flowchart}/FlowchartTemplate_pyside.py | 0 {flowchart => pyqtgraph/flowchart}/Node.py | 0 .../flowchart}/Terminal.py | 0 .../flowchart}/__init__.py | 0 {flowchart => pyqtgraph/flowchart}/eq.py | 0 .../flowchart}/library/Data.py | 0 .../flowchart}/library/Display.py | 0 .../flowchart}/library/Filters.py | 0 .../flowchart}/library/Operators.py | 0 .../flowchart}/library/__init__.py | 0 .../flowchart}/library/common.py | 0 .../flowchart}/library/functions.py | 0 .../frozenSupport.py | 0 functions.py => pyqtgraph/functions.py | 0 .../graphicsItems}/ArrowItem.py | 0 .../graphicsItems}/AxisItem.py | 0 .../graphicsItems}/ButtonItem.py | 0 .../graphicsItems}/CurvePoint.py | 0 .../graphicsItems}/FillBetweenItem.py | 0 .../graphicsItems}/GradientEditorItem.py | 0 .../graphicsItems}/GradientLegend.py | 0 .../graphicsItems}/GraphicsItem.py | 22 ++- .../graphicsItems}/GraphicsLayout.py | 0 .../graphicsItems}/GraphicsObject.py | 0 .../graphicsItems}/GraphicsWidget.py | 0 .../graphicsItems}/GraphicsWidgetAnchor.py | 0 .../graphicsItems}/GridItem.py | 0 .../graphicsItems}/HistogramLUTItem.py | 0 .../graphicsItems}/ImageItem.py | 0 .../graphicsItems}/InfiniteLine.py | 0 .../graphicsItems}/IsocurveItem.py | 0 .../graphicsItems}/ItemGroup.py | 0 .../graphicsItems}/LabelItem.py | 0 .../graphicsItems}/LegendItem.py | 0 .../graphicsItems}/LinearRegionItem.py | 0 .../graphicsItems}/MultiPlotItem.py | 0 .../graphicsItems}/PlotCurveItem.py | 14 +- .../graphicsItems}/PlotDataItem.py | 8 +- .../graphicsItems}/PlotItem/PlotItem.py | 14 +- .../graphicsItems}/PlotItem/__init__.py | 0 .../PlotItem/plotConfigTemplate.ui | 0 .../PlotItem/plotConfigTemplate_pyqt.py | 0 .../PlotItem/plotConfigTemplate_pyside.py | 0 .../graphicsItems}/ROI.py | 0 .../graphicsItems}/ScaleBar.py | 0 .../graphicsItems}/ScatterPlotItem.py | 43 ++--- .../graphicsItems}/TextItem.py | 83 ++++---- .../graphicsItems}/UIGraphicsItem.py | 0 .../graphicsItems}/VTickGroup.py | 0 .../graphicsItems}/ViewBox/ViewBox.py | 0 .../graphicsItems}/ViewBox/ViewBoxMenu.py | 0 .../graphicsItems}/ViewBox/__init__.py | 0 .../ViewBox/axisCtrlTemplate.ui | 0 .../ViewBox/axisCtrlTemplate_pyqt.py | 0 .../ViewBox/axisCtrlTemplate_pyside.py | 0 .../graphicsItems}/__init__.py | 0 .../graphicsWindows.py | 0 .../imageview}/ImageView.py | 0 .../imageview}/ImageViewTemplate.ui | 0 .../imageview}/ImageViewTemplate_pyqt.py | 0 .../imageview}/ImageViewTemplate_pyside.py | 0 .../imageview}/__init__.py | 0 .../metaarray}/MetaArray.py | 0 .../metaarray}/__init__.py | 0 .../metaarray}/license.txt | 0 {metaarray => pyqtgraph/metaarray}/readMeta.m | 0 .../multiprocess}/__init__.py | 0 .../multiprocess}/bootstrap.py | 0 .../multiprocess}/parallelizer.py | 0 .../multiprocess}/processes.py | 0 .../multiprocess}/remoteproxy.py | 0 numpy_fix.py => pyqtgraph/numpy_fix.py | 0 .../opengl}/GLGraphicsItem.py | 0 {opengl => pyqtgraph/opengl}/GLViewWidget.py | 0 {opengl => pyqtgraph/opengl}/MeshData.py | 0 {opengl => pyqtgraph/opengl}/__init__.py | 0 {opengl => pyqtgraph/opengl}/glInfo.py | 0 .../opengl}/items/GLAxisItem.py | 0 .../opengl}/items/GLBoxItem.py | 0 .../opengl}/items/GLGridItem.py | 0 .../opengl}/items/GLImageItem.py | 0 .../opengl}/items/GLMeshItem.py | 0 .../opengl}/items/GLScatterPlotItem.py | 0 .../opengl}/items/GLSurfacePlotItem.py | 0 .../opengl}/items/GLVolumeItem.py | 0 .../opengl}/items/__init__.py | 0 {opengl => pyqtgraph/opengl}/shaders.py | 0 .../parametertree}/Parameter.py | 0 .../parametertree}/ParameterItem.py | 0 .../parametertree}/ParameterTree.py | 0 .../parametertree}/__init__.py | 0 .../parametertree}/parameterTypes.py | 0 .../pgcollections.py | 0 {pixmaps => pyqtgraph/pixmaps}/__init__.py | 0 {pixmaps => pyqtgraph/pixmaps}/auto.png | Bin {pixmaps => pyqtgraph/pixmaps}/compile.py | 0 {pixmaps => pyqtgraph/pixmaps}/ctrl.png | Bin {pixmaps => pyqtgraph/pixmaps}/default.png | Bin {pixmaps => pyqtgraph/pixmaps}/icons.svg | 0 {pixmaps => pyqtgraph/pixmaps}/lock.png | Bin .../pixmaps}/pixmapData_2.py | 0 .../pixmaps}/pixmapData_3.py | 0 ptime.py => pyqtgraph/ptime.py | 0 python2_3.py => pyqtgraph/python2_3.py | 0 rebuildUi.py => pyqtgraph/rebuildUi.py | 0 reload.py => pyqtgraph/reload.py | 0 units.py => pyqtgraph/units.py | 0 {widgets => pyqtgraph/widgets}/BusyCursor.py | 0 {widgets => pyqtgraph/widgets}/CheckTable.py | 0 {widgets => pyqtgraph/widgets}/ColorButton.py | 0 {widgets => pyqtgraph/widgets}/ComboBox.py | 0 .../widgets}/DataTreeWidget.py | 0 .../widgets}/FeedbackButton.py | 0 {widgets => pyqtgraph/widgets}/FileDialog.py | 0 .../widgets}/GradientWidget.py | 0 .../widgets}/GraphicsLayoutWidget.py | 0 .../widgets}/GraphicsView.py | 0 .../widgets}/HistogramLUTWidget.py | 0 .../widgets}/JoystickButton.py | 0 .../widgets}/LayoutWidget.py | 0 .../widgets}/MatplotlibWidget.py | 0 .../widgets}/MultiPlotWidget.py | 0 {widgets => pyqtgraph/widgets}/PathButton.py | 0 {widgets => pyqtgraph/widgets}/PlotWidget.py | 0 .../widgets}/ProgressDialog.py | 0 .../widgets}/RawImageWidget.py | 0 .../widgets}/RemoteGraphicsView.py | 0 {widgets => pyqtgraph/widgets}/SpinBox.py | 0 {widgets => pyqtgraph/widgets}/TableWidget.py | 0 {widgets => pyqtgraph/widgets}/TreeWidget.py | 0 {widgets => pyqtgraph/widgets}/ValueLabel.py | 0 .../widgets}/VerticalLabel.py | 0 {widgets => pyqtgraph/widgets}/__init__.py | 0 tests/__init__.py | 0 tests/svg.py | 29 +++ tests/test.py | 8 + 308 files changed, 428 insertions(+), 185 deletions(-) rename license.txt => LICENSE.txt (100%) rename README => README.txt (100%) rename {documentation => doc}/Makefile (100%) rename {documentation => doc}/listmissing.py (100%) rename {documentation => doc}/make.bat (100%) rename {documentation => doc}/source/3dgraphics.rst (100%) rename {documentation => doc}/source/3dgraphics/glaxisitem.rst (100%) rename {documentation => doc}/source/3dgraphics/glgraphicsitem.rst (100%) rename {documentation => doc}/source/3dgraphics/glgriditem.rst (100%) rename {documentation => doc}/source/3dgraphics/glimageitem.rst (100%) rename {documentation => doc}/source/3dgraphics/glmeshitem.rst (100%) rename {documentation => doc}/source/3dgraphics/glscatterplotitem.rst (100%) rename {documentation => doc}/source/3dgraphics/glsurfaceplotitem.rst (100%) rename {documentation => doc}/source/3dgraphics/glviewwidget.rst (100%) rename {documentation => doc}/source/3dgraphics/glvolumeitem.rst (100%) rename {documentation => doc}/source/3dgraphics/index.rst (100%) rename {documentation => doc}/source/3dgraphics/meshdata.rst (100%) rename {documentation => doc}/source/apireference.rst (100%) rename {documentation => doc}/source/conf.py (100%) rename {documentation => doc}/source/functions.rst (100%) rename {documentation => doc}/source/graphicsItems/arrowitem.rst (100%) rename {documentation => doc}/source/graphicsItems/axisitem.rst (100%) rename {documentation => doc}/source/graphicsItems/buttonitem.rst (100%) rename {documentation => doc}/source/graphicsItems/curvearrow.rst (100%) rename {documentation => doc}/source/graphicsItems/curvepoint.rst (100%) rename {documentation => doc}/source/graphicsItems/fillbetweenitem.rst (100%) rename {documentation => doc}/source/graphicsItems/gradienteditoritem.rst (100%) rename {documentation => doc}/source/graphicsItems/gradientlegend.rst (100%) rename {documentation => doc}/source/graphicsItems/graphicsitem.rst (100%) rename {documentation => doc}/source/graphicsItems/graphicslayout.rst (100%) rename {documentation => doc}/source/graphicsItems/graphicsobject.rst (100%) rename {documentation => doc}/source/graphicsItems/graphicswidget.rst (100%) rename {documentation => doc}/source/graphicsItems/graphicswidgetanchor.rst (100%) rename {documentation => doc}/source/graphicsItems/griditem.rst (100%) rename {documentation => doc}/source/graphicsItems/histogramlutitem.rst (100%) rename {documentation => doc}/source/graphicsItems/imageitem.rst (100%) rename {documentation => doc}/source/graphicsItems/index.rst (100%) rename {documentation => doc}/source/graphicsItems/infiniteline.rst (100%) rename {documentation => doc}/source/graphicsItems/isocurveitem.rst (100%) rename {documentation => doc}/source/graphicsItems/labelitem.rst (100%) rename {documentation => doc}/source/graphicsItems/legenditem.rst (100%) rename {documentation => doc}/source/graphicsItems/linearregionitem.rst (100%) rename {documentation => doc}/source/graphicsItems/make (100%) rename {documentation => doc}/source/graphicsItems/plotcurveitem.rst (100%) rename {documentation => doc}/source/graphicsItems/plotdataitem.rst (100%) rename {documentation => doc}/source/graphicsItems/plotitem.rst (100%) rename {documentation => doc}/source/graphicsItems/roi.rst (100%) rename {documentation => doc}/source/graphicsItems/scalebar.rst (100%) rename {documentation => doc}/source/graphicsItems/scatterplotitem.rst (100%) rename {documentation => doc}/source/graphicsItems/textitem.rst (100%) rename {documentation => doc}/source/graphicsItems/uigraphicsitem.rst (100%) rename {documentation => doc}/source/graphicsItems/viewbox.rst (100%) rename {documentation => doc}/source/graphicsItems/vtickgroup.rst (100%) rename {documentation => doc}/source/graphicsscene/graphicsscene.rst (100%) rename {documentation => doc}/source/graphicsscene/hoverevent.rst (100%) rename {documentation => doc}/source/graphicsscene/index.rst (100%) rename {documentation => doc}/source/graphicsscene/mouseclickevent.rst (100%) rename {documentation => doc}/source/graphicsscene/mousedragevent.rst (100%) rename {documentation => doc}/source/graphicswindow.rst (100%) rename {documentation => doc}/source/how_to_use.rst (100%) rename {documentation => doc}/source/images.rst (100%) rename {documentation => doc}/source/images/plottingClasses.png (100%) rename {documentation => doc}/source/images/plottingClasses.svg (100%) rename {documentation => doc}/source/index.rst (100%) rename {documentation => doc}/source/installation.rst (100%) rename {documentation => doc}/source/internals.rst (100%) rename {documentation => doc}/source/introduction.rst (100%) rename {documentation => doc}/source/mouse_interaction.rst (100%) rename {documentation => doc}/source/parametertree/apiref.rst (100%) rename {documentation => doc}/source/parametertree/index.rst (100%) rename {documentation => doc}/source/parametertree/parameter.rst (100%) rename {documentation => doc}/source/parametertree/parameteritem.rst (100%) rename {documentation => doc}/source/parametertree/parametertree.rst (100%) rename {documentation => doc}/source/parametertree/parametertypes.rst (100%) rename {documentation => doc}/source/plotting.rst (100%) rename {documentation => doc}/source/prototyping.rst (100%) rename {documentation => doc}/source/region_of_interest.rst (100%) rename {documentation => doc}/source/style.rst (100%) rename {documentation => doc}/source/widgets/busycursor.rst (100%) rename {documentation => doc}/source/widgets/checktable.rst (100%) rename {documentation => doc}/source/widgets/colorbutton.rst (100%) rename {documentation => doc}/source/widgets/combobox.rst (100%) rename {documentation => doc}/source/widgets/datatreewidget.rst (100%) rename {documentation => doc}/source/widgets/dockarea.rst (100%) rename {documentation => doc}/source/widgets/feedbackbutton.rst (100%) rename {documentation => doc}/source/widgets/filedialog.rst (100%) rename {documentation => doc}/source/widgets/gradientwidget.rst (100%) rename {documentation => doc}/source/widgets/graphicslayoutwidget.rst (100%) rename {documentation => doc}/source/widgets/graphicsview.rst (100%) rename {documentation => doc}/source/widgets/histogramlutwidget.rst (100%) rename {documentation => doc}/source/widgets/imageview.rst (100%) rename {documentation => doc}/source/widgets/index.rst (100%) rename {documentation => doc}/source/widgets/joystickbutton.rst (100%) rename {documentation => doc}/source/widgets/layoutwidget.rst (100%) rename {documentation => doc}/source/widgets/make (100%) rename {documentation => doc}/source/widgets/matplotlibwidget.rst (100%) rename {documentation => doc}/source/widgets/multiplotwidget.rst (100%) rename {documentation => doc}/source/widgets/parametertree.rst (100%) rename {documentation => doc}/source/widgets/pathbutton.rst (100%) rename {documentation => doc}/source/widgets/plotwidget.rst (100%) rename {documentation => doc}/source/widgets/progressdialog.rst (100%) rename {documentation => doc}/source/widgets/rawimagewidget.rst (100%) rename {documentation => doc}/source/widgets/remotegraphicsview.rst (100%) rename {documentation => doc}/source/widgets/spinbox.rst (100%) rename {documentation => doc}/source/widgets/tablewidget.rst (100%) rename {documentation => doc}/source/widgets/treewidget.rst (100%) rename {documentation => doc}/source/widgets/valuelabel.rst (100%) rename {documentation => doc}/source/widgets/verticallabel.rst (100%) delete mode 100644 exporters/SVGExporter.py rename {GraphicsScene => pyqtgraph/GraphicsScene}/GraphicsScene.py (100%) rename {GraphicsScene => pyqtgraph/GraphicsScene}/__init__.py (100%) rename {GraphicsScene => pyqtgraph/GraphicsScene}/exportDialog.py (100%) rename {GraphicsScene => pyqtgraph/GraphicsScene}/exportDialogTemplate.ui (100%) rename {GraphicsScene => pyqtgraph/GraphicsScene}/exportDialogTemplate_pyqt.py (100%) rename {GraphicsScene => pyqtgraph/GraphicsScene}/exportDialogTemplate_pyside.py (100%) rename {GraphicsScene => pyqtgraph/GraphicsScene}/mouseEvents.py (100%) rename {PIL_Fix => pyqtgraph/PIL_Fix}/Image.py-1.6 (100%) rename {PIL_Fix => pyqtgraph/PIL_Fix}/Image.py-1.7 (100%) rename {PIL_Fix => pyqtgraph/PIL_Fix}/README (100%) rename Point.py => pyqtgraph/Point.py (100%) rename Qt.py => pyqtgraph/Qt.py (100%) rename SRTTransform.py => pyqtgraph/SRTTransform.py (100%) rename SRTTransform3D.py => pyqtgraph/SRTTransform3D.py (100%) rename SignalProxy.py => pyqtgraph/SignalProxy.py (100%) rename ThreadsafeTimer.py => pyqtgraph/ThreadsafeTimer.py (100%) rename Transform3D.py => pyqtgraph/Transform3D.py (100%) rename Vector.py => pyqtgraph/Vector.py (100%) rename WidgetGroup.py => pyqtgraph/WidgetGroup.py (100%) rename __init__.py => pyqtgraph/__init__.py (99%) rename {canvas => pyqtgraph/canvas}/Canvas.py (100%) rename {canvas => pyqtgraph/canvas}/CanvasItem.py (100%) rename {canvas => pyqtgraph/canvas}/CanvasManager.py (100%) rename {canvas => pyqtgraph/canvas}/CanvasTemplate.ui (100%) rename {canvas => pyqtgraph/canvas}/CanvasTemplate_pyqt.py (100%) rename {canvas => pyqtgraph/canvas}/CanvasTemplate_pyside.py (100%) rename {canvas => pyqtgraph/canvas}/TransformGuiTemplate.ui (100%) rename {canvas => pyqtgraph/canvas}/TransformGuiTemplate_pyqt.py (100%) rename {canvas => pyqtgraph/canvas}/TransformGuiTemplate_pyside.py (100%) rename {canvas => pyqtgraph/canvas}/__init__.py (100%) rename configfile.py => pyqtgraph/configfile.py (100%) rename {console => pyqtgraph/console}/CmdInput.py (100%) rename {console => pyqtgraph/console}/Console.py (100%) rename {console => pyqtgraph/console}/__init__.py (100%) rename {console => pyqtgraph/console}/template.ui (100%) rename {console => pyqtgraph/console}/template_pyqt.py (100%) rename {console => pyqtgraph/console}/template_pyside.py (100%) rename debug.py => pyqtgraph/debug.py (100%) rename {dockarea => pyqtgraph/dockarea}/Container.py (100%) rename {dockarea => pyqtgraph/dockarea}/Dock.py (100%) rename {dockarea => pyqtgraph/dockarea}/DockArea.py (100%) rename {dockarea => pyqtgraph/dockarea}/DockDrop.py (100%) rename {dockarea => pyqtgraph/dockarea}/__init__.py (100%) rename exceptionHandling.py => pyqtgraph/exceptionHandling.py (100%) rename {exporters => pyqtgraph/exporters}/CSVExporter.py (100%) rename {exporters => pyqtgraph/exporters}/Exporter.py (96%) rename {exporters => pyqtgraph/exporters}/ImageExporter.py (82%) rename {exporters => pyqtgraph/exporters}/Matplotlib.py (100%) rename {exporters => pyqtgraph/exporters}/PrintExporter.py (81%) create mode 100644 pyqtgraph/exporters/SVGExporter.py rename {exporters => pyqtgraph/exporters}/__init__.py (100%) rename {flowchart => pyqtgraph/flowchart}/Flowchart.py (100%) rename {flowchart => pyqtgraph/flowchart}/FlowchartCtrlTemplate.ui (100%) rename {flowchart => pyqtgraph/flowchart}/FlowchartCtrlTemplate_pyqt.py (100%) rename {flowchart => pyqtgraph/flowchart}/FlowchartCtrlTemplate_pyside.py (100%) rename {flowchart => pyqtgraph/flowchart}/FlowchartGraphicsView.py (100%) rename {flowchart => pyqtgraph/flowchart}/FlowchartTemplate.ui (100%) rename {flowchart => pyqtgraph/flowchart}/FlowchartTemplate_pyqt.py (100%) rename {flowchart => pyqtgraph/flowchart}/FlowchartTemplate_pyside.py (100%) rename {flowchart => pyqtgraph/flowchart}/Node.py (100%) rename {flowchart => pyqtgraph/flowchart}/Terminal.py (100%) rename {flowchart => pyqtgraph/flowchart}/__init__.py (100%) rename {flowchart => pyqtgraph/flowchart}/eq.py (100%) rename {flowchart => pyqtgraph/flowchart}/library/Data.py (100%) rename {flowchart => pyqtgraph/flowchart}/library/Display.py (100%) rename {flowchart => pyqtgraph/flowchart}/library/Filters.py (100%) rename {flowchart => pyqtgraph/flowchart}/library/Operators.py (100%) rename {flowchart => pyqtgraph/flowchart}/library/__init__.py (100%) rename {flowchart => pyqtgraph/flowchart}/library/common.py (100%) rename {flowchart => pyqtgraph/flowchart}/library/functions.py (100%) rename frozenSupport.py => pyqtgraph/frozenSupport.py (100%) rename functions.py => pyqtgraph/functions.py (100%) rename {graphicsItems => pyqtgraph/graphicsItems}/ArrowItem.py (100%) rename {graphicsItems => pyqtgraph/graphicsItems}/AxisItem.py (100%) rename {graphicsItems => pyqtgraph/graphicsItems}/ButtonItem.py (100%) rename {graphicsItems => pyqtgraph/graphicsItems}/CurvePoint.py (100%) rename {graphicsItems => pyqtgraph/graphicsItems}/FillBetweenItem.py (100%) rename {graphicsItems => pyqtgraph/graphicsItems}/GradientEditorItem.py (100%) rename {graphicsItems => pyqtgraph/graphicsItems}/GradientLegend.py (100%) rename {graphicsItems => pyqtgraph/graphicsItems}/GraphicsItem.py (95%) rename {graphicsItems => pyqtgraph/graphicsItems}/GraphicsLayout.py (100%) rename {graphicsItems => pyqtgraph/graphicsItems}/GraphicsObject.py (100%) rename {graphicsItems => pyqtgraph/graphicsItems}/GraphicsWidget.py (100%) rename {graphicsItems => pyqtgraph/graphicsItems}/GraphicsWidgetAnchor.py (100%) rename {graphicsItems => pyqtgraph/graphicsItems}/GridItem.py (100%) rename {graphicsItems => pyqtgraph/graphicsItems}/HistogramLUTItem.py (100%) rename {graphicsItems => pyqtgraph/graphicsItems}/ImageItem.py (100%) rename {graphicsItems => pyqtgraph/graphicsItems}/InfiniteLine.py (100%) rename {graphicsItems => pyqtgraph/graphicsItems}/IsocurveItem.py (100%) rename {graphicsItems => pyqtgraph/graphicsItems}/ItemGroup.py (100%) rename {graphicsItems => pyqtgraph/graphicsItems}/LabelItem.py (100%) rename {graphicsItems => pyqtgraph/graphicsItems}/LegendItem.py (100%) rename {graphicsItems => pyqtgraph/graphicsItems}/LinearRegionItem.py (100%) rename {graphicsItems => pyqtgraph/graphicsItems}/MultiPlotItem.py (100%) rename {graphicsItems => pyqtgraph/graphicsItems}/PlotCurveItem.py (97%) rename {graphicsItems => pyqtgraph/graphicsItems}/PlotDataItem.py (99%) rename {graphicsItems => pyqtgraph/graphicsItems}/PlotItem/PlotItem.py (99%) rename {graphicsItems => pyqtgraph/graphicsItems}/PlotItem/__init__.py (100%) rename {graphicsItems => pyqtgraph/graphicsItems}/PlotItem/plotConfigTemplate.ui (100%) rename {graphicsItems => pyqtgraph/graphicsItems}/PlotItem/plotConfigTemplate_pyqt.py (100%) rename {graphicsItems => pyqtgraph/graphicsItems}/PlotItem/plotConfigTemplate_pyside.py (100%) rename {graphicsItems => pyqtgraph/graphicsItems}/ROI.py (100%) rename {graphicsItems => pyqtgraph/graphicsItems}/ScaleBar.py (100%) rename {graphicsItems => pyqtgraph/graphicsItems}/ScatterPlotItem.py (97%) rename {graphicsItems => pyqtgraph/graphicsItems}/TextItem.py (66%) rename {graphicsItems => pyqtgraph/graphicsItems}/UIGraphicsItem.py (100%) rename {graphicsItems => pyqtgraph/graphicsItems}/VTickGroup.py (100%) rename {graphicsItems => pyqtgraph/graphicsItems}/ViewBox/ViewBox.py (100%) rename {graphicsItems => pyqtgraph/graphicsItems}/ViewBox/ViewBoxMenu.py (100%) rename {graphicsItems => pyqtgraph/graphicsItems}/ViewBox/__init__.py (100%) rename {graphicsItems => pyqtgraph/graphicsItems}/ViewBox/axisCtrlTemplate.ui (100%) rename {graphicsItems => pyqtgraph/graphicsItems}/ViewBox/axisCtrlTemplate_pyqt.py (100%) rename {graphicsItems => pyqtgraph/graphicsItems}/ViewBox/axisCtrlTemplate_pyside.py (100%) rename {graphicsItems => pyqtgraph/graphicsItems}/__init__.py (100%) rename graphicsWindows.py => pyqtgraph/graphicsWindows.py (100%) rename {imageview => pyqtgraph/imageview}/ImageView.py (100%) rename {imageview => pyqtgraph/imageview}/ImageViewTemplate.ui (100%) rename {imageview => pyqtgraph/imageview}/ImageViewTemplate_pyqt.py (100%) rename {imageview => pyqtgraph/imageview}/ImageViewTemplate_pyside.py (100%) rename {imageview => pyqtgraph/imageview}/__init__.py (100%) rename {metaarray => pyqtgraph/metaarray}/MetaArray.py (100%) rename {metaarray => pyqtgraph/metaarray}/__init__.py (100%) rename {metaarray => pyqtgraph/metaarray}/license.txt (100%) rename {metaarray => pyqtgraph/metaarray}/readMeta.m (100%) rename {multiprocess => pyqtgraph/multiprocess}/__init__.py (100%) rename {multiprocess => pyqtgraph/multiprocess}/bootstrap.py (100%) rename {multiprocess => pyqtgraph/multiprocess}/parallelizer.py (100%) rename {multiprocess => pyqtgraph/multiprocess}/processes.py (100%) rename {multiprocess => pyqtgraph/multiprocess}/remoteproxy.py (100%) rename numpy_fix.py => pyqtgraph/numpy_fix.py (100%) rename {opengl => pyqtgraph/opengl}/GLGraphicsItem.py (100%) rename {opengl => pyqtgraph/opengl}/GLViewWidget.py (100%) rename {opengl => pyqtgraph/opengl}/MeshData.py (100%) rename {opengl => pyqtgraph/opengl}/__init__.py (100%) rename {opengl => pyqtgraph/opengl}/glInfo.py (100%) rename {opengl => pyqtgraph/opengl}/items/GLAxisItem.py (100%) rename {opengl => pyqtgraph/opengl}/items/GLBoxItem.py (100%) rename {opengl => pyqtgraph/opengl}/items/GLGridItem.py (100%) rename {opengl => pyqtgraph/opengl}/items/GLImageItem.py (100%) rename {opengl => pyqtgraph/opengl}/items/GLMeshItem.py (100%) rename {opengl => pyqtgraph/opengl}/items/GLScatterPlotItem.py (100%) rename {opengl => pyqtgraph/opengl}/items/GLSurfacePlotItem.py (100%) rename {opengl => pyqtgraph/opengl}/items/GLVolumeItem.py (100%) rename {opengl => pyqtgraph/opengl}/items/__init__.py (100%) rename {opengl => pyqtgraph/opengl}/shaders.py (100%) rename {parametertree => pyqtgraph/parametertree}/Parameter.py (100%) rename {parametertree => pyqtgraph/parametertree}/ParameterItem.py (100%) rename {parametertree => pyqtgraph/parametertree}/ParameterTree.py (100%) rename {parametertree => pyqtgraph/parametertree}/__init__.py (100%) rename {parametertree => pyqtgraph/parametertree}/parameterTypes.py (100%) rename pgcollections.py => pyqtgraph/pgcollections.py (100%) rename {pixmaps => pyqtgraph/pixmaps}/__init__.py (100%) rename {pixmaps => pyqtgraph/pixmaps}/auto.png (100%) rename {pixmaps => pyqtgraph/pixmaps}/compile.py (100%) rename {pixmaps => pyqtgraph/pixmaps}/ctrl.png (100%) rename {pixmaps => pyqtgraph/pixmaps}/default.png (100%) rename {pixmaps => pyqtgraph/pixmaps}/icons.svg (100%) rename {pixmaps => pyqtgraph/pixmaps}/lock.png (100%) rename {pixmaps => pyqtgraph/pixmaps}/pixmapData_2.py (100%) rename {pixmaps => pyqtgraph/pixmaps}/pixmapData_3.py (100%) rename ptime.py => pyqtgraph/ptime.py (100%) rename python2_3.py => pyqtgraph/python2_3.py (100%) rename rebuildUi.py => pyqtgraph/rebuildUi.py (100%) rename reload.py => pyqtgraph/reload.py (100%) rename units.py => pyqtgraph/units.py (100%) rename {widgets => pyqtgraph/widgets}/BusyCursor.py (100%) rename {widgets => pyqtgraph/widgets}/CheckTable.py (100%) rename {widgets => pyqtgraph/widgets}/ColorButton.py (100%) rename {widgets => pyqtgraph/widgets}/ComboBox.py (100%) rename {widgets => pyqtgraph/widgets}/DataTreeWidget.py (100%) rename {widgets => pyqtgraph/widgets}/FeedbackButton.py (100%) rename {widgets => pyqtgraph/widgets}/FileDialog.py (100%) rename {widgets => pyqtgraph/widgets}/GradientWidget.py (100%) rename {widgets => pyqtgraph/widgets}/GraphicsLayoutWidget.py (100%) rename {widgets => pyqtgraph/widgets}/GraphicsView.py (100%) rename {widgets => pyqtgraph/widgets}/HistogramLUTWidget.py (100%) rename {widgets => pyqtgraph/widgets}/JoystickButton.py (100%) rename {widgets => pyqtgraph/widgets}/LayoutWidget.py (100%) rename {widgets => pyqtgraph/widgets}/MatplotlibWidget.py (100%) rename {widgets => pyqtgraph/widgets}/MultiPlotWidget.py (100%) rename {widgets => pyqtgraph/widgets}/PathButton.py (100%) rename {widgets => pyqtgraph/widgets}/PlotWidget.py (100%) rename {widgets => pyqtgraph/widgets}/ProgressDialog.py (100%) rename {widgets => pyqtgraph/widgets}/RawImageWidget.py (100%) rename {widgets => pyqtgraph/widgets}/RemoteGraphicsView.py (100%) rename {widgets => pyqtgraph/widgets}/SpinBox.py (100%) rename {widgets => pyqtgraph/widgets}/TableWidget.py (100%) rename {widgets => pyqtgraph/widgets}/TreeWidget.py (100%) rename {widgets => pyqtgraph/widgets}/ValueLabel.py (100%) rename {widgets => pyqtgraph/widgets}/VerticalLabel.py (100%) rename {widgets => pyqtgraph/widgets}/__init__.py (100%) create mode 100644 tests/__init__.py create mode 100644 tests/svg.py create mode 100644 tests/test.py diff --git a/license.txt b/LICENSE.txt similarity index 100% rename from license.txt rename to LICENSE.txt diff --git a/README b/README.txt similarity index 100% rename from README rename to README.txt diff --git a/documentation/Makefile b/doc/Makefile similarity index 100% rename from documentation/Makefile rename to doc/Makefile diff --git a/documentation/listmissing.py b/doc/listmissing.py similarity index 100% rename from documentation/listmissing.py rename to doc/listmissing.py diff --git a/documentation/make.bat b/doc/make.bat similarity index 100% rename from documentation/make.bat rename to doc/make.bat diff --git a/documentation/source/3dgraphics.rst b/doc/source/3dgraphics.rst similarity index 100% rename from documentation/source/3dgraphics.rst rename to doc/source/3dgraphics.rst diff --git a/documentation/source/3dgraphics/glaxisitem.rst b/doc/source/3dgraphics/glaxisitem.rst similarity index 100% rename from documentation/source/3dgraphics/glaxisitem.rst rename to doc/source/3dgraphics/glaxisitem.rst diff --git a/documentation/source/3dgraphics/glgraphicsitem.rst b/doc/source/3dgraphics/glgraphicsitem.rst similarity index 100% rename from documentation/source/3dgraphics/glgraphicsitem.rst rename to doc/source/3dgraphics/glgraphicsitem.rst diff --git a/documentation/source/3dgraphics/glgriditem.rst b/doc/source/3dgraphics/glgriditem.rst similarity index 100% rename from documentation/source/3dgraphics/glgriditem.rst rename to doc/source/3dgraphics/glgriditem.rst diff --git a/documentation/source/3dgraphics/glimageitem.rst b/doc/source/3dgraphics/glimageitem.rst similarity index 100% rename from documentation/source/3dgraphics/glimageitem.rst rename to doc/source/3dgraphics/glimageitem.rst diff --git a/documentation/source/3dgraphics/glmeshitem.rst b/doc/source/3dgraphics/glmeshitem.rst similarity index 100% rename from documentation/source/3dgraphics/glmeshitem.rst rename to doc/source/3dgraphics/glmeshitem.rst diff --git a/documentation/source/3dgraphics/glscatterplotitem.rst b/doc/source/3dgraphics/glscatterplotitem.rst similarity index 100% rename from documentation/source/3dgraphics/glscatterplotitem.rst rename to doc/source/3dgraphics/glscatterplotitem.rst diff --git a/documentation/source/3dgraphics/glsurfaceplotitem.rst b/doc/source/3dgraphics/glsurfaceplotitem.rst similarity index 100% rename from documentation/source/3dgraphics/glsurfaceplotitem.rst rename to doc/source/3dgraphics/glsurfaceplotitem.rst diff --git a/documentation/source/3dgraphics/glviewwidget.rst b/doc/source/3dgraphics/glviewwidget.rst similarity index 100% rename from documentation/source/3dgraphics/glviewwidget.rst rename to doc/source/3dgraphics/glviewwidget.rst diff --git a/documentation/source/3dgraphics/glvolumeitem.rst b/doc/source/3dgraphics/glvolumeitem.rst similarity index 100% rename from documentation/source/3dgraphics/glvolumeitem.rst rename to doc/source/3dgraphics/glvolumeitem.rst diff --git a/documentation/source/3dgraphics/index.rst b/doc/source/3dgraphics/index.rst similarity index 100% rename from documentation/source/3dgraphics/index.rst rename to doc/source/3dgraphics/index.rst diff --git a/documentation/source/3dgraphics/meshdata.rst b/doc/source/3dgraphics/meshdata.rst similarity index 100% rename from documentation/source/3dgraphics/meshdata.rst rename to doc/source/3dgraphics/meshdata.rst diff --git a/documentation/source/apireference.rst b/doc/source/apireference.rst similarity index 100% rename from documentation/source/apireference.rst rename to doc/source/apireference.rst diff --git a/documentation/source/conf.py b/doc/source/conf.py similarity index 100% rename from documentation/source/conf.py rename to doc/source/conf.py diff --git a/documentation/source/functions.rst b/doc/source/functions.rst similarity index 100% rename from documentation/source/functions.rst rename to doc/source/functions.rst diff --git a/documentation/source/graphicsItems/arrowitem.rst b/doc/source/graphicsItems/arrowitem.rst similarity index 100% rename from documentation/source/graphicsItems/arrowitem.rst rename to doc/source/graphicsItems/arrowitem.rst diff --git a/documentation/source/graphicsItems/axisitem.rst b/doc/source/graphicsItems/axisitem.rst similarity index 100% rename from documentation/source/graphicsItems/axisitem.rst rename to doc/source/graphicsItems/axisitem.rst diff --git a/documentation/source/graphicsItems/buttonitem.rst b/doc/source/graphicsItems/buttonitem.rst similarity index 100% rename from documentation/source/graphicsItems/buttonitem.rst rename to doc/source/graphicsItems/buttonitem.rst diff --git a/documentation/source/graphicsItems/curvearrow.rst b/doc/source/graphicsItems/curvearrow.rst similarity index 100% rename from documentation/source/graphicsItems/curvearrow.rst rename to doc/source/graphicsItems/curvearrow.rst diff --git a/documentation/source/graphicsItems/curvepoint.rst b/doc/source/graphicsItems/curvepoint.rst similarity index 100% rename from documentation/source/graphicsItems/curvepoint.rst rename to doc/source/graphicsItems/curvepoint.rst diff --git a/documentation/source/graphicsItems/fillbetweenitem.rst b/doc/source/graphicsItems/fillbetweenitem.rst similarity index 100% rename from documentation/source/graphicsItems/fillbetweenitem.rst rename to doc/source/graphicsItems/fillbetweenitem.rst diff --git a/documentation/source/graphicsItems/gradienteditoritem.rst b/doc/source/graphicsItems/gradienteditoritem.rst similarity index 100% rename from documentation/source/graphicsItems/gradienteditoritem.rst rename to doc/source/graphicsItems/gradienteditoritem.rst diff --git a/documentation/source/graphicsItems/gradientlegend.rst b/doc/source/graphicsItems/gradientlegend.rst similarity index 100% rename from documentation/source/graphicsItems/gradientlegend.rst rename to doc/source/graphicsItems/gradientlegend.rst diff --git a/documentation/source/graphicsItems/graphicsitem.rst b/doc/source/graphicsItems/graphicsitem.rst similarity index 100% rename from documentation/source/graphicsItems/graphicsitem.rst rename to doc/source/graphicsItems/graphicsitem.rst diff --git a/documentation/source/graphicsItems/graphicslayout.rst b/doc/source/graphicsItems/graphicslayout.rst similarity index 100% rename from documentation/source/graphicsItems/graphicslayout.rst rename to doc/source/graphicsItems/graphicslayout.rst diff --git a/documentation/source/graphicsItems/graphicsobject.rst b/doc/source/graphicsItems/graphicsobject.rst similarity index 100% rename from documentation/source/graphicsItems/graphicsobject.rst rename to doc/source/graphicsItems/graphicsobject.rst diff --git a/documentation/source/graphicsItems/graphicswidget.rst b/doc/source/graphicsItems/graphicswidget.rst similarity index 100% rename from documentation/source/graphicsItems/graphicswidget.rst rename to doc/source/graphicsItems/graphicswidget.rst diff --git a/documentation/source/graphicsItems/graphicswidgetanchor.rst b/doc/source/graphicsItems/graphicswidgetanchor.rst similarity index 100% rename from documentation/source/graphicsItems/graphicswidgetanchor.rst rename to doc/source/graphicsItems/graphicswidgetanchor.rst diff --git a/documentation/source/graphicsItems/griditem.rst b/doc/source/graphicsItems/griditem.rst similarity index 100% rename from documentation/source/graphicsItems/griditem.rst rename to doc/source/graphicsItems/griditem.rst diff --git a/documentation/source/graphicsItems/histogramlutitem.rst b/doc/source/graphicsItems/histogramlutitem.rst similarity index 100% rename from documentation/source/graphicsItems/histogramlutitem.rst rename to doc/source/graphicsItems/histogramlutitem.rst diff --git a/documentation/source/graphicsItems/imageitem.rst b/doc/source/graphicsItems/imageitem.rst similarity index 100% rename from documentation/source/graphicsItems/imageitem.rst rename to doc/source/graphicsItems/imageitem.rst diff --git a/documentation/source/graphicsItems/index.rst b/doc/source/graphicsItems/index.rst similarity index 100% rename from documentation/source/graphicsItems/index.rst rename to doc/source/graphicsItems/index.rst diff --git a/documentation/source/graphicsItems/infiniteline.rst b/doc/source/graphicsItems/infiniteline.rst similarity index 100% rename from documentation/source/graphicsItems/infiniteline.rst rename to doc/source/graphicsItems/infiniteline.rst diff --git a/documentation/source/graphicsItems/isocurveitem.rst b/doc/source/graphicsItems/isocurveitem.rst similarity index 100% rename from documentation/source/graphicsItems/isocurveitem.rst rename to doc/source/graphicsItems/isocurveitem.rst diff --git a/documentation/source/graphicsItems/labelitem.rst b/doc/source/graphicsItems/labelitem.rst similarity index 100% rename from documentation/source/graphicsItems/labelitem.rst rename to doc/source/graphicsItems/labelitem.rst diff --git a/documentation/source/graphicsItems/legenditem.rst b/doc/source/graphicsItems/legenditem.rst similarity index 100% rename from documentation/source/graphicsItems/legenditem.rst rename to doc/source/graphicsItems/legenditem.rst diff --git a/documentation/source/graphicsItems/linearregionitem.rst b/doc/source/graphicsItems/linearregionitem.rst similarity index 100% rename from documentation/source/graphicsItems/linearregionitem.rst rename to doc/source/graphicsItems/linearregionitem.rst diff --git a/documentation/source/graphicsItems/make b/doc/source/graphicsItems/make similarity index 100% rename from documentation/source/graphicsItems/make rename to doc/source/graphicsItems/make diff --git a/documentation/source/graphicsItems/plotcurveitem.rst b/doc/source/graphicsItems/plotcurveitem.rst similarity index 100% rename from documentation/source/graphicsItems/plotcurveitem.rst rename to doc/source/graphicsItems/plotcurveitem.rst diff --git a/documentation/source/graphicsItems/plotdataitem.rst b/doc/source/graphicsItems/plotdataitem.rst similarity index 100% rename from documentation/source/graphicsItems/plotdataitem.rst rename to doc/source/graphicsItems/plotdataitem.rst diff --git a/documentation/source/graphicsItems/plotitem.rst b/doc/source/graphicsItems/plotitem.rst similarity index 100% rename from documentation/source/graphicsItems/plotitem.rst rename to doc/source/graphicsItems/plotitem.rst diff --git a/documentation/source/graphicsItems/roi.rst b/doc/source/graphicsItems/roi.rst similarity index 100% rename from documentation/source/graphicsItems/roi.rst rename to doc/source/graphicsItems/roi.rst diff --git a/documentation/source/graphicsItems/scalebar.rst b/doc/source/graphicsItems/scalebar.rst similarity index 100% rename from documentation/source/graphicsItems/scalebar.rst rename to doc/source/graphicsItems/scalebar.rst diff --git a/documentation/source/graphicsItems/scatterplotitem.rst b/doc/source/graphicsItems/scatterplotitem.rst similarity index 100% rename from documentation/source/graphicsItems/scatterplotitem.rst rename to doc/source/graphicsItems/scatterplotitem.rst diff --git a/documentation/source/graphicsItems/textitem.rst b/doc/source/graphicsItems/textitem.rst similarity index 100% rename from documentation/source/graphicsItems/textitem.rst rename to doc/source/graphicsItems/textitem.rst diff --git a/documentation/source/graphicsItems/uigraphicsitem.rst b/doc/source/graphicsItems/uigraphicsitem.rst similarity index 100% rename from documentation/source/graphicsItems/uigraphicsitem.rst rename to doc/source/graphicsItems/uigraphicsitem.rst diff --git a/documentation/source/graphicsItems/viewbox.rst b/doc/source/graphicsItems/viewbox.rst similarity index 100% rename from documentation/source/graphicsItems/viewbox.rst rename to doc/source/graphicsItems/viewbox.rst diff --git a/documentation/source/graphicsItems/vtickgroup.rst b/doc/source/graphicsItems/vtickgroup.rst similarity index 100% rename from documentation/source/graphicsItems/vtickgroup.rst rename to doc/source/graphicsItems/vtickgroup.rst diff --git a/documentation/source/graphicsscene/graphicsscene.rst b/doc/source/graphicsscene/graphicsscene.rst similarity index 100% rename from documentation/source/graphicsscene/graphicsscene.rst rename to doc/source/graphicsscene/graphicsscene.rst diff --git a/documentation/source/graphicsscene/hoverevent.rst b/doc/source/graphicsscene/hoverevent.rst similarity index 100% rename from documentation/source/graphicsscene/hoverevent.rst rename to doc/source/graphicsscene/hoverevent.rst diff --git a/documentation/source/graphicsscene/index.rst b/doc/source/graphicsscene/index.rst similarity index 100% rename from documentation/source/graphicsscene/index.rst rename to doc/source/graphicsscene/index.rst diff --git a/documentation/source/graphicsscene/mouseclickevent.rst b/doc/source/graphicsscene/mouseclickevent.rst similarity index 100% rename from documentation/source/graphicsscene/mouseclickevent.rst rename to doc/source/graphicsscene/mouseclickevent.rst diff --git a/documentation/source/graphicsscene/mousedragevent.rst b/doc/source/graphicsscene/mousedragevent.rst similarity index 100% rename from documentation/source/graphicsscene/mousedragevent.rst rename to doc/source/graphicsscene/mousedragevent.rst diff --git a/documentation/source/graphicswindow.rst b/doc/source/graphicswindow.rst similarity index 100% rename from documentation/source/graphicswindow.rst rename to doc/source/graphicswindow.rst diff --git a/documentation/source/how_to_use.rst b/doc/source/how_to_use.rst similarity index 100% rename from documentation/source/how_to_use.rst rename to doc/source/how_to_use.rst diff --git a/documentation/source/images.rst b/doc/source/images.rst similarity index 100% rename from documentation/source/images.rst rename to doc/source/images.rst diff --git a/documentation/source/images/plottingClasses.png b/doc/source/images/plottingClasses.png similarity index 100% rename from documentation/source/images/plottingClasses.png rename to doc/source/images/plottingClasses.png diff --git a/documentation/source/images/plottingClasses.svg b/doc/source/images/plottingClasses.svg similarity index 100% rename from documentation/source/images/plottingClasses.svg rename to doc/source/images/plottingClasses.svg diff --git a/documentation/source/index.rst b/doc/source/index.rst similarity index 100% rename from documentation/source/index.rst rename to doc/source/index.rst diff --git a/documentation/source/installation.rst b/doc/source/installation.rst similarity index 100% rename from documentation/source/installation.rst rename to doc/source/installation.rst diff --git a/documentation/source/internals.rst b/doc/source/internals.rst similarity index 100% rename from documentation/source/internals.rst rename to doc/source/internals.rst diff --git a/documentation/source/introduction.rst b/doc/source/introduction.rst similarity index 100% rename from documentation/source/introduction.rst rename to doc/source/introduction.rst diff --git a/documentation/source/mouse_interaction.rst b/doc/source/mouse_interaction.rst similarity index 100% rename from documentation/source/mouse_interaction.rst rename to doc/source/mouse_interaction.rst diff --git a/documentation/source/parametertree/apiref.rst b/doc/source/parametertree/apiref.rst similarity index 100% rename from documentation/source/parametertree/apiref.rst rename to doc/source/parametertree/apiref.rst diff --git a/documentation/source/parametertree/index.rst b/doc/source/parametertree/index.rst similarity index 100% rename from documentation/source/parametertree/index.rst rename to doc/source/parametertree/index.rst diff --git a/documentation/source/parametertree/parameter.rst b/doc/source/parametertree/parameter.rst similarity index 100% rename from documentation/source/parametertree/parameter.rst rename to doc/source/parametertree/parameter.rst diff --git a/documentation/source/parametertree/parameteritem.rst b/doc/source/parametertree/parameteritem.rst similarity index 100% rename from documentation/source/parametertree/parameteritem.rst rename to doc/source/parametertree/parameteritem.rst diff --git a/documentation/source/parametertree/parametertree.rst b/doc/source/parametertree/parametertree.rst similarity index 100% rename from documentation/source/parametertree/parametertree.rst rename to doc/source/parametertree/parametertree.rst diff --git a/documentation/source/parametertree/parametertypes.rst b/doc/source/parametertree/parametertypes.rst similarity index 100% rename from documentation/source/parametertree/parametertypes.rst rename to doc/source/parametertree/parametertypes.rst diff --git a/documentation/source/plotting.rst b/doc/source/plotting.rst similarity index 100% rename from documentation/source/plotting.rst rename to doc/source/plotting.rst diff --git a/documentation/source/prototyping.rst b/doc/source/prototyping.rst similarity index 100% rename from documentation/source/prototyping.rst rename to doc/source/prototyping.rst diff --git a/documentation/source/region_of_interest.rst b/doc/source/region_of_interest.rst similarity index 100% rename from documentation/source/region_of_interest.rst rename to doc/source/region_of_interest.rst diff --git a/documentation/source/style.rst b/doc/source/style.rst similarity index 100% rename from documentation/source/style.rst rename to doc/source/style.rst diff --git a/documentation/source/widgets/busycursor.rst b/doc/source/widgets/busycursor.rst similarity index 100% rename from documentation/source/widgets/busycursor.rst rename to doc/source/widgets/busycursor.rst diff --git a/documentation/source/widgets/checktable.rst b/doc/source/widgets/checktable.rst similarity index 100% rename from documentation/source/widgets/checktable.rst rename to doc/source/widgets/checktable.rst diff --git a/documentation/source/widgets/colorbutton.rst b/doc/source/widgets/colorbutton.rst similarity index 100% rename from documentation/source/widgets/colorbutton.rst rename to doc/source/widgets/colorbutton.rst diff --git a/documentation/source/widgets/combobox.rst b/doc/source/widgets/combobox.rst similarity index 100% rename from documentation/source/widgets/combobox.rst rename to doc/source/widgets/combobox.rst diff --git a/documentation/source/widgets/datatreewidget.rst b/doc/source/widgets/datatreewidget.rst similarity index 100% rename from documentation/source/widgets/datatreewidget.rst rename to doc/source/widgets/datatreewidget.rst diff --git a/documentation/source/widgets/dockarea.rst b/doc/source/widgets/dockarea.rst similarity index 100% rename from documentation/source/widgets/dockarea.rst rename to doc/source/widgets/dockarea.rst diff --git a/documentation/source/widgets/feedbackbutton.rst b/doc/source/widgets/feedbackbutton.rst similarity index 100% rename from documentation/source/widgets/feedbackbutton.rst rename to doc/source/widgets/feedbackbutton.rst diff --git a/documentation/source/widgets/filedialog.rst b/doc/source/widgets/filedialog.rst similarity index 100% rename from documentation/source/widgets/filedialog.rst rename to doc/source/widgets/filedialog.rst diff --git a/documentation/source/widgets/gradientwidget.rst b/doc/source/widgets/gradientwidget.rst similarity index 100% rename from documentation/source/widgets/gradientwidget.rst rename to doc/source/widgets/gradientwidget.rst diff --git a/documentation/source/widgets/graphicslayoutwidget.rst b/doc/source/widgets/graphicslayoutwidget.rst similarity index 100% rename from documentation/source/widgets/graphicslayoutwidget.rst rename to doc/source/widgets/graphicslayoutwidget.rst diff --git a/documentation/source/widgets/graphicsview.rst b/doc/source/widgets/graphicsview.rst similarity index 100% rename from documentation/source/widgets/graphicsview.rst rename to doc/source/widgets/graphicsview.rst diff --git a/documentation/source/widgets/histogramlutwidget.rst b/doc/source/widgets/histogramlutwidget.rst similarity index 100% rename from documentation/source/widgets/histogramlutwidget.rst rename to doc/source/widgets/histogramlutwidget.rst diff --git a/documentation/source/widgets/imageview.rst b/doc/source/widgets/imageview.rst similarity index 100% rename from documentation/source/widgets/imageview.rst rename to doc/source/widgets/imageview.rst diff --git a/documentation/source/widgets/index.rst b/doc/source/widgets/index.rst similarity index 100% rename from documentation/source/widgets/index.rst rename to doc/source/widgets/index.rst diff --git a/documentation/source/widgets/joystickbutton.rst b/doc/source/widgets/joystickbutton.rst similarity index 100% rename from documentation/source/widgets/joystickbutton.rst rename to doc/source/widgets/joystickbutton.rst diff --git a/documentation/source/widgets/layoutwidget.rst b/doc/source/widgets/layoutwidget.rst similarity index 100% rename from documentation/source/widgets/layoutwidget.rst rename to doc/source/widgets/layoutwidget.rst diff --git a/documentation/source/widgets/make b/doc/source/widgets/make similarity index 100% rename from documentation/source/widgets/make rename to doc/source/widgets/make diff --git a/documentation/source/widgets/matplotlibwidget.rst b/doc/source/widgets/matplotlibwidget.rst similarity index 100% rename from documentation/source/widgets/matplotlibwidget.rst rename to doc/source/widgets/matplotlibwidget.rst diff --git a/documentation/source/widgets/multiplotwidget.rst b/doc/source/widgets/multiplotwidget.rst similarity index 100% rename from documentation/source/widgets/multiplotwidget.rst rename to doc/source/widgets/multiplotwidget.rst diff --git a/documentation/source/widgets/parametertree.rst b/doc/source/widgets/parametertree.rst similarity index 100% rename from documentation/source/widgets/parametertree.rst rename to doc/source/widgets/parametertree.rst diff --git a/documentation/source/widgets/pathbutton.rst b/doc/source/widgets/pathbutton.rst similarity index 100% rename from documentation/source/widgets/pathbutton.rst rename to doc/source/widgets/pathbutton.rst diff --git a/documentation/source/widgets/plotwidget.rst b/doc/source/widgets/plotwidget.rst similarity index 100% rename from documentation/source/widgets/plotwidget.rst rename to doc/source/widgets/plotwidget.rst diff --git a/documentation/source/widgets/progressdialog.rst b/doc/source/widgets/progressdialog.rst similarity index 100% rename from documentation/source/widgets/progressdialog.rst rename to doc/source/widgets/progressdialog.rst diff --git a/documentation/source/widgets/rawimagewidget.rst b/doc/source/widgets/rawimagewidget.rst similarity index 100% rename from documentation/source/widgets/rawimagewidget.rst rename to doc/source/widgets/rawimagewidget.rst diff --git a/documentation/source/widgets/remotegraphicsview.rst b/doc/source/widgets/remotegraphicsview.rst similarity index 100% rename from documentation/source/widgets/remotegraphicsview.rst rename to doc/source/widgets/remotegraphicsview.rst diff --git a/documentation/source/widgets/spinbox.rst b/doc/source/widgets/spinbox.rst similarity index 100% rename from documentation/source/widgets/spinbox.rst rename to doc/source/widgets/spinbox.rst diff --git a/documentation/source/widgets/tablewidget.rst b/doc/source/widgets/tablewidget.rst similarity index 100% rename from documentation/source/widgets/tablewidget.rst rename to doc/source/widgets/tablewidget.rst diff --git a/documentation/source/widgets/treewidget.rst b/doc/source/widgets/treewidget.rst similarity index 100% rename from documentation/source/widgets/treewidget.rst rename to doc/source/widgets/treewidget.rst diff --git a/documentation/source/widgets/valuelabel.rst b/doc/source/widgets/valuelabel.rst similarity index 100% rename from documentation/source/widgets/valuelabel.rst rename to doc/source/widgets/valuelabel.rst diff --git a/documentation/source/widgets/verticallabel.rst b/doc/source/widgets/verticallabel.rst similarity index 100% rename from documentation/source/widgets/verticallabel.rst rename to doc/source/widgets/verticallabel.rst diff --git a/examples/__main__.py b/examples/__main__.py index 6f4bf138..1dbe7b9a 100644 --- a/examples/__main__.py +++ b/examples/__main__.py @@ -126,6 +126,9 @@ class ExampleLoader(QtGui.QMainWindow): extra.append('pyqt') elif self.ui.pysideCheck.isChecked(): extra.append('pyside') + + if self.ui.forceGraphicsCheck.isChecked(): + extra.append(str(self.ui.forceGraphicsCombo.currentText())) if fn is None: return @@ -163,22 +166,26 @@ def buildFileList(examples, files=None): buildFileList(val, files) return files -def testFile(name, f, exe, lib): +def testFile(name, f, exe, lib, graphicsSystem): global path fn = os.path.join(path,f) #print "starting process: ", fn - + os.chdir(path) sys.stdout.write(name) sys.stdout.flush() + import1 = "import %s" % lib if lib != '' else '' + import2 = os.path.splitext(os.path.split(fn)[1])[0] + graphicsSystem = '' if graphicsSystem is None else "pg.QtGui.QApplication.setGraphicsSystem('%s')" % graphicsSystem code = """ try: + %s + import pyqtgraph as pg %s import %s import sys print("test complete") sys.stdout.flush() - import pyqtgraph as pg import time while True: ## run a little event loop pg.QtGui.QApplication.processEvents() @@ -187,7 +194,7 @@ except: print("test failed") raise -""" % ("import %s" % lib if lib != '' else "", os.path.splitext(os.path.split(fn)[1])[0]) +""" % (import1, import2, graphicsSystem) #print code 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')) diff --git a/examples/exampleLoaderTemplate.ui b/examples/exampleLoaderTemplate.ui index 1453240c..cd5ce921 100644 --- a/examples/exampleLoaderTemplate.ui +++ b/examples/exampleLoaderTemplate.ui @@ -57,6 +57,36 @@ + + + + + + Force Graphics System: + + + + + + + + native + + + + + raster + + + + + opengl + + + + + + diff --git a/examples/exampleLoaderTemplate_pyqt.py b/examples/exampleLoaderTemplate_pyqt.py index 26e55a44..f359cc32 100644 --- a/examples/exampleLoaderTemplate_pyqt.py +++ b/examples/exampleLoaderTemplate_pyqt.py @@ -2,7 +2,7 @@ # Form implementation generated from reading ui file './examples/exampleLoaderTemplate.ui' # -# Created: Fri Oct 26 07:53:55 2012 +# Created: Mon Dec 24 00:33:38 2012 # by: PyQt4 UI code generator 4.9.1 # # WARNING! All changes made in this file will be lost! @@ -44,6 +44,18 @@ class Ui_Form(object): self.pysideCheck.setObjectName(_fromUtf8("pysideCheck")) self.horizontalLayout.addWidget(self.pysideCheck) self.verticalLayout.addLayout(self.horizontalLayout) + self.horizontalLayout_2 = QtGui.QHBoxLayout() + self.horizontalLayout_2.setObjectName(_fromUtf8("horizontalLayout_2")) + self.forceGraphicsCheck = QtGui.QCheckBox(self.layoutWidget) + self.forceGraphicsCheck.setObjectName(_fromUtf8("forceGraphicsCheck")) + self.horizontalLayout_2.addWidget(self.forceGraphicsCheck) + self.forceGraphicsCombo = QtGui.QComboBox(self.layoutWidget) + self.forceGraphicsCombo.setObjectName(_fromUtf8("forceGraphicsCombo")) + self.forceGraphicsCombo.addItem(_fromUtf8("")) + self.forceGraphicsCombo.addItem(_fromUtf8("")) + self.forceGraphicsCombo.addItem(_fromUtf8("")) + self.horizontalLayout_2.addWidget(self.forceGraphicsCombo) + self.verticalLayout.addLayout(self.horizontalLayout_2) self.loadBtn = QtGui.QPushButton(self.layoutWidget) self.loadBtn.setObjectName(_fromUtf8("loadBtn")) self.verticalLayout.addWidget(self.loadBtn) @@ -62,5 +74,9 @@ class Ui_Form(object): Form.setWindowTitle(QtGui.QApplication.translate("Form", "Form", None, QtGui.QApplication.UnicodeUTF8)) self.pyqtCheck.setText(QtGui.QApplication.translate("Form", "Force PyQt", None, QtGui.QApplication.UnicodeUTF8)) self.pysideCheck.setText(QtGui.QApplication.translate("Form", "Force PySide", None, QtGui.QApplication.UnicodeUTF8)) + self.forceGraphicsCheck.setText(QtGui.QApplication.translate("Form", "Force Graphics System:", 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(2, QtGui.QApplication.translate("Form", "opengl", None, QtGui.QApplication.UnicodeUTF8)) self.loadBtn.setText(QtGui.QApplication.translate("Form", "Load Example", None, QtGui.QApplication.UnicodeUTF8)) diff --git a/examples/exampleLoaderTemplate_pyside.py b/examples/exampleLoaderTemplate_pyside.py index a81f7299..113c1654 100644 --- a/examples/exampleLoaderTemplate_pyside.py +++ b/examples/exampleLoaderTemplate_pyside.py @@ -2,8 +2,8 @@ # Form implementation generated from reading ui file './examples/exampleLoaderTemplate.ui' # -# Created: Fri Oct 26 07:53:57 2012 -# by: pyside-uic 0.2.13 running on PySide 1.1.0 +# Created: Mon Dec 24 00:33:39 2012 +# by: pyside-uic 0.2.13 running on PySide 1.1.2 # # WARNING! All changes made in this file will be lost! @@ -39,6 +39,18 @@ class Ui_Form(object): self.pysideCheck.setObjectName("pysideCheck") self.horizontalLayout.addWidget(self.pysideCheck) self.verticalLayout.addLayout(self.horizontalLayout) + self.horizontalLayout_2 = QtGui.QHBoxLayout() + self.horizontalLayout_2.setObjectName("horizontalLayout_2") + self.forceGraphicsCheck = QtGui.QCheckBox(self.layoutWidget) + self.forceGraphicsCheck.setObjectName("forceGraphicsCheck") + self.horizontalLayout_2.addWidget(self.forceGraphicsCheck) + self.forceGraphicsCombo = QtGui.QComboBox(self.layoutWidget) + self.forceGraphicsCombo.setObjectName("forceGraphicsCombo") + self.forceGraphicsCombo.addItem("") + self.forceGraphicsCombo.addItem("") + self.forceGraphicsCombo.addItem("") + self.horizontalLayout_2.addWidget(self.forceGraphicsCombo) + self.verticalLayout.addLayout(self.horizontalLayout_2) self.loadBtn = QtGui.QPushButton(self.layoutWidget) self.loadBtn.setObjectName("loadBtn") self.verticalLayout.addWidget(self.loadBtn) @@ -57,5 +69,9 @@ class Ui_Form(object): Form.setWindowTitle(QtGui.QApplication.translate("Form", "Form", None, QtGui.QApplication.UnicodeUTF8)) self.pyqtCheck.setText(QtGui.QApplication.translate("Form", "Force PyQt", None, QtGui.QApplication.UnicodeUTF8)) self.pysideCheck.setText(QtGui.QApplication.translate("Form", "Force PySide", None, QtGui.QApplication.UnicodeUTF8)) + self.forceGraphicsCheck.setText(QtGui.QApplication.translate("Form", "Force Graphics System:", 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(2, QtGui.QApplication.translate("Form", "opengl", None, QtGui.QApplication.UnicodeUTF8)) self.loadBtn.setText(QtGui.QApplication.translate("Form", "Load Example", None, QtGui.QApplication.UnicodeUTF8)) diff --git a/examples/initExample.py b/examples/initExample.py index 1b38363b..908f5fb0 100644 --- a/examples/initExample.py +++ b/examples/initExample.py @@ -3,6 +3,14 @@ import sys, os sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..'))) if 'pyside' in sys.argv: ## should force example to use PySide instead of PyQt - import PySide + from PySide import QtGui elif 'pyqt' in sys.argv: - import PyQt4 + from PyQt4 import QtGui +else: + from pyqtgraph.Qt import QtGui + +for gs in ['raster', 'native', 'opengl']: + if gs in sys.argv: + QtGui.QApplication.setGraphicsSystem(gs) + break + diff --git a/exporters/SVGExporter.py b/exporters/SVGExporter.py deleted file mode 100644 index 2d040282..00000000 --- a/exporters/SVGExporter.py +++ /dev/null @@ -1,71 +0,0 @@ -from .Exporter import Exporter -from pyqtgraph.parametertree import Parameter -from pyqtgraph.Qt import QtGui, QtCore, QtSvg -import re - -__all__ = ['SVGExporter'] - -class SVGExporter(Exporter): - Name = "Scalable Vector Graphics (SVG)" - def __init__(self, item): - Exporter.__init__(self, item) - tr = self.getTargetRect() - self.params = Parameter(name='params', type='group', children=[ - {'name': 'width', 'type': 'float', 'value': tr.width(), 'limits': (0, None)}, - {'name': 'height', 'type': 'float', 'value': tr.height(), 'limits': (0, None)}, - ]) - self.params.param('width').sigValueChanged.connect(self.widthChanged) - self.params.param('height').sigValueChanged.connect(self.heightChanged) - - def widthChanged(self): - sr = self.getSourceRect() - ar = sr.height() / sr.width() - self.params.param('height').setValue(self.params['width'] * ar, blockSignal=self.heightChanged) - - def heightChanged(self): - sr = self.getSourceRect() - ar = sr.width() / sr.height() - self.params.param('width').setValue(self.params['height'] * ar, blockSignal=self.widthChanged) - - def parameters(self): - return self.params - - def export(self, fileName=None): - if fileName is None: - self.fileSaveDialog(filter="Scalable Vector Graphics (*.svg)") - return - self.svg = QtSvg.QSvgGenerator() - self.svg.setFileName(fileName) - dpi = QtGui.QDesktopWidget().physicalDpiX() - ## not really sure why this works, but it seems to be important: - self.svg.setSize(QtCore.QSize(self.params['width']*dpi/90., self.params['height']*dpi/90.)) - self.svg.setResolution(dpi) - #self.svg.setViewBox() - targetRect = QtCore.QRect(0, 0, self.params['width'], self.params['height']) - sourceRect = self.getSourceRect() - - painter = QtGui.QPainter(self.svg) - try: - self.setExportMode(True) - self.render(painter, QtCore.QRectF(targetRect), sourceRect) - finally: - self.setExportMode(False) - painter.end() - - ## Workaround to set pen widths correctly - data = open(fileName).readlines() - for i in range(len(data)): - line = data[i] - m = re.match(r'( + +pyqtgraph SVG export +Generated with Qt and pyqtgraph + + +""" + node.toprettyxml(indent=' ') + "\n\n" + + if toBytes: + return bytes(xml) + else: + with open(fileName, 'w') as fh: + fh.write(xml) + + def generateItemSvg(self, item): + if isinstance(item, QtGui.QGraphicsScene): + xmlStr = "" + childs = [i for i in item.items() if i.parentItem() is None] + else: + tr = QtGui.QTransform() + tr.translate(item.pos().x(), item.pos().y()) + tr = tr * item.transform() + if not item.isVisible() or int(item.flags() & item.ItemHasNoContents) > 0: + m = (tr.m11(), tr.m12(), tr.m21(), tr.m22(), tr.m31(), tr.m32()) + #print item, m + xmlStr = '' % m + else: + arr = QtCore.QByteArray() + buf = QtCore.QBuffer(arr) + svg = QtSvg.QSvgGenerator() + svg.setOutputDevice(buf) + dpi = QtGui.QDesktopWidget().physicalDpiX() + ### not really sure why this works, but it seems to be important: + #self.svg.setSize(QtCore.QSize(self.params['width']*dpi/90., self.params['height']*dpi/90.)) + svg.setResolution(dpi) + + p = QtGui.QPainter() + p.begin(svg) + if hasattr(item, 'setExportMode'): + item.setExportMode(True, {'painter': p}) + try: + #tr = QtGui.QTransform() + #tr.translate(item.pos().x(), item.pos().y()) + #p.setTransform(tr * item.transform()) + p.setTransform(tr) + item.paint(p, QtGui.QStyleOptionGraphicsItem(), None) + finally: + p.end() + if hasattr(item, 'setExportMode'): + item.setExportMode(False) + + xmlStr = str(arr) + childs = item.childItems() + + doc = xml.parseString(xmlStr) + try: + groups = doc.getElementsByTagName('g') + if len(groups) == 1: + g1 = g2 = groups[0] + else: + g1,g2 = groups[:2] + except: + print doc.toxml() + raise + g1.setAttribute('id', item.__class__.__name__) + + ## Check for item visibility + visible = True + if not isinstance(item, QtGui.QGraphicsScene): + parent = item + while visible and parent is not None: + visible = parent.isVisible() + parent = parent.parentItem() + + if not visible: + style = g1.getAttribute('style').strip() + if len(style)>0 and not style.endswith(';'): + style += ';' + style += 'display:none;' + g1.setAttribute('style', style) + + childs.sort(key=lambda c: c.zValue()) + for ch in childs: + cg = self.generateItemSvg(ch) + g2.appendChild(cg) + + return g1 + + + + ### To check: + ### do all items really generate this double-group structure? + ### are both groups necessary? + ### How do we implement clipping? (can we clip to an object that is visible?) + + + + + + + diff --git a/exporters/__init__.py b/pyqtgraph/exporters/__init__.py similarity index 100% rename from exporters/__init__.py rename to pyqtgraph/exporters/__init__.py diff --git a/flowchart/Flowchart.py b/pyqtgraph/flowchart/Flowchart.py similarity index 100% rename from flowchart/Flowchart.py rename to pyqtgraph/flowchart/Flowchart.py diff --git a/flowchart/FlowchartCtrlTemplate.ui b/pyqtgraph/flowchart/FlowchartCtrlTemplate.ui similarity index 100% rename from flowchart/FlowchartCtrlTemplate.ui rename to pyqtgraph/flowchart/FlowchartCtrlTemplate.ui diff --git a/flowchart/FlowchartCtrlTemplate_pyqt.py b/pyqtgraph/flowchart/FlowchartCtrlTemplate_pyqt.py similarity index 100% rename from flowchart/FlowchartCtrlTemplate_pyqt.py rename to pyqtgraph/flowchart/FlowchartCtrlTemplate_pyqt.py diff --git a/flowchart/FlowchartCtrlTemplate_pyside.py b/pyqtgraph/flowchart/FlowchartCtrlTemplate_pyside.py similarity index 100% rename from flowchart/FlowchartCtrlTemplate_pyside.py rename to pyqtgraph/flowchart/FlowchartCtrlTemplate_pyside.py diff --git a/flowchart/FlowchartGraphicsView.py b/pyqtgraph/flowchart/FlowchartGraphicsView.py similarity index 100% rename from flowchart/FlowchartGraphicsView.py rename to pyqtgraph/flowchart/FlowchartGraphicsView.py diff --git a/flowchart/FlowchartTemplate.ui b/pyqtgraph/flowchart/FlowchartTemplate.ui similarity index 100% rename from flowchart/FlowchartTemplate.ui rename to pyqtgraph/flowchart/FlowchartTemplate.ui diff --git a/flowchart/FlowchartTemplate_pyqt.py b/pyqtgraph/flowchart/FlowchartTemplate_pyqt.py similarity index 100% rename from flowchart/FlowchartTemplate_pyqt.py rename to pyqtgraph/flowchart/FlowchartTemplate_pyqt.py diff --git a/flowchart/FlowchartTemplate_pyside.py b/pyqtgraph/flowchart/FlowchartTemplate_pyside.py similarity index 100% rename from flowchart/FlowchartTemplate_pyside.py rename to pyqtgraph/flowchart/FlowchartTemplate_pyside.py diff --git a/flowchart/Node.py b/pyqtgraph/flowchart/Node.py similarity index 100% rename from flowchart/Node.py rename to pyqtgraph/flowchart/Node.py diff --git a/flowchart/Terminal.py b/pyqtgraph/flowchart/Terminal.py similarity index 100% rename from flowchart/Terminal.py rename to pyqtgraph/flowchart/Terminal.py diff --git a/flowchart/__init__.py b/pyqtgraph/flowchart/__init__.py similarity index 100% rename from flowchart/__init__.py rename to pyqtgraph/flowchart/__init__.py diff --git a/flowchart/eq.py b/pyqtgraph/flowchart/eq.py similarity index 100% rename from flowchart/eq.py rename to pyqtgraph/flowchart/eq.py diff --git a/flowchart/library/Data.py b/pyqtgraph/flowchart/library/Data.py similarity index 100% rename from flowchart/library/Data.py rename to pyqtgraph/flowchart/library/Data.py diff --git a/flowchart/library/Display.py b/pyqtgraph/flowchart/library/Display.py similarity index 100% rename from flowchart/library/Display.py rename to pyqtgraph/flowchart/library/Display.py diff --git a/flowchart/library/Filters.py b/pyqtgraph/flowchart/library/Filters.py similarity index 100% rename from flowchart/library/Filters.py rename to pyqtgraph/flowchart/library/Filters.py diff --git a/flowchart/library/Operators.py b/pyqtgraph/flowchart/library/Operators.py similarity index 100% rename from flowchart/library/Operators.py rename to pyqtgraph/flowchart/library/Operators.py diff --git a/flowchart/library/__init__.py b/pyqtgraph/flowchart/library/__init__.py similarity index 100% rename from flowchart/library/__init__.py rename to pyqtgraph/flowchart/library/__init__.py diff --git a/flowchart/library/common.py b/pyqtgraph/flowchart/library/common.py similarity index 100% rename from flowchart/library/common.py rename to pyqtgraph/flowchart/library/common.py diff --git a/flowchart/library/functions.py b/pyqtgraph/flowchart/library/functions.py similarity index 100% rename from flowchart/library/functions.py rename to pyqtgraph/flowchart/library/functions.py diff --git a/frozenSupport.py b/pyqtgraph/frozenSupport.py similarity index 100% rename from frozenSupport.py rename to pyqtgraph/frozenSupport.py diff --git a/functions.py b/pyqtgraph/functions.py similarity index 100% rename from functions.py rename to pyqtgraph/functions.py diff --git a/graphicsItems/ArrowItem.py b/pyqtgraph/graphicsItems/ArrowItem.py similarity index 100% rename from graphicsItems/ArrowItem.py rename to pyqtgraph/graphicsItems/ArrowItem.py diff --git a/graphicsItems/AxisItem.py b/pyqtgraph/graphicsItems/AxisItem.py similarity index 100% rename from graphicsItems/AxisItem.py rename to pyqtgraph/graphicsItems/AxisItem.py diff --git a/graphicsItems/ButtonItem.py b/pyqtgraph/graphicsItems/ButtonItem.py similarity index 100% rename from graphicsItems/ButtonItem.py rename to pyqtgraph/graphicsItems/ButtonItem.py diff --git a/graphicsItems/CurvePoint.py b/pyqtgraph/graphicsItems/CurvePoint.py similarity index 100% rename from graphicsItems/CurvePoint.py rename to pyqtgraph/graphicsItems/CurvePoint.py diff --git a/graphicsItems/FillBetweenItem.py b/pyqtgraph/graphicsItems/FillBetweenItem.py similarity index 100% rename from graphicsItems/FillBetweenItem.py rename to pyqtgraph/graphicsItems/FillBetweenItem.py diff --git a/graphicsItems/GradientEditorItem.py b/pyqtgraph/graphicsItems/GradientEditorItem.py similarity index 100% rename from graphicsItems/GradientEditorItem.py rename to pyqtgraph/graphicsItems/GradientEditorItem.py diff --git a/graphicsItems/GradientLegend.py b/pyqtgraph/graphicsItems/GradientLegend.py similarity index 100% rename from graphicsItems/GradientLegend.py rename to pyqtgraph/graphicsItems/GradientLegend.py diff --git a/graphicsItems/GraphicsItem.py b/pyqtgraph/graphicsItems/GraphicsItem.py similarity index 95% rename from graphicsItems/GraphicsItem.py rename to pyqtgraph/graphicsItems/GraphicsItem.py index 43b8148c..6a0825dd 100644 --- a/graphicsItems/GraphicsItem.py +++ b/pyqtgraph/graphicsItems/GraphicsItem.py @@ -28,10 +28,13 @@ class GraphicsItem(object): self._viewWidget = None self._viewBox = None self._connectedView = None + self._exportOpts = False ## If False, not currently exporting. Otherwise, contains dict of export options. if register: GraphicsScene.registerObject(self) ## workaround for pyqt bug in graphicsscene.items() - + + + def getViewWidget(self): """ Return the view widget for this item. If the scene has multiple views, only the first view is returned. @@ -82,6 +85,9 @@ class GraphicsItem(object): Return the transform that converts local item coordinates to device coordinates (usually pixels). Extends deviceTransform to automatically determine the viewportTransform. """ + if self._exportOpts is not False and 'painter' in self._exportOpts: ## currently exporting; device transform may be different. + return self._exportOpts['painter'].deviceTransform() + if viewportTransform is None: view = self.getViewWidget() if view is None: @@ -476,4 +482,18 @@ class GraphicsItem(object): return tree + def setExportMode(self, export, opts=None): + """ + This method is called by exporters to inform items that they are being drawn for export + with a specific set of options. Items access these via self._exportOptions. + When exporting is complete, _exportOptions is set to False. + """ + if opts is None: + opts = {} + if export: + self._exportOpts = opts + #if 'antialias' not in opts: + #self._exportOpts['antialias'] = True + else: + self._exportOpts = False \ No newline at end of file diff --git a/graphicsItems/GraphicsLayout.py b/pyqtgraph/graphicsItems/GraphicsLayout.py similarity index 100% rename from graphicsItems/GraphicsLayout.py rename to pyqtgraph/graphicsItems/GraphicsLayout.py diff --git a/graphicsItems/GraphicsObject.py b/pyqtgraph/graphicsItems/GraphicsObject.py similarity index 100% rename from graphicsItems/GraphicsObject.py rename to pyqtgraph/graphicsItems/GraphicsObject.py diff --git a/graphicsItems/GraphicsWidget.py b/pyqtgraph/graphicsItems/GraphicsWidget.py similarity index 100% rename from graphicsItems/GraphicsWidget.py rename to pyqtgraph/graphicsItems/GraphicsWidget.py diff --git a/graphicsItems/GraphicsWidgetAnchor.py b/pyqtgraph/graphicsItems/GraphicsWidgetAnchor.py similarity index 100% rename from graphicsItems/GraphicsWidgetAnchor.py rename to pyqtgraph/graphicsItems/GraphicsWidgetAnchor.py diff --git a/graphicsItems/GridItem.py b/pyqtgraph/graphicsItems/GridItem.py similarity index 100% rename from graphicsItems/GridItem.py rename to pyqtgraph/graphicsItems/GridItem.py diff --git a/graphicsItems/HistogramLUTItem.py b/pyqtgraph/graphicsItems/HistogramLUTItem.py similarity index 100% rename from graphicsItems/HistogramLUTItem.py rename to pyqtgraph/graphicsItems/HistogramLUTItem.py diff --git a/graphicsItems/ImageItem.py b/pyqtgraph/graphicsItems/ImageItem.py similarity index 100% rename from graphicsItems/ImageItem.py rename to pyqtgraph/graphicsItems/ImageItem.py diff --git a/graphicsItems/InfiniteLine.py b/pyqtgraph/graphicsItems/InfiniteLine.py similarity index 100% rename from graphicsItems/InfiniteLine.py rename to pyqtgraph/graphicsItems/InfiniteLine.py diff --git a/graphicsItems/IsocurveItem.py b/pyqtgraph/graphicsItems/IsocurveItem.py similarity index 100% rename from graphicsItems/IsocurveItem.py rename to pyqtgraph/graphicsItems/IsocurveItem.py diff --git a/graphicsItems/ItemGroup.py b/pyqtgraph/graphicsItems/ItemGroup.py similarity index 100% rename from graphicsItems/ItemGroup.py rename to pyqtgraph/graphicsItems/ItemGroup.py diff --git a/graphicsItems/LabelItem.py b/pyqtgraph/graphicsItems/LabelItem.py similarity index 100% rename from graphicsItems/LabelItem.py rename to pyqtgraph/graphicsItems/LabelItem.py diff --git a/graphicsItems/LegendItem.py b/pyqtgraph/graphicsItems/LegendItem.py similarity index 100% rename from graphicsItems/LegendItem.py rename to pyqtgraph/graphicsItems/LegendItem.py diff --git a/graphicsItems/LinearRegionItem.py b/pyqtgraph/graphicsItems/LinearRegionItem.py similarity index 100% rename from graphicsItems/LinearRegionItem.py rename to pyqtgraph/graphicsItems/LinearRegionItem.py diff --git a/graphicsItems/MultiPlotItem.py b/pyqtgraph/graphicsItems/MultiPlotItem.py similarity index 100% rename from graphicsItems/MultiPlotItem.py rename to pyqtgraph/graphicsItems/MultiPlotItem.py diff --git a/graphicsItems/PlotCurveItem.py b/pyqtgraph/graphicsItems/PlotCurveItem.py similarity index 97% rename from graphicsItems/PlotCurveItem.py rename to pyqtgraph/graphicsItems/PlotCurveItem.py index c49ce30b..5314b0f2 100644 --- a/graphicsItems/PlotCurveItem.py +++ b/pyqtgraph/graphicsItems/PlotCurveItem.py @@ -52,7 +52,6 @@ class PlotCurveItem(GraphicsObject): self.clear() self.path = None self.fillPath = None - self.exportOpts = False ## this is disastrous for performance. @@ -404,8 +403,8 @@ class PlotCurveItem(GraphicsObject): path = self.path prof.mark('generate path') - if self.exportOpts is not False: - aa = self.exportOpts['antialias'] + if self._exportOpts is not False: + aa = self._exportOpts.get('antialias', True) else: aa = self.opts['antialias'] @@ -441,7 +440,7 @@ class PlotCurveItem(GraphicsObject): - if sp is not None: + if sp is not None and sp.style() != QtCore.Qt.NoPen: p.setPen(sp) p.drawPath(path) p.setPen(cp) @@ -487,13 +486,6 @@ class PlotCurveItem(GraphicsObject): ev.accept() self.sigClicked.emit(self) - def setExportMode(self, export, opts): - if export: - self.exportOpts = opts - if 'antialias' not in opts: - self.exportOpts['antialias'] = True - else: - self.exportOpts = False class ROIPlotItem(PlotCurveItem): """Plot curve that monitors an ROI and image for changes to automatically replot.""" diff --git a/graphicsItems/PlotDataItem.py b/pyqtgraph/graphicsItems/PlotDataItem.py similarity index 99% rename from graphicsItems/PlotDataItem.py rename to pyqtgraph/graphicsItems/PlotDataItem.py index f3db53ba..714210c4 100644 --- a/graphicsItems/PlotDataItem.py +++ b/pyqtgraph/graphicsItems/PlotDataItem.py @@ -523,7 +523,9 @@ class PlotDataItem(GraphicsObject): def dataType(obj): if hasattr(obj, '__len__') and len(obj) == 0: return 'empty' - if isSequence(obj): + if isinstance(obj, dict): + return 'dictOfLists' + elif isSequence(obj): first = obj[0] if (hasattr(obj, 'implements') and obj.implements('MetaArray')): @@ -542,12 +544,10 @@ def dataType(obj): return 'listOfDicts' else: return 'listOfValues' - elif isinstance(obj, dict): - return 'dictOfLists' def isSequence(obj): - return isinstance(obj, list) or isinstance(obj, np.ndarray) or (hasattr(obj, 'implements') and obj.implements('MetaArray')) + return hasattr(obj, '__iter__') or isinstance(obj, np.ndarray) or (hasattr(obj, 'implements') and obj.implements('MetaArray')) diff --git a/graphicsItems/PlotItem/PlotItem.py b/pyqtgraph/graphicsItems/PlotItem/PlotItem.py similarity index 99% rename from graphicsItems/PlotItem/PlotItem.py rename to pyqtgraph/graphicsItems/PlotItem/PlotItem.py index 42ae1830..6c2e1a6f 100644 --- a/graphicsItems/PlotItem/PlotItem.py +++ b/pyqtgraph/graphicsItems/PlotItem/PlotItem.py @@ -1107,7 +1107,7 @@ class PlotItem(GraphicsWidget): self.updateButtons() def updateButtons(self): - if self.mouseHovering and not self.buttonsHidden and not all(self.vb.autoRangeEnabled()): + if self._exportOpts is False and self.mouseHovering and not self.buttonsHidden and not all(self.vb.autoRangeEnabled()): self.autoBtn.show() else: self.autoBtn.hide() @@ -1151,9 +1151,11 @@ class PlotItem(GraphicsWidget): return c - def setExportMode(self, export, opts): - if export: - self.autoBtn.hide() - else: - self.autoBtn.show() + def setExportMode(self, export, opts=None): + GraphicsWidget.setExportMode(self, export, opts) + self.updateButtons() + #if export: + #self.autoBtn.hide() + #else: + #self.autoBtn.show() diff --git a/graphicsItems/PlotItem/__init__.py b/pyqtgraph/graphicsItems/PlotItem/__init__.py similarity index 100% rename from graphicsItems/PlotItem/__init__.py rename to pyqtgraph/graphicsItems/PlotItem/__init__.py diff --git a/graphicsItems/PlotItem/plotConfigTemplate.ui b/pyqtgraph/graphicsItems/PlotItem/plotConfigTemplate.ui similarity index 100% rename from graphicsItems/PlotItem/plotConfigTemplate.ui rename to pyqtgraph/graphicsItems/PlotItem/plotConfigTemplate.ui diff --git a/graphicsItems/PlotItem/plotConfigTemplate_pyqt.py b/pyqtgraph/graphicsItems/PlotItem/plotConfigTemplate_pyqt.py similarity index 100% rename from graphicsItems/PlotItem/plotConfigTemplate_pyqt.py rename to pyqtgraph/graphicsItems/PlotItem/plotConfigTemplate_pyqt.py diff --git a/graphicsItems/PlotItem/plotConfigTemplate_pyside.py b/pyqtgraph/graphicsItems/PlotItem/plotConfigTemplate_pyside.py similarity index 100% rename from graphicsItems/PlotItem/plotConfigTemplate_pyside.py rename to pyqtgraph/graphicsItems/PlotItem/plotConfigTemplate_pyside.py diff --git a/graphicsItems/ROI.py b/pyqtgraph/graphicsItems/ROI.py similarity index 100% rename from graphicsItems/ROI.py rename to pyqtgraph/graphicsItems/ROI.py diff --git a/graphicsItems/ScaleBar.py b/pyqtgraph/graphicsItems/ScaleBar.py similarity index 100% rename from graphicsItems/ScaleBar.py rename to pyqtgraph/graphicsItems/ScaleBar.py diff --git a/graphicsItems/ScatterPlotItem.py b/pyqtgraph/graphicsItems/ScatterPlotItem.py similarity index 97% rename from graphicsItems/ScatterPlotItem.py rename to pyqtgraph/graphicsItems/ScatterPlotItem.py index 2528d35b..2e41cb7c 100644 --- a/graphicsItems/ScatterPlotItem.py +++ b/pyqtgraph/graphicsItems/ScatterPlotItem.py @@ -239,7 +239,6 @@ class ScatterPlotItem(GraphicsObject): 'useCache': True, ## If useCache is False, symbols are re-drawn on every paint. 'antialias': pg.getConfigOption('antialias'), } - self.exportOpts = False self.setPen(200,200,200, update=False) self.setBrush(100,100,150, update=False) @@ -546,7 +545,7 @@ class ScatterPlotItem(GraphicsObject): if invalidate: self.invalidate() - def getSpotOpts(self, recs): + def getSpotOpts(self, recs, scale=1.0): if recs.ndim == 0: rec = recs symbol = rec['symbol'] @@ -561,11 +560,12 @@ class ScatterPlotItem(GraphicsObject): brush = rec['brush'] if brush is None: brush = self.opts['brush'] - return (symbol, size, fn.mkPen(pen), fn.mkBrush(brush)) + return (symbol, size*scale, fn.mkPen(pen), fn.mkBrush(brush)) else: recs = recs.copy() recs['symbol'][np.equal(recs['symbol'], None)] = self.opts['symbol'] recs['size'][np.equal(recs['size'], -1)] = self.opts['size'] + recs['size'] *= scale recs['pen'][np.equal(recs['pen'], None)] = fn.mkPen(self.opts['pen']) recs['brush'][np.equal(recs['brush'], None)] = fn.mkBrush(self.opts['brush']) return recs @@ -675,18 +675,20 @@ class ScatterPlotItem(GraphicsObject): rect = QtCore.QRectF(y, x, h, w) self.fragments.append(QtGui.QPainter.PixmapFragment.create(pos, rect)) - def setExportMode(self, export, opts): - if export: - self.exportOpts = opts - if 'antialias' not in opts: - self.exportOpts['antialias'] = True - else: - self.exportOpts = False - + def setExportMode(self, *args, **kwds): + GraphicsObject.setExportMode(self, *args, **kwds) + self.invalidate() def paint(self, p, *args): #p.setPen(fn.mkPen('r')) #p.drawRect(self.boundingRect()) + if self._exportOpts is not False: + aa = self._exportOpts.get('antialias', True) + scale = self._exportOpts.get('resolutionScale', 1.0) ## exporting to image; pixel resolution may have changed + else: + aa = self.opts['antialias'] + scale = 1.0 + if self.opts['pxMode'] is True: atlas = self.fragmentAtlas.getAtlas() #arr = fn.imageToArray(atlas.toImage(), copy=True) @@ -701,13 +703,9 @@ class ScatterPlotItem(GraphicsObject): p.resetTransform() - if not USE_PYSIDE and self.opts['useCache'] and self.exportOpts is False: + if not USE_PYSIDE and self.opts['useCache'] and self._exportOpts is False: p.drawPixmapFragments(self.fragments, atlas) else: - if self.exportOpts is not False: - aa = self.exportOpts['antialias'] - else: - aa = self.opts['antialias'] p.setRenderHint(p.Antialiasing, aa) for i in range(len(self.data)): @@ -715,23 +713,20 @@ class ScatterPlotItem(GraphicsObject): frag = self.fragments[i] p.resetTransform() p.translate(frag.x, frag.y) - drawSymbol(p, *self.getSpotOpts(rec)) + drawSymbol(p, *self.getSpotOpts(rec, scale)) else: if self.picture is None: self.picture = QtGui.QPicture() p2 = QtGui.QPainter(self.picture) for rec in self.data: - + if scale != 1.0: + rec = rec.copy() + rec['size'] *= scale p2.resetTransform() p2.translate(rec['x'], rec['y']) - drawSymbol(p2, *self.getSpotOpts(rec)) + drawSymbol(p2, *self.getSpotOpts(rec, scale)) p2.end() - if self.exportOpts is not False: - aa = self.exportOpts['antialias'] - else: - aa = self.opts['antialias'] - p.setRenderHint(p.Antialiasing, aa) self.picture.play(p) diff --git a/graphicsItems/TextItem.py b/pyqtgraph/graphicsItems/TextItem.py similarity index 66% rename from graphicsItems/TextItem.py rename to pyqtgraph/graphicsItems/TextItem.py index a85e919d..b5666f6e 100644 --- a/graphicsItems/TextItem.py +++ b/pyqtgraph/graphicsItems/TextItem.py @@ -27,25 +27,27 @@ class TextItem(UIGraphicsItem): #*angle* Angle in degrees to rotate text (note that the rotation assigned in this item's #transformation will be ignored) - + self.anchor = pg.Point(anchor) + #self.angle = 0 UIGraphicsItem.__init__(self) self.textItem = QtGui.QGraphicsTextItem() + self.textItem.setParentItem(self) self.lastTransform = None self._bounds = QtCore.QRectF() if html is None: self.setText(text, color) else: self.setHtml(html) - self.anchor = pg.Point(anchor) self.fill = pg.mkBrush(fill) self.border = pg.mkPen(border) - self.angle = angle - #self.setFlag(self.ItemIgnoresTransformations) ## This is required to keep the text unscaled inside the viewport + self.rotate(angle) + self.setFlag(self.ItemIgnoresTransformations) ## This is required to keep the text unscaled inside the viewport def setText(self, text, color=(200,200,200)): color = pg.mkColor(color) self.textItem.setDefaultTextColor(color) self.textItem.setPlainText(text) + self.updateText() #html = '%s' % (color, text) #self.setHtml(html) @@ -70,38 +72,41 @@ class TextItem(UIGraphicsItem): self.textItem.setFont(*args) self.updateText() - def updateText(self): - self.viewRangeChanged() - - #def getImage(self): - #if self.img is None: - #br = self.textItem.boundingRect() - #img = QtGui.QImage(int(br.width()), int(br.height()), QtGui.QImage.Format_ARGB32) - #p = QtGui.QPainter(img) - #self.textItem.paint(p, QtGui.QStyleOptionGraphicsItem(), None) - #p.end() - #self.img = img - #return self.img + #def setAngle(self, angle): + #self.angle = angle + #self.updateText() - def textBoundingRect(self): - ## return the bounds of the text box in device coordinates - pos = self.mapToDevice(QtCore.QPointF(0,0)) - if pos is None: - return None - tbr = self.textItem.boundingRect() - return QtCore.QRectF(pos.x() - tbr.width()*self.anchor.x(), pos.y() - tbr.height()*self.anchor.y(), tbr.width(), tbr.height()) + + def updateText(self): + + ## Needed to maintain font size when rendering to image with increased resolution + self.textItem.resetTransform() + #self.textItem.rotate(self.angle) + if self._exportOpts is not False and 'resolutionScale' in self._exportOpts: + s = self._exportOpts['resolutionScale'] + self.textItem.scale(s, s) + + #br = self.textItem.mapRectToParent(self.textItem.boundingRect()) + self.textItem.setPos(0,0) + br = self.textItem.boundingRect() + apos = self.textItem.mapToParent(pg.Point(br.width()*self.anchor.x(), br.height()*self.anchor.y())) + #print br, apos + self.textItem.setPos(-apos.x(), -apos.y()) + + #def textBoundingRect(self): + ### return the bounds of the text box in device coordinates + #pos = self.mapToDevice(QtCore.QPointF(0,0)) + #if pos is None: + #return None + #tbr = self.textItem.boundingRect() + #return QtCore.QRectF(pos.x() - tbr.width()*self.anchor.x(), pos.y() - tbr.height()*self.anchor.y(), tbr.width(), tbr.height()) def viewRangeChanged(self): - br = self.textBoundingRect() - if br is None: - return - self.prepareGeometryChange() - self._bounds = fn.invertQTransform(self.deviceTransform()).mapRect(br) - #print self._bounds + self.updateText() def boundingRect(self): - return self._bounds + return self.textItem.mapToParent(self.textItem.boundingRect()).boundingRect() def paint(self, p, *args): tr = p.transform() @@ -110,23 +115,9 @@ class TextItem(UIGraphicsItem): self.viewRangeChanged() self.lastTransform = tr - - tbr = self.textBoundingRect() - - #p.setPen(pg.mkPen('r')) - #p.drawRect(self.boundingRect()) - p.setPen(self.border) p.setBrush(self.fill) + p.setRenderHint(p.Antialiasing, True) + p.drawPolygon(self.textItem.mapToParent(self.textItem.boundingRect())) - - #p.fillRect(tbr) - p.resetTransform() - #p.drawRect(tbr) - - - p.translate(tbr.left(), tbr.top()) - p.rotate(self.angle) - p.drawRect(QtCore.QRectF(0, 0, tbr.width(), tbr.height())) - self.textItem.paint(p, QtGui.QStyleOptionGraphicsItem(), None) \ No newline at end of file diff --git a/graphicsItems/UIGraphicsItem.py b/pyqtgraph/graphicsItems/UIGraphicsItem.py similarity index 100% rename from graphicsItems/UIGraphicsItem.py rename to pyqtgraph/graphicsItems/UIGraphicsItem.py diff --git a/graphicsItems/VTickGroup.py b/pyqtgraph/graphicsItems/VTickGroup.py similarity index 100% rename from graphicsItems/VTickGroup.py rename to pyqtgraph/graphicsItems/VTickGroup.py diff --git a/graphicsItems/ViewBox/ViewBox.py b/pyqtgraph/graphicsItems/ViewBox/ViewBox.py similarity index 100% rename from graphicsItems/ViewBox/ViewBox.py rename to pyqtgraph/graphicsItems/ViewBox/ViewBox.py diff --git a/graphicsItems/ViewBox/ViewBoxMenu.py b/pyqtgraph/graphicsItems/ViewBox/ViewBoxMenu.py similarity index 100% rename from graphicsItems/ViewBox/ViewBoxMenu.py rename to pyqtgraph/graphicsItems/ViewBox/ViewBoxMenu.py diff --git a/graphicsItems/ViewBox/__init__.py b/pyqtgraph/graphicsItems/ViewBox/__init__.py similarity index 100% rename from graphicsItems/ViewBox/__init__.py rename to pyqtgraph/graphicsItems/ViewBox/__init__.py diff --git a/graphicsItems/ViewBox/axisCtrlTemplate.ui b/pyqtgraph/graphicsItems/ViewBox/axisCtrlTemplate.ui similarity index 100% rename from graphicsItems/ViewBox/axisCtrlTemplate.ui rename to pyqtgraph/graphicsItems/ViewBox/axisCtrlTemplate.ui diff --git a/graphicsItems/ViewBox/axisCtrlTemplate_pyqt.py b/pyqtgraph/graphicsItems/ViewBox/axisCtrlTemplate_pyqt.py similarity index 100% rename from graphicsItems/ViewBox/axisCtrlTemplate_pyqt.py rename to pyqtgraph/graphicsItems/ViewBox/axisCtrlTemplate_pyqt.py diff --git a/graphicsItems/ViewBox/axisCtrlTemplate_pyside.py b/pyqtgraph/graphicsItems/ViewBox/axisCtrlTemplate_pyside.py similarity index 100% rename from graphicsItems/ViewBox/axisCtrlTemplate_pyside.py rename to pyqtgraph/graphicsItems/ViewBox/axisCtrlTemplate_pyside.py diff --git a/graphicsItems/__init__.py b/pyqtgraph/graphicsItems/__init__.py similarity index 100% rename from graphicsItems/__init__.py rename to pyqtgraph/graphicsItems/__init__.py diff --git a/graphicsWindows.py b/pyqtgraph/graphicsWindows.py similarity index 100% rename from graphicsWindows.py rename to pyqtgraph/graphicsWindows.py diff --git a/imageview/ImageView.py b/pyqtgraph/imageview/ImageView.py similarity index 100% rename from imageview/ImageView.py rename to pyqtgraph/imageview/ImageView.py diff --git a/imageview/ImageViewTemplate.ui b/pyqtgraph/imageview/ImageViewTemplate.ui similarity index 100% rename from imageview/ImageViewTemplate.ui rename to pyqtgraph/imageview/ImageViewTemplate.ui diff --git a/imageview/ImageViewTemplate_pyqt.py b/pyqtgraph/imageview/ImageViewTemplate_pyqt.py similarity index 100% rename from imageview/ImageViewTemplate_pyqt.py rename to pyqtgraph/imageview/ImageViewTemplate_pyqt.py diff --git a/imageview/ImageViewTemplate_pyside.py b/pyqtgraph/imageview/ImageViewTemplate_pyside.py similarity index 100% rename from imageview/ImageViewTemplate_pyside.py rename to pyqtgraph/imageview/ImageViewTemplate_pyside.py diff --git a/imageview/__init__.py b/pyqtgraph/imageview/__init__.py similarity index 100% rename from imageview/__init__.py rename to pyqtgraph/imageview/__init__.py diff --git a/metaarray/MetaArray.py b/pyqtgraph/metaarray/MetaArray.py similarity index 100% rename from metaarray/MetaArray.py rename to pyqtgraph/metaarray/MetaArray.py diff --git a/metaarray/__init__.py b/pyqtgraph/metaarray/__init__.py similarity index 100% rename from metaarray/__init__.py rename to pyqtgraph/metaarray/__init__.py diff --git a/metaarray/license.txt b/pyqtgraph/metaarray/license.txt similarity index 100% rename from metaarray/license.txt rename to pyqtgraph/metaarray/license.txt diff --git a/metaarray/readMeta.m b/pyqtgraph/metaarray/readMeta.m similarity index 100% rename from metaarray/readMeta.m rename to pyqtgraph/metaarray/readMeta.m diff --git a/multiprocess/__init__.py b/pyqtgraph/multiprocess/__init__.py similarity index 100% rename from multiprocess/__init__.py rename to pyqtgraph/multiprocess/__init__.py diff --git a/multiprocess/bootstrap.py b/pyqtgraph/multiprocess/bootstrap.py similarity index 100% rename from multiprocess/bootstrap.py rename to pyqtgraph/multiprocess/bootstrap.py diff --git a/multiprocess/parallelizer.py b/pyqtgraph/multiprocess/parallelizer.py similarity index 100% rename from multiprocess/parallelizer.py rename to pyqtgraph/multiprocess/parallelizer.py diff --git a/multiprocess/processes.py b/pyqtgraph/multiprocess/processes.py similarity index 100% rename from multiprocess/processes.py rename to pyqtgraph/multiprocess/processes.py diff --git a/multiprocess/remoteproxy.py b/pyqtgraph/multiprocess/remoteproxy.py similarity index 100% rename from multiprocess/remoteproxy.py rename to pyqtgraph/multiprocess/remoteproxy.py diff --git a/numpy_fix.py b/pyqtgraph/numpy_fix.py similarity index 100% rename from numpy_fix.py rename to pyqtgraph/numpy_fix.py diff --git a/opengl/GLGraphicsItem.py b/pyqtgraph/opengl/GLGraphicsItem.py similarity index 100% rename from opengl/GLGraphicsItem.py rename to pyqtgraph/opengl/GLGraphicsItem.py diff --git a/opengl/GLViewWidget.py b/pyqtgraph/opengl/GLViewWidget.py similarity index 100% rename from opengl/GLViewWidget.py rename to pyqtgraph/opengl/GLViewWidget.py diff --git a/opengl/MeshData.py b/pyqtgraph/opengl/MeshData.py similarity index 100% rename from opengl/MeshData.py rename to pyqtgraph/opengl/MeshData.py diff --git a/opengl/__init__.py b/pyqtgraph/opengl/__init__.py similarity index 100% rename from opengl/__init__.py rename to pyqtgraph/opengl/__init__.py diff --git a/opengl/glInfo.py b/pyqtgraph/opengl/glInfo.py similarity index 100% rename from opengl/glInfo.py rename to pyqtgraph/opengl/glInfo.py diff --git a/opengl/items/GLAxisItem.py b/pyqtgraph/opengl/items/GLAxisItem.py similarity index 100% rename from opengl/items/GLAxisItem.py rename to pyqtgraph/opengl/items/GLAxisItem.py diff --git a/opengl/items/GLBoxItem.py b/pyqtgraph/opengl/items/GLBoxItem.py similarity index 100% rename from opengl/items/GLBoxItem.py rename to pyqtgraph/opengl/items/GLBoxItem.py diff --git a/opengl/items/GLGridItem.py b/pyqtgraph/opengl/items/GLGridItem.py similarity index 100% rename from opengl/items/GLGridItem.py rename to pyqtgraph/opengl/items/GLGridItem.py diff --git a/opengl/items/GLImageItem.py b/pyqtgraph/opengl/items/GLImageItem.py similarity index 100% rename from opengl/items/GLImageItem.py rename to pyqtgraph/opengl/items/GLImageItem.py diff --git a/opengl/items/GLMeshItem.py b/pyqtgraph/opengl/items/GLMeshItem.py similarity index 100% rename from opengl/items/GLMeshItem.py rename to pyqtgraph/opengl/items/GLMeshItem.py diff --git a/opengl/items/GLScatterPlotItem.py b/pyqtgraph/opengl/items/GLScatterPlotItem.py similarity index 100% rename from opengl/items/GLScatterPlotItem.py rename to pyqtgraph/opengl/items/GLScatterPlotItem.py diff --git a/opengl/items/GLSurfacePlotItem.py b/pyqtgraph/opengl/items/GLSurfacePlotItem.py similarity index 100% rename from opengl/items/GLSurfacePlotItem.py rename to pyqtgraph/opengl/items/GLSurfacePlotItem.py diff --git a/opengl/items/GLVolumeItem.py b/pyqtgraph/opengl/items/GLVolumeItem.py similarity index 100% rename from opengl/items/GLVolumeItem.py rename to pyqtgraph/opengl/items/GLVolumeItem.py diff --git a/opengl/items/__init__.py b/pyqtgraph/opengl/items/__init__.py similarity index 100% rename from opengl/items/__init__.py rename to pyqtgraph/opengl/items/__init__.py diff --git a/opengl/shaders.py b/pyqtgraph/opengl/shaders.py similarity index 100% rename from opengl/shaders.py rename to pyqtgraph/opengl/shaders.py diff --git a/parametertree/Parameter.py b/pyqtgraph/parametertree/Parameter.py similarity index 100% rename from parametertree/Parameter.py rename to pyqtgraph/parametertree/Parameter.py diff --git a/parametertree/ParameterItem.py b/pyqtgraph/parametertree/ParameterItem.py similarity index 100% rename from parametertree/ParameterItem.py rename to pyqtgraph/parametertree/ParameterItem.py diff --git a/parametertree/ParameterTree.py b/pyqtgraph/parametertree/ParameterTree.py similarity index 100% rename from parametertree/ParameterTree.py rename to pyqtgraph/parametertree/ParameterTree.py diff --git a/parametertree/__init__.py b/pyqtgraph/parametertree/__init__.py similarity index 100% rename from parametertree/__init__.py rename to pyqtgraph/parametertree/__init__.py diff --git a/parametertree/parameterTypes.py b/pyqtgraph/parametertree/parameterTypes.py similarity index 100% rename from parametertree/parameterTypes.py rename to pyqtgraph/parametertree/parameterTypes.py diff --git a/pgcollections.py b/pyqtgraph/pgcollections.py similarity index 100% rename from pgcollections.py rename to pyqtgraph/pgcollections.py diff --git a/pixmaps/__init__.py b/pyqtgraph/pixmaps/__init__.py similarity index 100% rename from pixmaps/__init__.py rename to pyqtgraph/pixmaps/__init__.py diff --git a/pixmaps/auto.png b/pyqtgraph/pixmaps/auto.png similarity index 100% rename from pixmaps/auto.png rename to pyqtgraph/pixmaps/auto.png diff --git a/pixmaps/compile.py b/pyqtgraph/pixmaps/compile.py similarity index 100% rename from pixmaps/compile.py rename to pyqtgraph/pixmaps/compile.py diff --git a/pixmaps/ctrl.png b/pyqtgraph/pixmaps/ctrl.png similarity index 100% rename from pixmaps/ctrl.png rename to pyqtgraph/pixmaps/ctrl.png diff --git a/pixmaps/default.png b/pyqtgraph/pixmaps/default.png similarity index 100% rename from pixmaps/default.png rename to pyqtgraph/pixmaps/default.png diff --git a/pixmaps/icons.svg b/pyqtgraph/pixmaps/icons.svg similarity index 100% rename from pixmaps/icons.svg rename to pyqtgraph/pixmaps/icons.svg diff --git a/pixmaps/lock.png b/pyqtgraph/pixmaps/lock.png similarity index 100% rename from pixmaps/lock.png rename to pyqtgraph/pixmaps/lock.png diff --git a/pixmaps/pixmapData_2.py b/pyqtgraph/pixmaps/pixmapData_2.py similarity index 100% rename from pixmaps/pixmapData_2.py rename to pyqtgraph/pixmaps/pixmapData_2.py diff --git a/pixmaps/pixmapData_3.py b/pyqtgraph/pixmaps/pixmapData_3.py similarity index 100% rename from pixmaps/pixmapData_3.py rename to pyqtgraph/pixmaps/pixmapData_3.py diff --git a/ptime.py b/pyqtgraph/ptime.py similarity index 100% rename from ptime.py rename to pyqtgraph/ptime.py diff --git a/python2_3.py b/pyqtgraph/python2_3.py similarity index 100% rename from python2_3.py rename to pyqtgraph/python2_3.py diff --git a/rebuildUi.py b/pyqtgraph/rebuildUi.py similarity index 100% rename from rebuildUi.py rename to pyqtgraph/rebuildUi.py diff --git a/reload.py b/pyqtgraph/reload.py similarity index 100% rename from reload.py rename to pyqtgraph/reload.py diff --git a/units.py b/pyqtgraph/units.py similarity index 100% rename from units.py rename to pyqtgraph/units.py diff --git a/widgets/BusyCursor.py b/pyqtgraph/widgets/BusyCursor.py similarity index 100% rename from widgets/BusyCursor.py rename to pyqtgraph/widgets/BusyCursor.py diff --git a/widgets/CheckTable.py b/pyqtgraph/widgets/CheckTable.py similarity index 100% rename from widgets/CheckTable.py rename to pyqtgraph/widgets/CheckTable.py diff --git a/widgets/ColorButton.py b/pyqtgraph/widgets/ColorButton.py similarity index 100% rename from widgets/ColorButton.py rename to pyqtgraph/widgets/ColorButton.py diff --git a/widgets/ComboBox.py b/pyqtgraph/widgets/ComboBox.py similarity index 100% rename from widgets/ComboBox.py rename to pyqtgraph/widgets/ComboBox.py diff --git a/widgets/DataTreeWidget.py b/pyqtgraph/widgets/DataTreeWidget.py similarity index 100% rename from widgets/DataTreeWidget.py rename to pyqtgraph/widgets/DataTreeWidget.py diff --git a/widgets/FeedbackButton.py b/pyqtgraph/widgets/FeedbackButton.py similarity index 100% rename from widgets/FeedbackButton.py rename to pyqtgraph/widgets/FeedbackButton.py diff --git a/widgets/FileDialog.py b/pyqtgraph/widgets/FileDialog.py similarity index 100% rename from widgets/FileDialog.py rename to pyqtgraph/widgets/FileDialog.py diff --git a/widgets/GradientWidget.py b/pyqtgraph/widgets/GradientWidget.py similarity index 100% rename from widgets/GradientWidget.py rename to pyqtgraph/widgets/GradientWidget.py diff --git a/widgets/GraphicsLayoutWidget.py b/pyqtgraph/widgets/GraphicsLayoutWidget.py similarity index 100% rename from widgets/GraphicsLayoutWidget.py rename to pyqtgraph/widgets/GraphicsLayoutWidget.py diff --git a/widgets/GraphicsView.py b/pyqtgraph/widgets/GraphicsView.py similarity index 100% rename from widgets/GraphicsView.py rename to pyqtgraph/widgets/GraphicsView.py diff --git a/widgets/HistogramLUTWidget.py b/pyqtgraph/widgets/HistogramLUTWidget.py similarity index 100% rename from widgets/HistogramLUTWidget.py rename to pyqtgraph/widgets/HistogramLUTWidget.py diff --git a/widgets/JoystickButton.py b/pyqtgraph/widgets/JoystickButton.py similarity index 100% rename from widgets/JoystickButton.py rename to pyqtgraph/widgets/JoystickButton.py diff --git a/widgets/LayoutWidget.py b/pyqtgraph/widgets/LayoutWidget.py similarity index 100% rename from widgets/LayoutWidget.py rename to pyqtgraph/widgets/LayoutWidget.py diff --git a/widgets/MatplotlibWidget.py b/pyqtgraph/widgets/MatplotlibWidget.py similarity index 100% rename from widgets/MatplotlibWidget.py rename to pyqtgraph/widgets/MatplotlibWidget.py diff --git a/widgets/MultiPlotWidget.py b/pyqtgraph/widgets/MultiPlotWidget.py similarity index 100% rename from widgets/MultiPlotWidget.py rename to pyqtgraph/widgets/MultiPlotWidget.py diff --git a/widgets/PathButton.py b/pyqtgraph/widgets/PathButton.py similarity index 100% rename from widgets/PathButton.py rename to pyqtgraph/widgets/PathButton.py diff --git a/widgets/PlotWidget.py b/pyqtgraph/widgets/PlotWidget.py similarity index 100% rename from widgets/PlotWidget.py rename to pyqtgraph/widgets/PlotWidget.py diff --git a/widgets/ProgressDialog.py b/pyqtgraph/widgets/ProgressDialog.py similarity index 100% rename from widgets/ProgressDialog.py rename to pyqtgraph/widgets/ProgressDialog.py diff --git a/widgets/RawImageWidget.py b/pyqtgraph/widgets/RawImageWidget.py similarity index 100% rename from widgets/RawImageWidget.py rename to pyqtgraph/widgets/RawImageWidget.py diff --git a/widgets/RemoteGraphicsView.py b/pyqtgraph/widgets/RemoteGraphicsView.py similarity index 100% rename from widgets/RemoteGraphicsView.py rename to pyqtgraph/widgets/RemoteGraphicsView.py diff --git a/widgets/SpinBox.py b/pyqtgraph/widgets/SpinBox.py similarity index 100% rename from widgets/SpinBox.py rename to pyqtgraph/widgets/SpinBox.py diff --git a/widgets/TableWidget.py b/pyqtgraph/widgets/TableWidget.py similarity index 100% rename from widgets/TableWidget.py rename to pyqtgraph/widgets/TableWidget.py diff --git a/widgets/TreeWidget.py b/pyqtgraph/widgets/TreeWidget.py similarity index 100% rename from widgets/TreeWidget.py rename to pyqtgraph/widgets/TreeWidget.py diff --git a/widgets/ValueLabel.py b/pyqtgraph/widgets/ValueLabel.py similarity index 100% rename from widgets/ValueLabel.py rename to pyqtgraph/widgets/ValueLabel.py diff --git a/widgets/VerticalLabel.py b/pyqtgraph/widgets/VerticalLabel.py similarity index 100% rename from widgets/VerticalLabel.py rename to pyqtgraph/widgets/VerticalLabel.py diff --git a/widgets/__init__.py b/pyqtgraph/widgets/__init__.py similarity index 100% rename from widgets/__init__.py rename to pyqtgraph/widgets/__init__.py diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/svg.py b/tests/svg.py new file mode 100644 index 00000000..dc9657bb --- /dev/null +++ b/tests/svg.py @@ -0,0 +1,29 @@ +""" +SVG export test +""" +import test +import pyqtgraph as pg +app = pg.mkQApp() + +class SVGTest(test.TestCase): + def test_plotscene(self): + p = pg.plot([1,5,2,3,4,6,1,2,4,2,3,5,3]) + p.setXRange(0,5) + ex = pg.exporters.SVGExporter.SVGExporter(p.scene()) + ex.export(fileName='test.svg') + + #def test_simple(self): + #rect = pg.QtGui.QGraphicsRectItem(0, 0, 100, 100) + ##rect.rotate(30) + #grp = pg.ItemGroup() + #grp.setParentItem(rect) + #grp.translate(200,0) + #grp.rotate(30) + #el = pg.QtGui.QGraphicsEllipseItem(10, 0, 100, 50) + #el.setParentItem(grp) + #ex = pg.exporters.SVGExporter.SVGExporter(rect) + #ex.export(fileName='test.svg') + + +if __name__ == '__main__': + test.unittest.main() \ No newline at end of file diff --git a/tests/test.py b/tests/test.py new file mode 100644 index 00000000..f24a7d42 --- /dev/null +++ b/tests/test.py @@ -0,0 +1,8 @@ +import unittest +import os, sys +## make sure this instance of pyqtgraph gets imported first +sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))) + +## all tests should be defined with this class so we have the option to tweak it later. +class TestCase(unittest.TestCase): + pass \ No newline at end of file From b0e07816246bc33a1a4c6e5799081b1334da1f38 Mon Sep 17 00:00:00 2001 From: Luke Campagnola Date: Tue, 25 Dec 2012 22:20:31 -0500 Subject: [PATCH 2/6] svg exporter updates --- pyqtgraph/__init__.py | 2 +- pyqtgraph/exporters/SVGExporter.py | 283 +++++++++++++++++------- pyqtgraph/widgets/RemoteGraphicsView.py | 2 +- tests/svg.py | 33 ++- 4 files changed, 225 insertions(+), 95 deletions(-) diff --git a/pyqtgraph/__init__.py b/pyqtgraph/__init__.py index 09dc7c58..6e950770 100644 --- a/pyqtgraph/__init__.py +++ b/pyqtgraph/__init__.py @@ -50,7 +50,7 @@ CONFIG_OPTIONS = { def setConfigOption(opt, value): CONFIG_OPTIONS[opt] = value -def setConfigOptions(opts): +def setConfigOptions(**opts): CONFIG_OPTIONS.update(opts) def getConfigOption(opt): diff --git a/pyqtgraph/exporters/SVGExporter.py b/pyqtgraph/exporters/SVGExporter.py index bac03dae..4052deec 100644 --- a/pyqtgraph/exporters/SVGExporter.py +++ b/pyqtgraph/exporters/SVGExporter.py @@ -1,6 +1,7 @@ from .Exporter import Exporter from pyqtgraph.parametertree import Parameter from pyqtgraph.Qt import QtGui, QtCore, QtSvg +import pyqtgraph as pg import re import xml.dom.minidom as xml @@ -72,107 +73,217 @@ class SVGExporter(Exporter): ##print "old line:", line ##print "new line:", data[i] #open(fileName, 'w').write(''.join(data)) - - node = self.generateItemSvg(self.item) - xml = """\ - - -pyqtgraph SVG export -Generated with Qt and pyqtgraph - - -""" + node.toprettyxml(indent=' ') + "\n\n" - + + ## Qt's SVG generator is not complete. (notably, it lacks clipping) + ## Instead, we will use Qt to generate SVG for each item independently, + ## then manually reconstruct the entire document. + xml = generateSvg(self.item) + if toBytes: return bytes(xml) else: with open(fileName, 'w') as fh: fh.write(xml) - def generateItemSvg(self, item): +xmlHeader = """\ + + +pyqtgraph SVG export +Generated with Qt and pyqtgraph + + +""" + +def generateSvg(item): + global xmlHeader + try: + node = _generateItemSvg(item) + finally: + ## reset export mode for all items in the tree if isinstance(item, QtGui.QGraphicsScene): - xmlStr = "" - childs = [i for i in item.items() if i.parentItem() is None] + items = item.items() else: - tr = QtGui.QTransform() - tr.translate(item.pos().x(), item.pos().y()) - tr = tr * item.transform() - if not item.isVisible() or int(item.flags() & item.ItemHasNoContents) > 0: - m = (tr.m11(), tr.m12(), tr.m21(), tr.m22(), tr.m31(), tr.m32()) - #print item, m - xmlStr = '' % m - else: - arr = QtCore.QByteArray() - buf = QtCore.QBuffer(arr) - svg = QtSvg.QSvgGenerator() - svg.setOutputDevice(buf) - dpi = QtGui.QDesktopWidget().physicalDpiX() - ### not really sure why this works, but it seems to be important: - #self.svg.setSize(QtCore.QSize(self.params['width']*dpi/90., self.params['height']*dpi/90.)) - svg.setResolution(dpi) + items = [item] + for i in items: + items.extend(i.childItems()) + for i in items: + if hasattr(i, 'setExportMode'): + i.setExportMode(False) + + cleanXml(node) + + return xmlHeader + node.toprettyxml(indent=' ') + "\n\n" - p = QtGui.QPainter() - p.begin(svg) - if hasattr(item, 'setExportMode'): - item.setExportMode(True, {'painter': p}) - try: - #tr = QtGui.QTransform() - #tr.translate(item.pos().x(), item.pos().y()) - #p.setTransform(tr * item.transform()) - p.setTransform(tr) - item.paint(p, QtGui.QStyleOptionGraphicsItem(), None) - finally: - p.end() - if hasattr(item, 'setExportMode'): - item.setExportMode(False) - - xmlStr = str(arr) - childs = item.childItems() +def _generateItemSvg(item, nodes=None, root=None): + ## This function is intended to work around some issues with Qt's SVG generator + ## and SVG in general. + ## 1) Qt SVG does not implement clipping paths. This is absurd. + ## The solution is to let Qt generate SVG for each item independently, + ## then glue them together manually with clipping. + ## 2) There seems to be wide disagreement over whether path strokes + ## should be scaled anisotropically. + ## see: http://web.mit.edu/jonas/www/anisotropy/ + ## Given that both inkscape and illustrator seem to prefer isotropic + ## scaling, we will optimize for those cases. + ## 3) Qt generates paths using non-scaling-stroke from SVG 1.2, but + ## inkscape only supports 1.1. + + + + if nodes is None: ## nodes maps all node IDs to their XML element. + ## this allows us to ensure all elements receive unique names. + nodes = {} + + if root is None: + root = item + + ## Skip hidden items + if hasattr(item, 'isVisible') and not item.isVisible(): + return None + + ## If this item defines its own SVG generator, use that. + if hasattr(item, 'generateSvg'): + return item.generateSvg(nodes) + + + ## Generate SVG text for just this item (exclude its children; we'll handle them later) + tr = QtGui.QTransform() + if isinstance(item, QtGui.QGraphicsScene): + xmlStr = "\n\n" + childs = [i for i in item.items() if i.parentItem() is None] doc = xml.parseString(xmlStr) + else: + childs = item.childItems() + tr.translate(item.pos().x(), item.pos().y()) + tr = tr * item.transform() + #if not item.isVisible() or int(item.flags() & item.ItemHasNoContents) > 0: + #m = (tr.m11(), tr.m12(), tr.m21(), tr.m22(), tr.m31(), tr.m32()) + ##print item, m + #xmlStr = '' % m # note: outer group is needed to separate clipping from transform + #doc = xml.parseString(xmlStr) + #else: + arr = QtCore.QByteArray() + buf = QtCore.QBuffer(arr) + svg = QtSvg.QSvgGenerator() + svg.setOutputDevice(buf) + dpi = QtGui.QDesktopWidget().physicalDpiX() + ### not really sure why this works, but it seems to be important: + #self.svg.setSize(QtCore.QSize(self.params['width']*dpi/90., self.params['height']*dpi/90.)) + svg.setResolution(dpi) + + p = QtGui.QPainter() + p.begin(svg) + if hasattr(item, 'setExportMode'): + item.setExportMode(True, {'painter': p}) try: - groups = doc.getElementsByTagName('g') - if len(groups) == 1: - g1 = g2 = groups[0] - else: - g1,g2 = groups[:2] - except: - print doc.toxml() - raise - g1.setAttribute('id', item.__class__.__name__) - - ## Check for item visibility - visible = True - if not isinstance(item, QtGui.QGraphicsScene): - parent = item - while visible and parent is not None: - visible = parent.isVisible() - parent = parent.parentItem() + #p.setTransform(tr) + item.paint(p, QtGui.QStyleOptionGraphicsItem(), None) + finally: + p.end() + ## Can't do this here--we need to wait until all children have painted as well. + ## this is taken care of in generateSvg instead. + #if hasattr(item, 'setExportMode'): + #item.setExportMode(False) - if not visible: - style = g1.getAttribute('style').strip() - if len(style)>0 and not style.endswith(';'): - style += ';' - style += 'display:none;' - g1.setAttribute('style', style) - - childs.sort(key=lambda c: c.zValue()) - for ch in childs: - cg = self.generateItemSvg(ch) - g2.appendChild(cg) + xmlStr = str(arr) + doc = xml.parseString(xmlStr) - return g1 - - - - ### To check: - ### do all items really generate this double-group structure? - ### are both groups necessary? - ### How do we implement clipping? (can we clip to an object that is visible?) - - - + try: + ## Get top-level group for this item + g1 = doc.getElementsByTagName('g')[0] + ## get list of sub-groups + g2 = [n for n in g1.childNodes if isinstance(n, xml.Element) and n.tagName == 'g'] + except: + print doc.toxml() + raise + + ## make sure g1 has the transformation matrix + m = (tr.m11(), tr.m12(), tr.m21(), tr.m22(), tr.m31(), tr.m32()) + g1.setAttribute('transform', "matrix(%f,%f,%f,%f,%f,%f)" % m) + + #print "=================",item,"=====================" + #print g1.toprettyxml(indent=" ", newl='') + + ## Inkscape does not support non-scaling-stroke (this is SVG 1.2, inkscape supports 1.1) + ## So we need to correct anything attempting to use this. + correctStroke(g1, item, root) + + ## decide on a name for this item + baseName = item.__class__.__name__ + i = 1 + while True: + name = baseName + "_%d" % i + if name not in nodes: + break + i += 1 + nodes[name] = g1 + g1.setAttribute('id', name) + + ## If this item clips its children, we need to take car of that. + childGroup = g1 ## add children directly to this node unless we are clipping + if not isinstance(item, QtGui.QGraphicsScene): + ## See if this item clips its children + if int(item.flags() & item.ItemClipsChildrenToShape) > 0: + ## Generate svg for just the path + path = QtGui.QGraphicsPathItem(item.shape()) + pathNode = _generateItemSvg(path, root=root).getElementsByTagName('path')[0] + ## and for the clipPath element + clip = name + '_clip' + clipNode = g1.ownerDocument.createElement('clipPath') + clipNode.setAttribute('id', clip) + clipNode.appendChild(pathNode) + g1.appendChild(clipNode) + + childGroup = g1.ownerDocument.createElement('g') + childGroup.setAttribute('clip-path', 'url(#%s)' % clip) + g1.appendChild(childGroup) + ## Add all child items as sub-elements. + childs.sort(key=lambda c: c.zValue()) + for ch in childs: + cg = _generateItemSvg(ch, nodes, root) + if cg is None: + continue + childGroup.appendChild(cg) ### this isn't quite right--some items draw below their parent (good enough for now) + + return g1 +def correctStroke(node, item, root, width=1): + #print "==============", item, node + if node.hasAttribute('stroke-width'): + width = float(node.getAttribute('stroke-width')) + if node.getAttribute('vector-effect') == 'non-scaling-stroke': + node.removeAttribute('vector-effect') + if isinstance(root, QtGui.QGraphicsScene): + w = item.mapFromScene(pg.Point(width,0)) + o = item.mapFromScene(pg.Point(0,0)) + else: + w = item.mapFromItem(root, pg.Point(width,0)) + o = item.mapFromItem(root, pg.Point(0,0)) + w = w-o + #print " ", w, o, w-o + w = (w.x()**2 + w.y()**2) ** 0.5 + #print " ", w + node.setAttribute('stroke-width', str(w)) + + for ch in node.childNodes: + if isinstance(ch, xml.Element): + correctStroke(ch, item, root, width) + +def cleanXml(node): + ## remove extraneous text; let the xml library do the formatting. + hasElement = False + nonElement = [] + for ch in node.childNodes: + if isinstance(ch, xml.Element): + hasElement = True + cleanXml(ch) + else: + nonElement.append(ch) + + if hasElement: + for ch in nonElement: + node.removeChild(ch) diff --git a/pyqtgraph/widgets/RemoteGraphicsView.py b/pyqtgraph/widgets/RemoteGraphicsView.py index 5a389616..3752a6bb 100644 --- a/pyqtgraph/widgets/RemoteGraphicsView.py +++ b/pyqtgraph/widgets/RemoteGraphicsView.py @@ -21,7 +21,7 @@ class RemoteGraphicsView(QtGui.QWidget): QtGui.QWidget.__init__(self) self._proc = mp.QtProcess() self.pg = self._proc._import('pyqtgraph') - self.pg.setConfigOptions(self.pg.CONFIG_OPTIONS) + self.pg.setConfigOptions(**self.pg.CONFIG_OPTIONS) rpgRemote = self._proc._import('pyqtgraph.widgets.RemoteGraphicsView') self._view = rpgRemote.Renderer(*args, **kwds) self._view._setProxyOptions(deferGetattr=True) diff --git a/tests/svg.py b/tests/svg.py index dc9657bb..db54eb83 100644 --- a/tests/svg.py +++ b/tests/svg.py @@ -7,20 +7,39 @@ app = pg.mkQApp() class SVGTest(test.TestCase): def test_plotscene(self): - p = pg.plot([1,5,2,3,4,6,1,2,4,2,3,5,3]) - p.setXRange(0,5) - ex = pg.exporters.SVGExporter.SVGExporter(p.scene()) + pg.setConfigOption('foreground', (0,0,0)) + w = pg.GraphicsWindow() + w.show() + p1 = w.addPlot() + p2 = w.addPlot() + p1.plot([1,3,2,3,1,6,9,8,4,2,3,5,3], pen={'color':'k'}) + p1.setXRange(0,5) + p2.plot([1,5,2,3,4,6,1,2,4,2,3,5,3], pen={'color':'k', 'cosmetic':False, 'width': 0.3}) + app.processEvents() + app.processEvents() + + ex = pg.exporters.SVGExporter.SVGExporter(w.scene()) ex.export(fileName='test.svg') #def test_simple(self): #rect = pg.QtGui.QGraphicsRectItem(0, 0, 100, 100) - ##rect.rotate(30) + #rect.translate(50, 50) + #rect.rotate(30) #grp = pg.ItemGroup() #grp.setParentItem(rect) #grp.translate(200,0) - #grp.rotate(30) - #el = pg.QtGui.QGraphicsEllipseItem(10, 0, 100, 50) - #el.setParentItem(grp) + ##grp.rotate(30) + + #rect2 = pg.QtGui.QGraphicsRectItem(0, 0, 100, 25) + #rect2.setFlag(rect2.ItemClipsChildrenToShape) + #rect2.setParentItem(grp) + #rect2.setPos(0,25) + #rect2.rotate(30) + #el = pg.QtGui.QGraphicsEllipseItem(0, 0, 100, 50) + #el.translate(10,-5) + #el.scale(0.5,2) + #el.setParentItem(rect2) + #ex = pg.exporters.SVGExporter.SVGExporter(rect) #ex.export(fileName='test.svg') From 49e21776235318bd11aa7f6cb9f1bd58e7269162 Mon Sep 17 00:00:00 2001 From: Luke Campagnola Date: Wed, 26 Dec 2012 08:42:48 -0500 Subject: [PATCH 3/6] SVG export looks good. --- pyqtgraph/exporters/SVGExporter.py | 103 +++++++++++++++++--- pyqtgraph/graphicsItems/LinearRegionItem.py | 1 + 2 files changed, 89 insertions(+), 15 deletions(-) diff --git a/pyqtgraph/exporters/SVGExporter.py b/pyqtgraph/exporters/SVGExporter.py index 4052deec..9787de59 100644 --- a/pyqtgraph/exporters/SVGExporter.py +++ b/pyqtgraph/exporters/SVGExporter.py @@ -4,7 +4,7 @@ from pyqtgraph.Qt import QtGui, QtCore, QtSvg import pyqtgraph as pg import re import xml.dom.minidom as xml - +import numpy as np __all__ = ['SVGExporter'] @@ -121,13 +121,29 @@ def _generateItemSvg(item, nodes=None, root=None): ## 1) Qt SVG does not implement clipping paths. This is absurd. ## The solution is to let Qt generate SVG for each item independently, ## then glue them together manually with clipping. + ## + ## The format Qt generates for all items looks like this: + ## + ## + ## + ## one or more of: or or + ## + ## + ## one or more of: or or + ## + ## . . . + ## + ## ## 2) There seems to be wide disagreement over whether path strokes ## should be scaled anisotropically. ## see: http://web.mit.edu/jonas/www/anisotropy/ ## Given that both inkscape and illustrator seem to prefer isotropic ## scaling, we will optimize for those cases. + ## ## 3) Qt generates paths using non-scaling-stroke from SVG 1.2, but ## inkscape only supports 1.1. + ## + ## Both 2 and 3 can be addressed by drawing all items in world coordinates. @@ -155,14 +171,12 @@ def _generateItemSvg(item, nodes=None, root=None): doc = xml.parseString(xmlStr) else: childs = item.childItems() - tr.translate(item.pos().x(), item.pos().y()) - tr = tr * item.transform() - #if not item.isVisible() or int(item.flags() & item.ItemHasNoContents) > 0: - #m = (tr.m11(), tr.m12(), tr.m21(), tr.m22(), tr.m31(), tr.m32()) - ##print item, m - #xmlStr = '' % m # note: outer group is needed to separate clipping from transform - #doc = xml.parseString(xmlStr) - #else: + if isinstance(root, QtGui.QGraphicsScene): + tr = item.sceneTransform() + else: + tr = item.itemTransform(root) + #tr.translate(item.pos().x(), item.pos().y()) + #tr = tr * item.transform() arr = QtCore.QByteArray() buf = QtCore.QBuffer(arr) svg = QtSvg.QSvgGenerator() @@ -177,7 +191,7 @@ def _generateItemSvg(item, nodes=None, root=None): if hasattr(item, 'setExportMode'): item.setExportMode(True, {'painter': p}) try: - #p.setTransform(tr) + p.setTransform(tr) item.paint(p, QtGui.QStyleOptionGraphicsItem(), None) finally: p.end() @@ -197,17 +211,22 @@ def _generateItemSvg(item, nodes=None, root=None): except: print doc.toxml() raise + + + ## Get rid of group transformation matrices by applying + ## transformation to inner coordinates + correctCoordinates(g1, item) ## make sure g1 has the transformation matrix - m = (tr.m11(), tr.m12(), tr.m21(), tr.m22(), tr.m31(), tr.m32()) - g1.setAttribute('transform', "matrix(%f,%f,%f,%f,%f,%f)" % m) + #m = (tr.m11(), tr.m12(), tr.m21(), tr.m22(), tr.m31(), tr.m32()) + #g1.setAttribute('transform', "matrix(%f,%f,%f,%f,%f,%f)" % m) #print "=================",item,"=====================" #print g1.toprettyxml(indent=" ", newl='') ## Inkscape does not support non-scaling-stroke (this is SVG 1.2, inkscape supports 1.1) ## So we need to correct anything attempting to use this. - correctStroke(g1, item, root) + #correctStroke(g1, item, root) ## decide on a name for this item baseName = item.__class__.__name__ @@ -226,7 +245,10 @@ def _generateItemSvg(item, nodes=None, root=None): ## See if this item clips its children if int(item.flags() & item.ItemClipsChildrenToShape) > 0: ## Generate svg for just the path - path = QtGui.QGraphicsPathItem(item.shape()) + if isinstance(root, QtGui.QGraphicsScene): + path = QtGui.QGraphicsPathItem(item.mapToScene(item.shape())) + else: + path = QtGui.QGraphicsPathItem(item.mapToItem(root, item.shape())) pathNode = _generateItemSvg(path, root=root).getElementsByTagName('path')[0] ## and for the clipPath element clip = name + '_clip' @@ -248,7 +270,58 @@ def _generateItemSvg(item, nodes=None, root=None): return g1 - +def correctCoordinates(node, item): + ## Remove transformation matrices from tags by applying matrix to coordinates inside. + groups = node.getElementsByTagName('g') + for grp in groups: + matrix = grp.getAttribute('transform') + match = re.match(r'matrix\((.*)\)', matrix) + if match is None: + vals = [1,0,0,1,0,0] + else: + vals = map(float, match.groups()[0].split(',')) + tr = np.array([[vals[0], vals[2], vals[4]], [vals[1], vals[3], vals[5]]]) + + removeTransform = False + for ch in grp.childNodes: + if not isinstance(ch, xml.Element): + continue + if ch.tagName == 'polyline': + removeTransform = True + coords = np.array([map(float, c.split(',')) for c in ch.getAttribute('points').strip().split(' ')]) + coords = pg.transformCoordinates(tr, coords, transpose=True) + ch.setAttribute('points', ' '.join([','.join(map(str, c)) for c in coords])) + elif ch.tagName == 'path': + removeTransform = True + newCoords = '' + for c in ch.getAttribute('d').strip().split(' '): + x,y = c.split(',') + if x[0].isalpha(): + t = x[0] + x = x[1:] + else: + t = '' + nc = pg.transformCoordinates(tr, np.array([[float(x),float(y)]]), transpose=True) + newCoords += t+str(nc[0,0])+','+str(nc[0,1])+' ' + ch.setAttribute('d', newCoords) + elif ch.tagName == 'text': + removeTransform = False + #c = np.array([ + #[float(ch.getAttribute('x')), float(ch.getAttribute('y'))], + #[float(ch.getAttribute('font-size')), 0], + #[0,0]]) + #c = pg.transformCoordinates(tr, c, transpose=True) + #ch.setAttribute('x', str(c[0,0])) + #ch.setAttribute('y', str(c[0,1])) + #fs = c[1]-c[2] + #fs = (fs**2).sum()**0.5 + #ch.setAttribute('font-size', str(fs)) + else: + print('warning: export not implemented for SVG tag %s (from item %s)' % (ch.tagName, item)) + + if removeTransform: + grp.removeAttribute('transform') + def correctStroke(node, item, root, width=1): #print "==============", item, node diff --git a/pyqtgraph/graphicsItems/LinearRegionItem.py b/pyqtgraph/graphicsItems/LinearRegionItem.py index e1b391aa..0b44c815 100644 --- a/pyqtgraph/graphicsItems/LinearRegionItem.py +++ b/pyqtgraph/graphicsItems/LinearRegionItem.py @@ -143,6 +143,7 @@ class LinearRegionItem(UIGraphicsItem): #prof = debug.Profiler('LinearRegionItem.paint') UIGraphicsItem.paint(self, p, *args) p.setBrush(self.currentBrush) + p.setPen(fn.mkPen(None)) p.drawRect(self.boundingRect()) #prof.finish() From 51e88bd436b4af7f6ac7f424a8c5ef580b3aac3e Mon Sep 17 00:00:00 2001 From: Luke Campagnola Date: Wed, 26 Dec 2012 13:48:12 -0500 Subject: [PATCH 4/6] SVG export fixes --- examples/__main__.py | 6 +- pyqtgraph/exporters/SVGExporter.py | 106 +++++++++++++++++++++-------- tests/svg.py | 56 ++++++++++----- 3 files changed, 121 insertions(+), 47 deletions(-) diff --git a/examples/__main__.py b/examples/__main__.py index 1dbe7b9a..bbba88f8 100644 --- a/examples/__main__.py +++ b/examples/__main__.py @@ -166,7 +166,7 @@ def buildFileList(examples, files=None): buildFileList(val, files) return files -def testFile(name, f, exe, lib, graphicsSystem): +def testFile(name, f, exe, lib, graphicsSystem=None): global path fn = os.path.join(path,f) #print "starting process: ", fn @@ -194,8 +194,8 @@ except: print("test failed") raise -""" % (import1, import2, graphicsSystem) - #print code +""" % (import1, graphicsSystem, import2) + 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')) #process.stdin.close() diff --git a/pyqtgraph/exporters/SVGExporter.py b/pyqtgraph/exporters/SVGExporter.py index 9787de59..ce05b82d 100644 --- a/pyqtgraph/exporters/SVGExporter.py +++ b/pyqtgraph/exporters/SVGExporter.py @@ -153,7 +153,7 @@ def _generateItemSvg(item, nodes=None, root=None): if root is None: root = item - + ## Skip hidden items if hasattr(item, 'isVisible') and not item.isVisible(): return None @@ -171,10 +171,10 @@ def _generateItemSvg(item, nodes=None, root=None): doc = xml.parseString(xmlStr) else: childs = item.childItems() - if isinstance(root, QtGui.QGraphicsScene): - tr = item.sceneTransform() - else: - tr = item.itemTransform(root) + tr = itemTransform(item, root) + + #print item, pg.SRTTransform(tr) + #tr.translate(item.pos().x(), item.pos().y()) #tr = tr * item.transform() arr = QtCore.QByteArray() @@ -248,7 +248,7 @@ def _generateItemSvg(item, nodes=None, root=None): if isinstance(root, QtGui.QGraphicsScene): path = QtGui.QGraphicsPathItem(item.mapToScene(item.shape())) else: - path = QtGui.QGraphicsPathItem(item.mapToItem(root, item.shape())) + path = QtGui.QGraphicsPathItem(root.mapToParent(item.mapToItem(root, item.shape()))) pathNode = _generateItemSvg(path, root=root).getElementsByTagName('path')[0] ## and for the clipPath element clip = name + '_clip' @@ -306,6 +306,7 @@ def correctCoordinates(node, item): ch.setAttribute('d', newCoords) elif ch.tagName == 'text': removeTransform = False + ## leave text alone for now. Might need this later to correctly render text with outline. #c = np.array([ #[float(ch.getAttribute('x')), float(ch.getAttribute('y'))], #[float(ch.getAttribute('font-size')), 0], @@ -318,32 +319,82 @@ def correctCoordinates(node, item): #ch.setAttribute('font-size', str(fs)) else: print('warning: export not implemented for SVG tag %s (from item %s)' % (ch.tagName, item)) + + ## correct line widths if needed + if removeTransform and ch.getAttribute('vector-effect') != 'non-scaling-stroke': + w = float(grp.getAttribute('stroke-width')) + s = pg.transformCoordinates(tr, np.array([[w,0], [0,0]]), transpose=True) + w = ((s[0]-s[1])**2).sum()**0.5 + ch.setAttribute('stroke-width', str(w)) if removeTransform: grp.removeAttribute('transform') -def correctStroke(node, item, root, width=1): - #print "==============", item, node - if node.hasAttribute('stroke-width'): - width = float(node.getAttribute('stroke-width')) - if node.getAttribute('vector-effect') == 'non-scaling-stroke': - node.removeAttribute('vector-effect') - if isinstance(root, QtGui.QGraphicsScene): - w = item.mapFromScene(pg.Point(width,0)) - o = item.mapFromScene(pg.Point(0,0)) - else: - w = item.mapFromItem(root, pg.Point(width,0)) - o = item.mapFromItem(root, pg.Point(0,0)) - w = w-o - #print " ", w, o, w-o - w = (w.x()**2 + w.y()**2) ** 0.5 - #print " ", w - node.setAttribute('stroke-width', str(w)) +def itemTransform(item, root): + ## Return the transformation mapping item to root + ## (actually to parent coordinate system of root) - for ch in node.childNodes: - if isinstance(ch, xml.Element): - correctStroke(ch, item, root, width) + if item is root: + tr = QtGui.QTransform() + tr.translate(*item.pos()) + tr = tr * item.transform() + return tr + + + if int(item.flags() & item.ItemIgnoresTransformations) > 0: + pos = item.pos() + parent = item.parentItem() + if parent is not None: + pos = itemTransform(parent, root).map(pos) + tr = QtGui.QTransform() + tr.translate(pos.x(), pos.y()) + tr = item.transform() * tr + else: + ## find next parent that is either the root item or + ## an item that ignores its transformation + nextRoot = item + while True: + nextRoot = nextRoot.parentItem() + if nextRoot is None: + nextRoot = root + break + if nextRoot is root or int(nextRoot.flags() & nextRoot.ItemIgnoresTransformations) > 0: + break + + if isinstance(nextRoot, QtGui.QGraphicsScene): + tr = item.sceneTransform() + else: + tr = itemTransform(nextRoot, root) * item.itemTransform(nextRoot)[0] + #pos = QtGui.QTransform() + #pos.translate(root.pos().x(), root.pos().y()) + #tr = pos * root.transform() * item.itemTransform(root)[0] + + + return tr + + +#def correctStroke(node, item, root, width=1): + ##print "==============", item, node + #if node.hasAttribute('stroke-width'): + #width = float(node.getAttribute('stroke-width')) + #if node.getAttribute('vector-effect') == 'non-scaling-stroke': + #node.removeAttribute('vector-effect') + #if isinstance(root, QtGui.QGraphicsScene): + #w = item.mapFromScene(pg.Point(width,0)) + #o = item.mapFromScene(pg.Point(0,0)) + #else: + #w = item.mapFromItem(root, pg.Point(width,0)) + #o = item.mapFromItem(root, pg.Point(0,0)) + #w = w-o + ##print " ", w, o, w-o + #w = (w.x()**2 + w.y()**2) ** 0.5 + ##print " ", w + #node.setAttribute('stroke-width', str(w)) + + #for ch in node.childNodes: + #if isinstance(ch, xml.Element): + #correctStroke(ch, item, root, width) def cleanXml(node): ## remove extraneous text; let the xml library do the formatting. @@ -359,4 +410,5 @@ def cleanXml(node): if hasElement: for ch in nonElement: node.removeChild(ch) - + elif node.tagName == 'g': ## remove childless groups + node.parentNode.removeChild(node) diff --git a/tests/svg.py b/tests/svg.py index db54eb83..7c26833e 100644 --- a/tests/svg.py +++ b/tests/svg.py @@ -6,26 +6,40 @@ import pyqtgraph as pg app = pg.mkQApp() class SVGTest(test.TestCase): - def test_plotscene(self): - pg.setConfigOption('foreground', (0,0,0)) - w = pg.GraphicsWindow() - w.show() - p1 = w.addPlot() - p2 = w.addPlot() - p1.plot([1,3,2,3,1,6,9,8,4,2,3,5,3], pen={'color':'k'}) - p1.setXRange(0,5) - p2.plot([1,5,2,3,4,6,1,2,4,2,3,5,3], pen={'color':'k', 'cosmetic':False, 'width': 0.3}) - app.processEvents() - app.processEvents() + #def test_plotscene(self): + #pg.setConfigOption('foreground', (0,0,0)) + #w = pg.GraphicsWindow() + #w.show() + #p1 = w.addPlot() + #p2 = w.addPlot() + #p1.plot([1,3,2,3,1,6,9,8,4,2,3,5,3], pen={'color':'k'}) + #p1.setXRange(0,5) + #p2.plot([1,5,2,3,4,6,1,2,4,2,3,5,3], pen={'color':'k', 'cosmetic':False, 'width': 0.3}) + #app.processEvents() + #app.processEvents() - ex = pg.exporters.SVGExporter.SVGExporter(w.scene()) - ex.export(fileName='test.svg') + #ex = pg.exporters.SVGExporter.SVGExporter(w.scene()) + #ex.export(fileName='test.svg') - #def test_simple(self): + + def test_simple(self): + scene = pg.QtGui.QGraphicsScene() #rect = pg.QtGui.QGraphicsRectItem(0, 0, 100, 100) + #scene.addItem(rect) + #rect.setPos(20,20) #rect.translate(50, 50) #rect.rotate(30) - #grp = pg.ItemGroup() + #rect.scale(0.5, 0.5) + + #rect1 = pg.QtGui.QGraphicsRectItem(0, 0, 100, 100) + #rect1.setParentItem(rect) + #rect1.setFlag(rect1.ItemIgnoresTransformations) + #rect1.setPos(20, 20) + #rect1.scale(2,2) + + #el1 = pg.QtGui.QGraphicsEllipseItem(0, 0, 100, 100) + #el1.setParentItem(rect1) + ##grp = pg.ItemGroup() #grp.setParentItem(rect) #grp.translate(200,0) ##grp.rotate(30) @@ -40,8 +54,16 @@ class SVGTest(test.TestCase): #el.scale(0.5,2) #el.setParentItem(rect2) - #ex = pg.exporters.SVGExporter.SVGExporter(rect) - #ex.export(fileName='test.svg') + grp2 = pg.ItemGroup() + scene.addItem(grp2) + grp2.scale(100,100) + + rect3 = pg.QtGui.QGraphicsRectItem(0,0,2,2) + rect3.setPen(pg.mkPen(width=1, cosmetic=False)) + grp2.addItem(rect3) + + ex = pg.exporters.SVGExporter.SVGExporter(scene) + ex.export(fileName='test.svg') if __name__ == '__main__': From 5374afeca867b51265227ee4cdd01cb231bbafea Mon Sep 17 00:00:00 2001 From: Luke Campagnola Date: Wed, 26 Dec 2012 15:22:44 -0500 Subject: [PATCH 5/6] Added basic 3D line plot class --- examples/GLLinePlotItem.py | 48 ++++++++++++++ pyqtgraph/opengl/items/GLLinePlotItem.py | 81 ++++++++++++++++++++++++ 2 files changed, 129 insertions(+) create mode 100644 examples/GLLinePlotItem.py create mode 100644 pyqtgraph/opengl/items/GLLinePlotItem.py diff --git a/examples/GLLinePlotItem.py b/examples/GLLinePlotItem.py new file mode 100644 index 00000000..7a670333 --- /dev/null +++ b/examples/GLLinePlotItem.py @@ -0,0 +1,48 @@ +# -*- coding: utf-8 -*- +## Add path to library (just for examples; you do not need this) +import sys, os +sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', '..')) + +from pyqtgraph.Qt import QtCore, QtGui +import pyqtgraph.opengl as gl +import pyqtgraph as pg +import numpy as np + +app = QtGui.QApplication([]) +w = gl.GLViewWidget() +w.opts['distance'] = 40 +w.show() + +gx = gl.GLGridItem() +gx.rotate(90, 0, 1, 0) +gx.translate(-10, 0, 0) +w.addItem(gx) +gy = gl.GLGridItem() +gy.rotate(90, 1, 0, 0) +gy.translate(0, -10, 0) +w.addItem(gy) +gz = gl.GLGridItem() +gz.translate(0, 0, -10) +w.addItem(gz) + +def fn(x, y): + return np.cos((x**2 + y**2)**0.5) + +n = 51 +y = np.linspace(-10,10,n) +x = np.linspace(-10,10,100) +for i in range(n): + yi = np.array([y[i]]*100) + d = (x**2 + yi**2)**0.5 + z = 10 * np.cos(d) / (d+1) + pts = np.vstack([x,yi,z]).transpose() + plt = gl.GLLinePlotItem(pos=pts, color=pg.glColor((i,n*1.3))) + w.addItem(plt) + + + +## Start Qt event loop unless running in interactive mode. +if __name__ == '__main__': + import sys + if (sys.flags.interactive != 1) or not hasattr(QtCore, 'PYQT_VERSION'): + QtGui.QApplication.instance().exec_() diff --git a/pyqtgraph/opengl/items/GLLinePlotItem.py b/pyqtgraph/opengl/items/GLLinePlotItem.py new file mode 100644 index 00000000..ef747d17 --- /dev/null +++ b/pyqtgraph/opengl/items/GLLinePlotItem.py @@ -0,0 +1,81 @@ +from OpenGL.GL import * +from OpenGL.arrays import vbo +from .. GLGraphicsItem import GLGraphicsItem +from .. import shaders +from pyqtgraph import QtGui +import numpy as np + +__all__ = ['GLLinePlotItem'] + +class GLLinePlotItem(GLGraphicsItem): + """Draws line plots in 3D.""" + + def __init__(self, **kwds): + GLGraphicsItem.__init__(self) + glopts = kwds.pop('glOptions', 'additive') + self.setGLOptions(glopts) + self.pos = None + self.width = 1. + self.color = (1.0,1.0,1.0,1.0) + self.setData(**kwds) + + def setData(self, **kwds): + """ + Update the data displayed by this item. All arguments are optional; + for example it is allowed to update spot positions while leaving + colors unchanged, etc. + + ==================== ================================================== + Arguments: + ------------------------------------------------------------------------ + pos (N,3) array of floats specifying point locations. + color tuple of floats (0.0-1.0) specifying + a color for the entire item. + width float specifying line width + ==================== ================================================== + """ + args = ['pos', 'color', 'width', 'connected'] + for k in kwds.keys(): + if k not in args: + raise Exception('Invalid keyword argument: %s (allowed arguments are %s)' % (k, str(args))) + + for arg in args: + if arg in kwds: + setattr(self, arg, kwds[arg]) + #self.vbo.pop(arg, None) + self.update() + + def initializeGL(self): + pass + + #def setupGLState(self): + #"""Prepare OpenGL state for drawing. This function is called immediately before painting.""" + ##glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) ## requires z-sorting to render properly. + #glBlendFunc(GL_SRC_ALPHA, GL_ONE) + #glEnable( GL_BLEND ) + #glEnable( GL_ALPHA_TEST ) + #glDisable( GL_DEPTH_TEST ) + + ##glEnable( GL_POINT_SMOOTH ) + + ##glHint(GL_POINT_SMOOTH_HINT, GL_NICEST) + ##glPointParameterfv(GL_POINT_DISTANCE_ATTENUATION, (0, 0, -1e-3)) + ##glPointParameterfv(GL_POINT_SIZE_MAX, (65500,)) + ##glPointParameterfv(GL_POINT_SIZE_MIN, (0,)) + + def paint(self): + if self.pos is None: + return + self.setupGLState() + + glEnableClientState(GL_VERTEX_ARRAY) + try: + glVertexPointerf(self.pos) + glColor4f(*self.color) + + glPointSize(self.width) + glDrawArrays(GL_LINE_STRIP, 0, self.pos.size / self.pos.shape[-1]) + finally: + glDisableClientState(GL_VERTEX_ARRAY) + + From 51b0ba0877932a90474eb3aeccea1618b55133df Mon Sep 17 00:00:00 2001 From: Luke Campagnola Date: Wed, 26 Dec 2012 15:26:04 -0500 Subject: [PATCH 6/6] added line plot example to menu --- examples/__main__.py | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/__main__.py b/examples/__main__.py index bbba88f8..6655cddb 100644 --- a/examples/__main__.py +++ b/examples/__main__.py @@ -47,6 +47,7 @@ examples = OrderedDict([ ('Surface Plot', 'GLSurfacePlot.py'), ('Scatter Plot', 'GLScatterPlotItem.py'), ('Shaders', 'GLshaders.py'), + ('Line Plot', 'GLLinePlotItem.py'), ('Mesh', 'GLMeshItem.py'), ('Image', 'GLImageItem.py'), ])),