diff --git a/GraphicsScene/GraphicsScene.py b/GraphicsScene/GraphicsScene.py index 8729d085..d61a1fa4 100644 --- a/GraphicsScene/GraphicsScene.py +++ b/GraphicsScene/GraphicsScene.py @@ -1,19 +1,11 @@ -from pyqtgraph.Qt import QtCore, QtGui - -from pyqtgraph.python2_3 import sortList -#try: - #from PyQt4 import QtOpenGL - #HAVE_OPENGL = True -#except ImportError: - #HAVE_OPENGL = False - +from ..Qt import QtCore, QtGui +from ..python2_3 import sortList import weakref -from pyqtgraph.Point import Point -import pyqtgraph.functions as fn -import pyqtgraph.ptime as ptime +from ..Point import Point +from .. import functions as fn +from .. import ptime as ptime from .mouseEvents import * -import pyqtgraph.debug as debug -from . import exportDialog +from .. import debug as debug if hasattr(QtCore, 'PYQT_VERSION'): try: @@ -489,7 +481,7 @@ class GraphicsScene(QtGui.QGraphicsScene): #return v #else: #return widget - + def addParentContextMenus(self, item, menu, event): """ Can be called by any item in the scene to expand its context menu to include parent context menus. @@ -519,30 +511,23 @@ class GraphicsScene(QtGui.QGraphicsScene): event The original event that triggered the menu to appear. ============== ================================================== """ - - #items = self.itemsNearEvent(ev) + menusToAdd = [] while item is not self: item = item.parentItem() - if item is None: item = self - if not hasattr(item, "getContextMenus"): continue - - subMenus = item.getContextMenus(event) - if subMenus is None: - continue - if type(subMenus) is not list: ## so that some items (like FlowchartViewBox) can return multiple menus - subMenus = [subMenus] - - for sm in subMenus: - menusToAdd.append(sm) - - if len(menusToAdd) > 0: + subMenus = item.getContextMenus(event) or [] + if isinstance(subMenus, list): ## so that some items (like FlowchartViewBox) can return multiple menus + menusToAdd.extend(subMenus) + else: + menusToAdd.append(subMenus) + + if menusToAdd: menu.addSeparator() - + for m in menusToAdd: if isinstance(m, QtGui.QMenu): menu.addMenu(m) @@ -559,6 +544,7 @@ class GraphicsScene(QtGui.QGraphicsScene): def showExportDialog(self): if self.exportDialog is None: + from . import exportDialog self.exportDialog = exportDialog.ExportDialog(self) self.exportDialog.show(self.contextMenuItem) diff --git a/GraphicsScene/exportDialog.py b/GraphicsScene/exportDialog.py index 436d5e42..5efb7c44 100644 --- a/GraphicsScene/exportDialog.py +++ b/GraphicsScene/exportDialog.py @@ -1,6 +1,8 @@ -from pyqtgraph.Qt import QtCore, QtGui, USE_PYSIDE -import pyqtgraph as pg -import pyqtgraph.exporters as exporters +from ..Qt import QtCore, QtGui, USE_PYSIDE +from .. import exporters as exporters +from .. import functions as fn +from ..graphicsItems.ViewBox import ViewBox +from ..graphicsItems.PlotItem import PlotItem if USE_PYSIDE: from . import exportDialogTemplate_pyside as exportDialogTemplate @@ -18,7 +20,7 @@ class ExportDialog(QtGui.QWidget): self.scene = scene self.selectBox = QtGui.QGraphicsRectItem() - self.selectBox.setPen(pg.mkPen('y', width=3, style=QtCore.Qt.DashLine)) + self.selectBox.setPen(fn.mkPen('y', width=3, style=QtCore.Qt.DashLine)) self.selectBox.hide() self.scene.addItem(self.selectBox) @@ -35,10 +37,10 @@ class ExportDialog(QtGui.QWidget): def show(self, item=None): if item is not None: ## Select next exportable parent of the item originally clicked on - while not isinstance(item, pg.ViewBox) and not isinstance(item, pg.PlotItem) and item is not None: + while not isinstance(item, ViewBox) and not isinstance(item, PlotItem) and item is not None: item = item.parentItem() ## if this is a ViewBox inside a PlotItem, select the parent instead. - if isinstance(item, pg.ViewBox) and isinstance(item.parentItem(), pg.PlotItem): + if isinstance(item, ViewBox) and isinstance(item.parentItem(), PlotItem): item = item.parentItem() self.updateItemList(select=item) self.setVisible(True) @@ -64,9 +66,9 @@ class ExportDialog(QtGui.QWidget): def updateItemTree(self, item, treeItem, select=None): si = None - if isinstance(item, pg.ViewBox): + if isinstance(item, ViewBox): si = QtGui.QTreeWidgetItem(['ViewBox']) - elif isinstance(item, pg.PlotItem): + elif isinstance(item, PlotItem): si = QtGui.QTreeWidgetItem(['Plot']) if si is not None: diff --git a/GraphicsScene/exportDialogTemplate.ui b/GraphicsScene/exportDialogTemplate.ui index c91fbc3f..eacacd88 100644 --- a/GraphicsScene/exportDialogTemplate.ui +++ b/GraphicsScene/exportDialogTemplate.ui @@ -92,7 +92,7 @@ ParameterTree QTreeWidget -
pyqtgraph.parametertree
+
..parametertree
diff --git a/GraphicsScene/exportDialogTemplate_pyqt.py b/GraphicsScene/exportDialogTemplate_pyqt.py index c3056d1c..ad7361ab 100644 --- a/GraphicsScene/exportDialogTemplate_pyqt.py +++ b/GraphicsScene/exportDialogTemplate_pyqt.py @@ -1,9 +1,9 @@ # -*- coding: utf-8 -*- -# Form implementation generated from reading ui file './GraphicsScene/exportDialogTemplate.ui' +# Form implementation generated from reading ui file './pyqtgraph/GraphicsScene/exportDialogTemplate.ui' # -# Created: Wed Jan 30 21:02:28 2013 -# by: PyQt4 UI code generator 4.9.3 +# Created: Mon Dec 23 10:10:52 2013 +# by: PyQt4 UI code generator 4.10 # # WARNING! All changes made in this file will be lost! @@ -12,7 +12,16 @@ from PyQt4 import QtCore, QtGui try: _fromUtf8 = QtCore.QString.fromUtf8 except AttributeError: - _fromUtf8 = lambda s: s + def _fromUtf8(s): + return s + +try: + _encoding = QtGui.QApplication.UnicodeUTF8 + def _translate(context, text, disambig): + return QtGui.QApplication.translate(context, text, disambig, _encoding) +except AttributeError: + def _translate(context, text, disambig): + return QtGui.QApplication.translate(context, text, disambig) class Ui_Form(object): def setupUi(self, Form): @@ -57,12 +66,12 @@ class Ui_Form(object): QtCore.QMetaObject.connectSlotsByName(Form) def retranslateUi(self, Form): - Form.setWindowTitle(QtGui.QApplication.translate("Form", "Export", None, QtGui.QApplication.UnicodeUTF8)) - self.label.setText(QtGui.QApplication.translate("Form", "Item to export:", None, QtGui.QApplication.UnicodeUTF8)) - self.label_2.setText(QtGui.QApplication.translate("Form", "Export format", None, QtGui.QApplication.UnicodeUTF8)) - self.exportBtn.setText(QtGui.QApplication.translate("Form", "Export", None, QtGui.QApplication.UnicodeUTF8)) - self.closeBtn.setText(QtGui.QApplication.translate("Form", "Close", None, QtGui.QApplication.UnicodeUTF8)) - self.label_3.setText(QtGui.QApplication.translate("Form", "Export options", None, QtGui.QApplication.UnicodeUTF8)) - self.copyBtn.setText(QtGui.QApplication.translate("Form", "Copy", None, QtGui.QApplication.UnicodeUTF8)) + Form.setWindowTitle(_translate("Form", "Export", None)) + self.label.setText(_translate("Form", "Item to export:", None)) + self.label_2.setText(_translate("Form", "Export format", None)) + self.exportBtn.setText(_translate("Form", "Export", None)) + self.closeBtn.setText(_translate("Form", "Close", None)) + self.label_3.setText(_translate("Form", "Export options", None)) + self.copyBtn.setText(_translate("Form", "Copy", None)) -from pyqtgraph.parametertree import ParameterTree +from ..parametertree import ParameterTree diff --git a/GraphicsScene/exportDialogTemplate_pyside.py b/GraphicsScene/exportDialogTemplate_pyside.py index cf27f60a..f2e8dc70 100644 --- a/GraphicsScene/exportDialogTemplate_pyside.py +++ b/GraphicsScene/exportDialogTemplate_pyside.py @@ -1,9 +1,9 @@ # -*- coding: utf-8 -*- -# Form implementation generated from reading ui file './GraphicsScene/exportDialogTemplate.ui' +# Form implementation generated from reading ui file './pyqtgraph/GraphicsScene/exportDialogTemplate.ui' # -# Created: Wed Jan 30 21:02:28 2013 -# by: pyside-uic 0.2.13 running on PySide 1.1.1 +# Created: Mon Dec 23 10:10:53 2013 +# by: pyside-uic 0.2.14 running on PySide 1.1.2 # # WARNING! All changes made in this file will be lost! @@ -60,4 +60,4 @@ class Ui_Form(object): self.label_3.setText(QtGui.QApplication.translate("Form", "Export options", None, QtGui.QApplication.UnicodeUTF8)) self.copyBtn.setText(QtGui.QApplication.translate("Form", "Copy", None, QtGui.QApplication.UnicodeUTF8)) -from pyqtgraph.parametertree import ParameterTree +from ..parametertree import ParameterTree diff --git a/GraphicsScene/mouseEvents.py b/GraphicsScene/mouseEvents.py index 0b71ac6f..f337a657 100644 --- a/GraphicsScene/mouseEvents.py +++ b/GraphicsScene/mouseEvents.py @@ -1,7 +1,7 @@ -from pyqtgraph.Point import Point -from pyqtgraph.Qt import QtCore, QtGui +from ..Point import Point +from ..Qt import QtCore, QtGui import weakref -import pyqtgraph.ptime as ptime +from .. import ptime as ptime class MouseDragEvent(object): """ diff --git a/Qt.py b/Qt.py index e584a381..410bfd83 100644 --- a/Qt.py +++ b/Qt.py @@ -1,4 +1,14 @@ -## Do all Qt imports from here to allow easier PyQt / PySide compatibility +""" +This module exists to smooth out some of the differences between PySide and PyQt4: + +* Automatically import either PyQt4 or PySide depending on availability +* Allow to import QtCore/QtGui pyqtgraph.Qt without specifying which Qt wrapper + you want to use. +* Declare QtCore.Signal, .Slot in PyQt4 +* Declare loadUiType function for Pyside + +""" + import sys, re ## Automatically determine whether to use PyQt or PySide. @@ -23,8 +33,41 @@ if USE_PYSIDE: from PySide import QtGui, QtCore, QtOpenGL, QtSvg import PySide VERSION_INFO = 'PySide ' + PySide.__version__ + + # Make a loadUiType function like PyQt has + + # Credit: + # http://stackoverflow.com/questions/4442286/python-code-genration-with-pyside-uic/14195313#14195313 + + def loadUiType(uiFile): + """ + Pyside "loadUiType" command like PyQt4 has one, so we have to convert the ui file to py code in-memory first and then execute it in a special frame to retrieve the form_class. + """ + import pysideuic + import xml.etree.ElementTree as xml + from io import StringIO + + parsed = xml.parse(uiFile) + widget_class = parsed.find('widget').get('class') + form_class = parsed.find('class').text + + with open(uiFile, 'r') as f: + o = StringIO() + frame = {} + + pysideuic.compileUi(f, o, indent=0) + pyc = compile(o.getvalue(), '', 'exec') + exec(pyc, frame) + + #Fetch the base_class and form class based on their type in the xml from designer + form_class = frame['Ui_%s'%form_class] + base_class = eval('QtGui.%s'%widget_class) + + return form_class, base_class + + else: - from PyQt4 import QtGui, QtCore + from PyQt4 import QtGui, QtCore, uic try: from PyQt4 import QtSvg except ImportError: @@ -34,6 +77,9 @@ else: except ImportError: pass + + loadUiType = uic.loadUiType + QtCore.Signal = QtCore.pyqtSignal VERSION_INFO = 'PyQt4 ' + QtCore.PYQT_VERSION_STR + ' Qt ' + QtCore.QT_VERSION_STR @@ -43,6 +89,6 @@ versionReq = [4, 7] QtVersion = PySide.QtCore.__version__ if USE_PYSIDE else QtCore.QT_VERSION_STR m = re.match(r'(\d+)\.(\d+).*', QtVersion) if m is not None and list(map(int, m.groups())) < versionReq: - print(map(int, m.groups())) + print(list(map(int, m.groups()))) raise Exception('pyqtgraph requires Qt version >= %d.%d (your version is %s)' % (versionReq[0], versionReq[1], QtVersion)) diff --git a/SRTTransform.py b/SRTTransform.py index efb24f60..23281343 100644 --- a/SRTTransform.py +++ b/SRTTransform.py @@ -2,7 +2,6 @@ from .Qt import QtCore, QtGui from .Point import Point import numpy as np -import pyqtgraph as pg class SRTTransform(QtGui.QTransform): """Transform that can always be represented as a combination of 3 matrices: scale * rotate * translate @@ -77,7 +76,7 @@ class SRTTransform(QtGui.QTransform): self.update() def setFromMatrix4x4(self, m): - m = pg.SRTTransform3D(m) + m = SRTTransform3D(m) angle, axis = m.getRotation() if angle != 0 and (axis[0] != 0 or axis[1] != 0 or axis[2] != 1): print("angle: %s axis: %s" % (str(angle), str(axis))) @@ -256,4 +255,4 @@ if __name__ == '__main__': w1.sigRegionChanged.connect(update) #w2.sigRegionChanged.connect(update2) - \ No newline at end of file +from .SRTTransform3D import SRTTransform3D diff --git a/SRTTransform3D.py b/SRTTransform3D.py index 7d87dcb8..417190e1 100644 --- a/SRTTransform3D.py +++ b/SRTTransform3D.py @@ -1,17 +1,17 @@ # -*- coding: utf-8 -*- from .Qt import QtCore, QtGui from .Vector import Vector -from .SRTTransform import SRTTransform -import pyqtgraph as pg +from .Transform3D import Transform3D +from .Vector import Vector import numpy as np import scipy.linalg -class SRTTransform3D(pg.Transform3D): +class SRTTransform3D(Transform3D): """4x4 Transform matrix that can always be represented as a combination of 3 matrices: scale * rotate * translate This transform has no shear; angles are always preserved. """ def __init__(self, init=None): - pg.Transform3D.__init__(self) + Transform3D.__init__(self) self.reset() if init is None: return @@ -44,14 +44,14 @@ class SRTTransform3D(pg.Transform3D): def getScale(self): - return pg.Vector(self._state['scale']) + return Vector(self._state['scale']) def getRotation(self): """Return (angle, axis) of rotation""" - return self._state['angle'], pg.Vector(self._state['axis']) + return self._state['angle'], Vector(self._state['axis']) def getTranslation(self): - return pg.Vector(self._state['pos']) + return Vector(self._state['pos']) def reset(self): self._state = { @@ -169,7 +169,7 @@ class SRTTransform3D(pg.Transform3D): def as2D(self): """Return a QTransform representing the x,y portion of this transform (if possible)""" - return pg.SRTTransform(self) + return SRTTransform(self) #def __div__(self, t): #"""A / B == B^-1 * A""" @@ -202,11 +202,11 @@ class SRTTransform3D(pg.Transform3D): self.update() def update(self): - pg.Transform3D.setToIdentity(self) + Transform3D.setToIdentity(self) ## modifications to the transform are multiplied on the right, so we need to reverse order here. - pg.Transform3D.translate(self, *self._state['pos']) - pg.Transform3D.rotate(self, self._state['angle'], *self._state['axis']) - pg.Transform3D.scale(self, *self._state['scale']) + Transform3D.translate(self, *self._state['pos']) + Transform3D.rotate(self, self._state['angle'], *self._state['axis']) + Transform3D.scale(self, *self._state['scale']) def __repr__(self): return str(self.saveState()) @@ -311,4 +311,4 @@ if __name__ == '__main__': w1.sigRegionChanged.connect(update) #w2.sigRegionChanged.connect(update2) - \ No newline at end of file +from .SRTTransform import SRTTransform diff --git a/ThreadsafeTimer.py b/ThreadsafeTimer.py index f2de9791..201469de 100644 --- a/ThreadsafeTimer.py +++ b/ThreadsafeTimer.py @@ -1,4 +1,4 @@ -from pyqtgraph.Qt import QtCore, QtGui +from .Qt import QtCore, QtGui class ThreadsafeTimer(QtCore.QObject): """ diff --git a/Transform3D.py b/Transform3D.py index aa948e28..43b12de3 100644 --- a/Transform3D.py +++ b/Transform3D.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- from .Qt import QtCore, QtGui -import pyqtgraph as pg +from . import functions as fn import numpy as np class Transform3D(QtGui.QMatrix4x4): @@ -26,7 +26,7 @@ class Transform3D(QtGui.QMatrix4x4): Extends QMatrix4x4.map() to allow mapping (3, ...) arrays of coordinates """ if isinstance(obj, np.ndarray) and obj.ndim >= 2 and obj.shape[0] in (2,3): - return pg.transformCoordinates(self, obj) + return fn.transformCoordinates(self, obj) else: return QtGui.QMatrix4x4.map(self, obj) diff --git a/__init__.py b/__init__.py index 11e281a4..77b7c590 100644 --- a/__init__.py +++ b/__init__.py @@ -4,7 +4,7 @@ PyQtGraph - Scientific Graphics and GUI Library for Python www.pyqtgraph.org """ -__version__ = None +__version__ = '0.9.8' ### import all the goodies and add some helper functions for easy CLI use @@ -130,56 +130,119 @@ if __version__ is None and not hasattr(sys, 'frozen') and sys.version_info[0] == ## Import almost everything to make it available from a single namespace ## don't import the more complex systems--canvas, parametertree, flowchart, dockarea ## these must be imported separately. -from . import frozenSupport -def importModules(path, globals, locals, excludes=()): - """Import all modules residing within *path*, return a dict of name: module pairs. +#from . import frozenSupport +#def importModules(path, globals, locals, excludes=()): + #"""Import all modules residing within *path*, return a dict of name: module pairs. - Note that *path* MUST be relative to the module doing the import. - """ - d = os.path.join(os.path.split(globals['__file__'])[0], path) - files = set() - for f in frozenSupport.listdir(d): - if frozenSupport.isdir(os.path.join(d, f)) and f not in ['__pycache__', 'tests']: - files.add(f) - elif f[-3:] == '.py' and f != '__init__.py': - files.add(f[:-3]) - elif f[-4:] == '.pyc' and f != '__init__.pyc': - files.add(f[:-4]) + #Note that *path* MUST be relative to the module doing the import. + #""" + #d = os.path.join(os.path.split(globals['__file__'])[0], path) + #files = set() + #for f in frozenSupport.listdir(d): + #if frozenSupport.isdir(os.path.join(d, f)) and f not in ['__pycache__', 'tests']: + #files.add(f) + #elif f[-3:] == '.py' and f != '__init__.py': + #files.add(f[:-3]) + #elif f[-4:] == '.pyc' and f != '__init__.pyc': + #files.add(f[:-4]) - mods = {} - path = path.replace(os.sep, '.') - for modName in files: - if modName in excludes: - continue - try: - if len(path) > 0: - modName = path + '.' + modName - #mod = __import__(modName, globals, locals, fromlist=['*']) - mod = __import__(modName, globals, locals, ['*'], 1) - mods[modName] = mod - except: - import traceback - traceback.print_stack() - sys.excepthook(*sys.exc_info()) - print("[Error importing module: %s]" % modName) + #mods = {} + #path = path.replace(os.sep, '.') + #for modName in files: + #if modName in excludes: + #continue + #try: + #if len(path) > 0: + #modName = path + '.' + modName + #print( "from .%s import * " % modName) + #mod = __import__(modName, globals, locals, ['*'], 1) + #mods[modName] = mod + #except: + #import traceback + #traceback.print_stack() + #sys.excepthook(*sys.exc_info()) + #print("[Error importing module: %s]" % modName) - return mods + #return mods -def importAll(path, globals, locals, excludes=()): - """Given a list of modules, import all names from each module into the global namespace.""" - mods = importModules(path, globals, locals, excludes) - for mod in mods.values(): - if hasattr(mod, '__all__'): - names = mod.__all__ - else: - names = [n for n in dir(mod) if n[0] != '_'] - for k in names: - if hasattr(mod, k): - globals[k] = getattr(mod, k) +#def importAll(path, globals, locals, excludes=()): + #"""Given a list of modules, import all names from each module into the global namespace.""" + #mods = importModules(path, globals, locals, excludes) + #for mod in mods.values(): + #if hasattr(mod, '__all__'): + #names = mod.__all__ + #else: + #names = [n for n in dir(mod) if n[0] != '_'] + #for k in names: + #if hasattr(mod, k): + #globals[k] = getattr(mod, k) -importAll('graphicsItems', globals(), locals()) -importAll('widgets', globals(), locals(), - excludes=['MatplotlibWidget', 'RawImageWidget', 'RemoteGraphicsView']) +# Dynamic imports are disabled. This causes too many problems. +#importAll('graphicsItems', globals(), locals()) +#importAll('widgets', globals(), locals(), + #excludes=['MatplotlibWidget', 'RawImageWidget', 'RemoteGraphicsView']) + +from .graphicsItems.VTickGroup import * +from .graphicsItems.GraphicsWidget import * +from .graphicsItems.ScaleBar import * +from .graphicsItems.PlotDataItem import * +from .graphicsItems.GraphItem import * +from .graphicsItems.TextItem import * +from .graphicsItems.GraphicsLayout import * +from .graphicsItems.UIGraphicsItem import * +from .graphicsItems.GraphicsObject import * +from .graphicsItems.PlotItem import * +from .graphicsItems.ROI import * +from .graphicsItems.InfiniteLine import * +from .graphicsItems.HistogramLUTItem import * +from .graphicsItems.GridItem import * +from .graphicsItems.GradientLegend import * +from .graphicsItems.GraphicsItem import * +from .graphicsItems.BarGraphItem import * +from .graphicsItems.ViewBox import * +from .graphicsItems.ArrowItem import * +from .graphicsItems.ImageItem import * +from .graphicsItems.AxisItem import * +from .graphicsItems.LabelItem import * +from .graphicsItems.CurvePoint import * +from .graphicsItems.GraphicsWidgetAnchor import * +from .graphicsItems.PlotCurveItem import * +from .graphicsItems.ButtonItem import * +from .graphicsItems.GradientEditorItem import * +from .graphicsItems.MultiPlotItem import * +from .graphicsItems.ErrorBarItem import * +from .graphicsItems.IsocurveItem import * +from .graphicsItems.LinearRegionItem import * +from .graphicsItems.FillBetweenItem import * +from .graphicsItems.LegendItem import * +from .graphicsItems.ScatterPlotItem import * +from .graphicsItems.ItemGroup import * + +from .widgets.MultiPlotWidget import * +from .widgets.ScatterPlotWidget import * +from .widgets.ColorMapWidget import * +from .widgets.FileDialog import * +from .widgets.ValueLabel import * +from .widgets.HistogramLUTWidget import * +from .widgets.CheckTable import * +from .widgets.BusyCursor import * +from .widgets.PlotWidget import * +from .widgets.ComboBox import * +from .widgets.GradientWidget import * +from .widgets.DataFilterWidget import * +from .widgets.SpinBox import * +from .widgets.JoystickButton import * +from .widgets.GraphicsLayoutWidget import * +from .widgets.TreeWidget import * +from .widgets.PathButton import * +from .widgets.VerticalLabel import * +from .widgets.FeedbackButton import * +from .widgets.ColorButton import * +from .widgets.DataTreeWidget import * +from .widgets.GraphicsView import * +from .widgets.LayoutWidget import * +from .widgets.TableWidget import * +from .widgets.ProgressDialog import * from .imageview import * from .WidgetGroup import * @@ -194,6 +257,7 @@ from .SignalProxy import * from .colormap import * from .ptime import time + ############################################################## ## PyQt and PySide both are prone to crashing on exit. ## There are two general approaches to dealing with this: @@ -292,7 +356,8 @@ def plot(*args, **kargs): dataArgs[k] = kargs[k] w = PlotWindow(**pwArgs) - w.plot(*args, **dataArgs) + if len(args) > 0 or len(dataArgs) > 0: + w.plot(*args, **dataArgs) plots.append(w) w.show() return w diff --git a/canvas/Canvas.py b/canvas/Canvas.py index 17a39c2b..d07b3428 100644 --- a/canvas/Canvas.py +++ b/canvas/Canvas.py @@ -3,29 +3,21 @@ if __name__ == '__main__': import sys, os md = os.path.dirname(os.path.abspath(__file__)) sys.path = [os.path.dirname(md), os.path.join(md, '..', '..', '..')] + sys.path - #print md - -#from pyqtgraph.GraphicsView import GraphicsView -#import pyqtgraph.graphicsItems as graphicsItems -#from pyqtgraph.PlotWidget import PlotWidget -from pyqtgraph.Qt import QtGui, QtCore, USE_PYSIDE -from pyqtgraph.graphicsItems.ROI import ROI -from pyqtgraph.graphicsItems.ViewBox import ViewBox -from pyqtgraph.graphicsItems.GridItem import GridItem +from ..Qt import QtGui, QtCore, USE_PYSIDE +from ..graphicsItems.ROI import ROI +from ..graphicsItems.ViewBox import ViewBox +from ..graphicsItems.GridItem import GridItem if USE_PYSIDE: from .CanvasTemplate_pyside import * else: from .CanvasTemplate_pyqt import * -#import DataManager import numpy as np -from pyqtgraph import debug -#import pyqtgraph as pg +from .. import debug import weakref from .CanvasManager import CanvasManager -#import items from .CanvasItem import CanvasItem, GroupCanvasItem class Canvas(QtGui.QWidget): @@ -605,4 +597,4 @@ class SelectBox(ROI): - \ No newline at end of file + diff --git a/canvas/CanvasItem.py b/canvas/CanvasItem.py index 81388cb6..a808765c 100644 --- a/canvas/CanvasItem.py +++ b/canvas/CanvasItem.py @@ -1,13 +1,13 @@ # -*- coding: utf-8 -*- -from pyqtgraph.Qt import QtGui, QtCore, QtSvg, USE_PYSIDE -from pyqtgraph.graphicsItems.ROI import ROI -import pyqtgraph as pg +from ..Qt import QtGui, QtCore, QtSvg, USE_PYSIDE +from ..graphicsItems.ROI import ROI +from .. import SRTTransform, ItemGroup if USE_PYSIDE: from . import TransformGuiTemplate_pyside as TransformGuiTemplate else: from . import TransformGuiTemplate_pyqt as TransformGuiTemplate -from pyqtgraph import debug +from .. import debug class SelectBox(ROI): def __init__(self, scalable=False, rotatable=True): @@ -96,7 +96,7 @@ class CanvasItem(QtCore.QObject): if 'transform' in self.opts: self.baseTransform = self.opts['transform'] else: - self.baseTransform = pg.SRTTransform() + self.baseTransform = SRTTransform() if 'pos' in self.opts and self.opts['pos'] is not None: self.baseTransform.translate(self.opts['pos']) if 'angle' in self.opts and self.opts['angle'] is not None: @@ -124,8 +124,8 @@ class CanvasItem(QtCore.QObject): self.itemScale = QtGui.QGraphicsScale() self._graphicsItem.setTransformations([self.itemRotation, self.itemScale]) - self.tempTransform = pg.SRTTransform() ## holds the additional transform that happens during a move - gets added to the userTransform when move is done. - self.userTransform = pg.SRTTransform() ## stores the total transform of the object + self.tempTransform = SRTTransform() ## holds the additional transform that happens during a move - gets added to the userTransform when move is done. + self.userTransform = SRTTransform() ## stores the total transform of the object self.resetUserTransform() ## now happens inside resetUserTransform -> selectBoxToItem @@ -200,7 +200,7 @@ class CanvasItem(QtCore.QObject): #flip = self.transformGui.mirrorImageCheck.isChecked() #tr = self.userTransform.saveState() - inv = pg.SRTTransform() + inv = SRTTransform() inv.scale(-1, 1) self.userTransform = self.userTransform * inv self.updateTransform() @@ -231,7 +231,7 @@ class CanvasItem(QtCore.QObject): if not self.isMovable(): return self.rotate(180.) - # inv = pg.SRTTransform() + # inv = SRTTransform() # inv.scale(-1, -1) # self.userTransform = self.userTransform * inv #flip lr/ud # s=self.updateTransform() @@ -316,7 +316,7 @@ class CanvasItem(QtCore.QObject): def resetTemporaryTransform(self): - self.tempTransform = pg.SRTTransform() ## don't use Transform.reset()--this transform might be used elsewhere. + self.tempTransform = SRTTransform() ## don't use Transform.reset()--this transform might be used elsewhere. self.updateTransform() def transform(self): @@ -368,7 +368,7 @@ class CanvasItem(QtCore.QObject): try: #self.userTranslate = pg.Point(tr['trans']) #self.userRotate = tr['rot'] - self.userTransform = pg.SRTTransform(tr) + self.userTransform = SRTTransform(tr) self.updateTransform() self.selectBoxFromUser() ## move select box to match @@ -377,7 +377,7 @@ class CanvasItem(QtCore.QObject): except: #self.userTranslate = pg.Point([0,0]) #self.userRotate = 0 - self.userTransform = pg.SRTTransform() + self.userTransform = SRTTransform() debug.printExc("Failed to load transform:") #print "set transform", self, self.userTranslate @@ -504,6 +504,6 @@ class GroupCanvasItem(CanvasItem): def __init__(self, **opts): defOpts = {'movable': False, 'scalable': False} defOpts.update(opts) - item = pg.ItemGroup() + item = ItemGroup() CanvasItem.__init__(self, item, **defOpts) diff --git a/canvas/CanvasManager.py b/canvas/CanvasManager.py index e89ec00f..28188039 100644 --- a/canvas/CanvasManager.py +++ b/canvas/CanvasManager.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -from pyqtgraph.Qt import QtCore, QtGui +from ..Qt import QtCore, QtGui if not hasattr(QtCore, 'Signal'): QtCore.Signal = QtCore.pyqtSignal import weakref diff --git a/canvas/CanvasTemplate.ui b/canvas/CanvasTemplate.ui index da032906..218cf48d 100644 --- a/canvas/CanvasTemplate.ui +++ b/canvas/CanvasTemplate.ui @@ -131,12 +131,12 @@ TreeWidget QTreeWidget -
pyqtgraph.widgets.TreeWidget
+
..widgets.TreeWidget
GraphicsView QGraphicsView -
pyqtgraph.widgets.GraphicsView
+
..widgets.GraphicsView
CanvasCombo diff --git a/canvas/CanvasTemplate_pyqt.py b/canvas/CanvasTemplate_pyqt.py index 4d1d8208..c809cb1d 100644 --- a/canvas/CanvasTemplate_pyqt.py +++ b/canvas/CanvasTemplate_pyqt.py @@ -1,9 +1,9 @@ # -*- coding: utf-8 -*- -# Form implementation generated from reading ui file './canvas/CanvasTemplate.ui' +# Form implementation generated from reading ui file './pyqtgraph/canvas/CanvasTemplate.ui' # -# Created: Sun Sep 9 14:41:30 2012 -# by: PyQt4 UI code generator 4.9.1 +# Created: Mon Dec 23 10:10:52 2013 +# by: PyQt4 UI code generator 4.10 # # WARNING! All changes made in this file will be lost! @@ -12,7 +12,16 @@ from PyQt4 import QtCore, QtGui try: _fromUtf8 = QtCore.QString.fromUtf8 except AttributeError: - _fromUtf8 = lambda s: s + def _fromUtf8(s): + return s + +try: + _encoding = QtGui.QApplication.UnicodeUTF8 + def _translate(context, text, disambig): + return QtGui.QApplication.translate(context, text, disambig, _encoding) +except AttributeError: + def _translate(context, text, disambig): + return QtGui.QApplication.translate(context, text, disambig) class Ui_Form(object): def setupUi(self, Form): @@ -85,16 +94,16 @@ class Ui_Form(object): QtCore.QMetaObject.connectSlotsByName(Form) def retranslateUi(self, Form): - Form.setWindowTitle(QtGui.QApplication.translate("Form", "Form", None, QtGui.QApplication.UnicodeUTF8)) - self.storeSvgBtn.setText(QtGui.QApplication.translate("Form", "Store SVG", None, QtGui.QApplication.UnicodeUTF8)) - self.storePngBtn.setText(QtGui.QApplication.translate("Form", "Store PNG", None, QtGui.QApplication.UnicodeUTF8)) - self.autoRangeBtn.setText(QtGui.QApplication.translate("Form", "Auto Range", None, QtGui.QApplication.UnicodeUTF8)) - self.redirectCheck.setToolTip(QtGui.QApplication.translate("Form", "Check to display all local items in a remote canvas.", None, QtGui.QApplication.UnicodeUTF8)) - self.redirectCheck.setText(QtGui.QApplication.translate("Form", "Redirect", None, QtGui.QApplication.UnicodeUTF8)) - self.resetTransformsBtn.setText(QtGui.QApplication.translate("Form", "Reset Transforms", None, QtGui.QApplication.UnicodeUTF8)) - self.mirrorSelectionBtn.setText(QtGui.QApplication.translate("Form", "Mirror Selection", None, QtGui.QApplication.UnicodeUTF8)) - self.reflectSelectionBtn.setText(QtGui.QApplication.translate("Form", "MirrorXY", None, QtGui.QApplication.UnicodeUTF8)) + Form.setWindowTitle(_translate("Form", "Form", None)) + self.storeSvgBtn.setText(_translate("Form", "Store SVG", None)) + self.storePngBtn.setText(_translate("Form", "Store PNG", None)) + self.autoRangeBtn.setText(_translate("Form", "Auto Range", None)) + self.redirectCheck.setToolTip(_translate("Form", "Check to display all local items in a remote canvas.", None)) + self.redirectCheck.setText(_translate("Form", "Redirect", None)) + self.resetTransformsBtn.setText(_translate("Form", "Reset Transforms", None)) + self.mirrorSelectionBtn.setText(_translate("Form", "Mirror Selection", None)) + self.reflectSelectionBtn.setText(_translate("Form", "MirrorXY", None)) -from pyqtgraph.widgets.GraphicsView import GraphicsView +from ..widgets.TreeWidget import TreeWidget from CanvasManager import CanvasCombo -from pyqtgraph.widgets.TreeWidget import TreeWidget +from ..widgets.GraphicsView import GraphicsView diff --git a/canvas/CanvasTemplate_pyside.py b/canvas/CanvasTemplate_pyside.py index 12afdf25..56d1ff47 100644 --- a/canvas/CanvasTemplate_pyside.py +++ b/canvas/CanvasTemplate_pyside.py @@ -1,9 +1,9 @@ # -*- coding: utf-8 -*- -# Form implementation generated from reading ui file './canvas/CanvasTemplate.ui' +# Form implementation generated from reading ui file './pyqtgraph/canvas/CanvasTemplate.ui' # -# Created: Sun Sep 9 14:41:30 2012 -# by: pyside-uic 0.2.13 running on PySide 1.1.0 +# Created: Mon Dec 23 10:10:52 2013 +# by: pyside-uic 0.2.14 running on PySide 1.1.2 # # WARNING! All changes made in this file will be lost! @@ -90,6 +90,6 @@ class Ui_Form(object): self.mirrorSelectionBtn.setText(QtGui.QApplication.translate("Form", "Mirror Selection", None, QtGui.QApplication.UnicodeUTF8)) self.reflectSelectionBtn.setText(QtGui.QApplication.translate("Form", "MirrorXY", None, QtGui.QApplication.UnicodeUTF8)) -from pyqtgraph.widgets.GraphicsView import GraphicsView +from ..widgets.TreeWidget import TreeWidget from CanvasManager import CanvasCombo -from pyqtgraph.widgets.TreeWidget import TreeWidget +from ..widgets.GraphicsView import GraphicsView diff --git a/canvas/TransformGuiTemplate_pyqt.py b/canvas/TransformGuiTemplate_pyqt.py index 1fb86d24..75c694c0 100644 --- a/canvas/TransformGuiTemplate_pyqt.py +++ b/canvas/TransformGuiTemplate_pyqt.py @@ -1,9 +1,9 @@ # -*- coding: utf-8 -*- -# Form implementation generated from reading ui file './canvas/TransformGuiTemplate.ui' +# Form implementation generated from reading ui file './pyqtgraph/canvas/TransformGuiTemplate.ui' # -# Created: Sun Sep 9 14:41:30 2012 -# by: PyQt4 UI code generator 4.9.1 +# Created: Mon Dec 23 10:10:52 2013 +# by: PyQt4 UI code generator 4.10 # # WARNING! All changes made in this file will be lost! @@ -12,7 +12,16 @@ from PyQt4 import QtCore, QtGui try: _fromUtf8 = QtCore.QString.fromUtf8 except AttributeError: - _fromUtf8 = lambda s: s + def _fromUtf8(s): + return s + +try: + _encoding = QtGui.QApplication.UnicodeUTF8 + def _translate(context, text, disambig): + return QtGui.QApplication.translate(context, text, disambig, _encoding) +except AttributeError: + def _translate(context, text, disambig): + return QtGui.QApplication.translate(context, text, disambig) class Ui_Form(object): def setupUi(self, Form): @@ -51,10 +60,10 @@ class Ui_Form(object): QtCore.QMetaObject.connectSlotsByName(Form) def retranslateUi(self, Form): - Form.setWindowTitle(QtGui.QApplication.translate("Form", "Form", None, QtGui.QApplication.UnicodeUTF8)) - self.translateLabel.setText(QtGui.QApplication.translate("Form", "Translate:", None, QtGui.QApplication.UnicodeUTF8)) - self.rotateLabel.setText(QtGui.QApplication.translate("Form", "Rotate:", None, QtGui.QApplication.UnicodeUTF8)) - self.scaleLabel.setText(QtGui.QApplication.translate("Form", "Scale:", None, QtGui.QApplication.UnicodeUTF8)) - self.mirrorImageBtn.setText(QtGui.QApplication.translate("Form", "Mirror", None, QtGui.QApplication.UnicodeUTF8)) - self.reflectImageBtn.setText(QtGui.QApplication.translate("Form", "Reflect", None, QtGui.QApplication.UnicodeUTF8)) + Form.setWindowTitle(_translate("Form", "Form", None)) + self.translateLabel.setText(_translate("Form", "Translate:", None)) + self.rotateLabel.setText(_translate("Form", "Rotate:", None)) + self.scaleLabel.setText(_translate("Form", "Scale:", None)) + self.mirrorImageBtn.setText(_translate("Form", "Mirror", None)) + self.reflectImageBtn.setText(_translate("Form", "Reflect", None)) diff --git a/canvas/TransformGuiTemplate_pyside.py b/canvas/TransformGuiTemplate_pyside.py index 47b23faa..bce7b511 100644 --- a/canvas/TransformGuiTemplate_pyside.py +++ b/canvas/TransformGuiTemplate_pyside.py @@ -1,9 +1,9 @@ # -*- coding: utf-8 -*- -# Form implementation generated from reading ui file './canvas/TransformGuiTemplate.ui' +# Form implementation generated from reading ui file './pyqtgraph/canvas/TransformGuiTemplate.ui' # -# Created: Sun Sep 9 14:41:30 2012 -# by: pyside-uic 0.2.13 running on PySide 1.1.0 +# Created: Mon Dec 23 10:10:52 2013 +# by: pyside-uic 0.2.14 running on PySide 1.1.2 # # WARNING! All changes made in this file will be lost! diff --git a/colormap.py b/colormap.py index d6169209..cb1e882e 100644 --- a/colormap.py +++ b/colormap.py @@ -1,6 +1,6 @@ import numpy as np import scipy.interpolate -from pyqtgraph.Qt import QtGui, QtCore +from .Qt import QtGui, QtCore class ColorMap(object): """ diff --git a/console/CmdInput.py b/console/CmdInput.py index 3e9730d6..24a01e89 100644 --- a/console/CmdInput.py +++ b/console/CmdInput.py @@ -1,5 +1,5 @@ -from pyqtgraph.Qt import QtCore, QtGui -from pyqtgraph.python2_3 import asUnicode +from ..Qt import QtCore, QtGui +from ..python2_3 import asUnicode class CmdInput(QtGui.QLineEdit): diff --git a/console/Console.py b/console/Console.py index 982c2424..0cbd2c3e 100644 --- a/console/Console.py +++ b/console/Console.py @@ -1,14 +1,14 @@ -from pyqtgraph.Qt import QtCore, QtGui, USE_PYSIDE +from ..Qt import QtCore, QtGui, USE_PYSIDE import sys, re, os, time, traceback, subprocess -import pyqtgraph as pg if USE_PYSIDE: from . import template_pyside as template else: from . import template_pyqt as template -import pyqtgraph.exceptionHandling as exceptionHandling +from .. import exceptionHandling as exceptionHandling import pickle +from .. import getConfigOption class ConsoleWidget(QtGui.QWidget): """ @@ -281,7 +281,7 @@ class ConsoleWidget(QtGui.QWidget): def stackItemDblClicked(self, item): editor = self.editor if editor is None: - editor = pg.getConfigOption('editorCommand') + editor = getConfigOption('editorCommand') if editor is None: return tb = self.currentFrame() diff --git a/console/template_pyqt.py b/console/template_pyqt.py index 89ee6cff..e0852c93 100644 --- a/console/template_pyqt.py +++ b/console/template_pyqt.py @@ -1,9 +1,9 @@ # -*- coding: utf-8 -*- -# Form implementation generated from reading ui file './console/template.ui' +# Form implementation generated from reading ui file './pyqtgraph/console/template.ui' # -# Created: Sun Sep 9 14:41:30 2012 -# by: PyQt4 UI code generator 4.9.1 +# Created: Mon Dec 23 10:10:53 2013 +# by: PyQt4 UI code generator 4.10 # # WARNING! All changes made in this file will be lost! @@ -12,7 +12,16 @@ from PyQt4 import QtCore, QtGui try: _fromUtf8 = QtCore.QString.fromUtf8 except AttributeError: - _fromUtf8 = lambda s: s + def _fromUtf8(s): + return s + +try: + _encoding = QtGui.QApplication.UnicodeUTF8 + def _translate(context, text, disambig): + return QtGui.QApplication.translate(context, text, disambig, _encoding) +except AttributeError: + def _translate(context, text, disambig): + return QtGui.QApplication.translate(context, text, disambig) class Ui_Form(object): def setupUi(self, Form): @@ -97,15 +106,15 @@ class Ui_Form(object): QtCore.QMetaObject.connectSlotsByName(Form) def retranslateUi(self, Form): - Form.setWindowTitle(QtGui.QApplication.translate("Form", "Console", None, QtGui.QApplication.UnicodeUTF8)) - self.historyBtn.setText(QtGui.QApplication.translate("Form", "History..", None, QtGui.QApplication.UnicodeUTF8)) - self.exceptionBtn.setText(QtGui.QApplication.translate("Form", "Exceptions..", None, QtGui.QApplication.UnicodeUTF8)) - self.exceptionGroup.setTitle(QtGui.QApplication.translate("Form", "Exception Handling", None, QtGui.QApplication.UnicodeUTF8)) - self.catchAllExceptionsBtn.setText(QtGui.QApplication.translate("Form", "Show All Exceptions", None, QtGui.QApplication.UnicodeUTF8)) - self.catchNextExceptionBtn.setText(QtGui.QApplication.translate("Form", "Show Next Exception", None, QtGui.QApplication.UnicodeUTF8)) - self.onlyUncaughtCheck.setText(QtGui.QApplication.translate("Form", "Only Uncaught Exceptions", None, QtGui.QApplication.UnicodeUTF8)) - self.runSelectedFrameCheck.setText(QtGui.QApplication.translate("Form", "Run commands in selected stack frame", None, QtGui.QApplication.UnicodeUTF8)) - self.exceptionInfoLabel.setText(QtGui.QApplication.translate("Form", "Exception Info", None, QtGui.QApplication.UnicodeUTF8)) - self.clearExceptionBtn.setText(QtGui.QApplication.translate("Form", "Clear Exception", None, QtGui.QApplication.UnicodeUTF8)) + Form.setWindowTitle(_translate("Form", "Console", None)) + self.historyBtn.setText(_translate("Form", "History..", None)) + self.exceptionBtn.setText(_translate("Form", "Exceptions..", None)) + self.exceptionGroup.setTitle(_translate("Form", "Exception Handling", None)) + self.catchAllExceptionsBtn.setText(_translate("Form", "Show All Exceptions", None)) + self.catchNextExceptionBtn.setText(_translate("Form", "Show Next Exception", None)) + self.onlyUncaughtCheck.setText(_translate("Form", "Only Uncaught Exceptions", None)) + self.runSelectedFrameCheck.setText(_translate("Form", "Run commands in selected stack frame", None)) + self.exceptionInfoLabel.setText(_translate("Form", "Exception Info", None)) + self.clearExceptionBtn.setText(_translate("Form", "Clear Exception", None)) from .CmdInput import CmdInput diff --git a/console/template_pyside.py b/console/template_pyside.py index 0493a0fe..2db8ed95 100644 --- a/console/template_pyside.py +++ b/console/template_pyside.py @@ -1,9 +1,9 @@ # -*- coding: utf-8 -*- -# Form implementation generated from reading ui file './console/template.ui' +# Form implementation generated from reading ui file './pyqtgraph/console/template.ui' # -# Created: Sun Sep 9 14:41:30 2012 -# by: pyside-uic 0.2.13 running on PySide 1.1.0 +# Created: Mon Dec 23 10:10:53 2013 +# by: pyside-uic 0.2.14 running on PySide 1.1.2 # # WARNING! All changes made in this file will be lost! diff --git a/debug.py b/debug.py index a175be9c..685780d4 100644 --- a/debug.py +++ b/debug.py @@ -5,6 +5,8 @@ Copyright 2010 Luke Campagnola Distributed under MIT/X11 license. See license.txt for more infomation. """ +from __future__ import print_function + import sys, traceback, time, gc, re, types, weakref, inspect, os, cProfile from . import ptime from numpy import ndarray @@ -365,85 +367,128 @@ class GarbageWatcher(object): return self.objs[item] -class Profiler: + + +class Profiler(object): """Simple profiler allowing measurement of multiple time intervals. - Arguments: - msg: message to print at start and finish of profiling - disabled: If true, profiler does nothing (so you can leave it in place) - delayed: If true, all messages are printed after call to finish() - (this can result in more accurate time step measurements) - globalDelay: if True, all nested profilers delay printing until the top level finishes - + + By default, profilers are disabled. To enable profiling, set the + environment variable `PYQTGRAPHPROFILE` to a comma-separated list of + fully-qualified names of profiled functions. + + Calling a profiler registers a message (defaulting to an increasing + counter) that contains the time elapsed since the last call. When the + profiler is about to be garbage-collected, the messages are passed to the + outer profiler if one is running, or printed to stdout otherwise. + + If `delayed` is set to False, messages are immediately printed instead. + Example: - prof = Profiler('Function') - ... do stuff ... - prof.mark('did stuff') - ... do other stuff ... - prof.mark('did other stuff') - prof.finish() + def function(...): + profiler = Profiler() + ... do stuff ... + profiler('did stuff') + ... do other stuff ... + profiler('did other stuff') + # profiler is garbage-collected and flushed at function end + + If this function is a method of class C, setting `PYQTGRAPHPROFILE` to + "C.function" (without the module name) will enable this profiler. + + For regular functions, use the qualified name of the function, stripping + only the initial "pyqtgraph." prefix from the module. """ - depth = 0 - msgs = [] + + _profilers = os.environ.get("PYQTGRAPHPROFILE", "") + _depth = 0 + _msgs = [] - def __init__(self, msg="Profiler", disabled=False, delayed=True, globalDelay=True): - self.disabled = disabled - if disabled: - return - - self.markCount = 0 - self.finished = False - self.depth = Profiler.depth - Profiler.depth += 1 - if not globalDelay: - self.msgs = [] - self.delayed = delayed - self.msg = " "*self.depth + msg - msg2 = self.msg + " >>> Started" - if self.delayed: - self.msgs.append(msg2) - else: - print(msg2) - self.t0 = ptime.time() - self.t1 = self.t0 + class DisabledProfiler(object): + def __init__(self, *args, **kwds): + pass + def __call__(self, *args): + pass + def finish(self): + pass + def mark(self, msg=None): + pass + _disabledProfiler = DisabledProfiler() - def mark(self, msg=None): - if self.disabled: - return - + + if _profilers: + _profilers = _profilers.split(",") + def __new__(cls, msg=None, disabled='env', delayed=True): + """Optionally create a new profiler based on caller's qualname. + """ + if disabled is True: + return cls._disabledProfiler + + # determine the qualified name of the caller function + caller_frame = sys._getframe(1) + try: + caller_object_type = type(caller_frame.f_locals["self"]) + except KeyError: # we are in a regular function + qualifier = caller_frame.f_globals["__name__"].split(".", 1)[1] + else: # we are in a method + qualifier = caller_object_type.__name__ + func_qualname = qualifier + "." + caller_frame.f_code.co_name + if func_qualname not in cls._profilers: # don't do anything + return cls._disabledProfiler + # create an actual profiling object + cls._depth += 1 + obj = super(Profiler, cls).__new__(cls) + obj._name = msg or func_qualname + obj._delayed = delayed + obj._markCount = 0 + obj._finished = False + obj._firstTime = obj._lastTime = ptime.time() + obj._newMsg("> Entering " + obj._name) + return obj + else: + def __new__(cls, delayed=True): + return lambda msg=None: None + + def __call__(self, msg=None): + """Register or print a new message with timing information. + """ if msg is None: - msg = str(self.markCount) - self.markCount += 1 + msg = str(self._markCount) + self._markCount += 1 + newTime = ptime.time() + self._newMsg(" %s: %0.4f ms", + msg, (newTime - self._lastTime) * 1000) + self._lastTime = newTime - t1 = ptime.time() - msg2 = " "+self.msg+" "+msg+" "+"%gms" % ((t1-self.t1)*1000) - if self.delayed: - self.msgs.append(msg2) + def mark(self, msg=None): + self(msg) + + def _newMsg(self, msg, *args): + msg = " " * (self._depth - 1) + msg + if self._delayed: + self._msgs.append((msg, args)) else: - print(msg2) - self.t1 = ptime.time() ## don't measure time it took to print - + print(msg % args) + + def __del__(self): + self.finish() + def finish(self, msg=None): - if self.disabled or self.finished: - return - + """Add a final message; flush the message list if no parent profiler. + """ + if self._finished: + return + self._finished = True if msg is not None: - self.mark(msg) - t1 = ptime.time() - msg = self.msg + ' <<< Finished, total time: %gms' % ((t1-self.t0)*1000) - if self.delayed: - self.msgs.append(msg) - if self.depth == 0: - for line in self.msgs: - print(line) - Profiler.msgs = [] - else: - print(msg) - Profiler.depth = self.depth - self.finished = True - - + self(msg) + self._newMsg("< Exiting %s, total time: %0.4f ms", + self._name, (ptime.time() - self._firstTime) * 1000) + type(self)._depth -= 1 + if self._depth < 1 and self._msgs: + print("\n".join([m[0]%m[1] for m in self._msgs])) + type(self)._msgs = [] + def profile(code, name='profile_run', sort='cumulative', num=30): """Common-use for cProfile""" cProfile.run(code, name) @@ -943,4 +988,4 @@ class PrintDetector(object): traceback.print_stack() def flush(self): - self.stdout.flush() \ No newline at end of file + self.stdout.flush() diff --git a/dockarea/Container.py b/dockarea/Container.py index 83610937..277375f3 100644 --- a/dockarea/Container.py +++ b/dockarea/Container.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -from pyqtgraph.Qt import QtCore, QtGui +from ..Qt import QtCore, QtGui import weakref class Container(object): @@ -241,6 +241,13 @@ class TContainer(Container, QtGui.QWidget): else: w.label.setDim(True) + def raiseDock(self, dock): + """Move *dock* to the top of the stack""" + self.stack.currentWidget().label.setDim(True) + self.stack.setCurrentWidget(dock) + dock.label.setDim(False) + + def type(self): return 'tab' diff --git a/dockarea/Dock.py b/dockarea/Dock.py index 414980ac..f83397c7 100644 --- a/dockarea/Dock.py +++ b/dockarea/Dock.py @@ -1,7 +1,7 @@ -from pyqtgraph.Qt import QtCore, QtGui +from ..Qt import QtCore, QtGui from .DockDrop import * -from pyqtgraph.widgets.VerticalLabel import VerticalLabel +from ..widgets.VerticalLabel import VerticalLabel class Dock(QtGui.QWidget, DockDrop): @@ -208,6 +208,11 @@ class Dock(QtGui.QWidget, DockDrop): self.moveLabel = False self.setOrientation(force=True) + + def raiseDock(self): + """If this Dock is stacked underneath others, raise it to the top.""" + self.container().raiseDock(self) + def close(self): """Remove this dock from the DockArea it lives inside.""" diff --git a/dockarea/DockArea.py b/dockarea/DockArea.py index 882b29a3..5c367f0b 100644 --- a/dockarea/DockArea.py +++ b/dockarea/DockArea.py @@ -1,9 +1,9 @@ # -*- coding: utf-8 -*- -from pyqtgraph.Qt import QtCore, QtGui +from ..Qt import QtCore, QtGui from .Container import * from .DockDrop import * from .Dock import Dock -import pyqtgraph.debug as debug +from .. import debug as debug import weakref ## TODO: diff --git a/dockarea/DockDrop.py b/dockarea/DockDrop.py index acab28cd..bd364f50 100644 --- a/dockarea/DockDrop.py +++ b/dockarea/DockDrop.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -from pyqtgraph.Qt import QtCore, QtGui +from ..Qt import QtCore, QtGui class DockDrop(object): """Provides dock-dropping methods""" diff --git a/exporters/CSVExporter.py b/exporters/CSVExporter.py index 0439fc35..b0cf5af5 100644 --- a/exporters/CSVExporter.py +++ b/exporters/CSVExporter.py @@ -1,8 +1,7 @@ -import pyqtgraph as pg -from pyqtgraph.Qt import QtGui, QtCore +from ..Qt import QtGui, QtCore from .Exporter import Exporter -from pyqtgraph.parametertree import Parameter - +from ..parametertree import Parameter +from .. import PlotItem __all__ = ['CSVExporter'] @@ -22,7 +21,7 @@ class CSVExporter(Exporter): def export(self, fileName=None): - if not isinstance(self.item, pg.PlotItem): + if not isinstance(self.item, PlotItem): raise Exception("Must have a PlotItem selected for CSV export.") if fileName is None: @@ -33,8 +32,14 @@ class CSVExporter(Exporter): data = [] header = [] for c in self.item.curves: - data.append(c.getData()) - header.extend(['x', 'y']) + cd = c.getData() + if cd[0] is None: + continue + data.append(cd) + name = '' + if hasattr(c, 'implements') and c.implements('plotData') and c.name() is not None: + name = c.name().replace('"', '""') + '_' + header.extend(['"'+name+'x"', '"'+name+'y"']) if self.params['separator'] == 'comma': sep = ',' @@ -44,7 +49,7 @@ class CSVExporter(Exporter): fd.write(sep.join(header) + '\n') i = 0 numFormat = '%%0.%dg' % self.params['precision'] - numRows = reduce(max, [len(d[0]) for d in data]) + numRows = max([len(d[0]) for d in data]) for i in range(numRows): for d in data: if i < len(d[0]): @@ -54,6 +59,6 @@ class CSVExporter(Exporter): fd.write('\n') fd.close() - +CSVExporter.register() diff --git a/exporters/Exporter.py b/exporters/Exporter.py index 6371a3b9..64a25294 100644 --- a/exporters/Exporter.py +++ b/exporters/Exporter.py @@ -1,7 +1,7 @@ -from pyqtgraph.widgets.FileDialog import FileDialog -import pyqtgraph as pg -from pyqtgraph.Qt import QtGui, QtCore, QtSvg -from pyqtgraph.python2_3 import asUnicode +from ..widgets.FileDialog import FileDialog +from ..Qt import QtGui, QtCore, QtSvg +from ..python2_3 import asUnicode +from ..GraphicsScene import GraphicsScene import os, re LastExportDirectory = None @@ -11,6 +11,14 @@ class Exporter(object): Abstract class used for exporting graphics to file / printer / whatever. """ allowCopy = False # subclasses set this to True if they can use the copy buffer + Exporters = [] + + @classmethod + def register(cls): + """ + Used to register Exporter classes to appear in the export dialog. + """ + Exporter.Exporters.append(cls) def __init__(self, item): """ @@ -20,9 +28,6 @@ class Exporter(object): object.__init__(self) self.item = item - #def item(self): - #return self.item - def parameters(self): """Return the parameters used to configure this exporter.""" raise Exception("Abstract method must be overridden in subclass.") @@ -72,20 +77,20 @@ class Exporter(object): self.export(fileName=fileName, **self.fileDialog.opts) def getScene(self): - if isinstance(self.item, pg.GraphicsScene): + if isinstance(self.item, GraphicsScene): return self.item else: return self.item.scene() def getSourceRect(self): - if isinstance(self.item, pg.GraphicsScene): + if isinstance(self.item, GraphicsScene): w = self.item.getViewWidget() return w.viewportTransform().inverted()[0].mapRect(w.rect()) else: return self.item.sceneBoundingRect() def getTargetRect(self): - if isinstance(self.item, pg.GraphicsScene): + if isinstance(self.item, GraphicsScene): return self.item.getViewWidget().rect() else: return self.item.mapRectToDevice(self.item.boundingRect()) @@ -131,45 +136,4 @@ class Exporter(object): return preItems + rootItem + postItems def render(self, painter, targetRect, sourceRect, item=None): - - #if item is None: - #item = self.item - #preItems = [] - #postItems = [] - #if isinstance(item, QtGui.QGraphicsScene): - #childs = [i for i in item.items() if i.parentItem() is None] - #rootItem = [] - #else: - #childs = item.childItems() - #rootItem = [item] - #childs.sort(lambda a,b: cmp(a.zValue(), b.zValue())) - #while len(childs) > 0: - #ch = childs.pop(0) - #if int(ch.flags() & ch.ItemStacksBehindParent) > 0 or (ch.zValue() < 0 and int(ch.flags() & ch.ItemNegativeZStacksBehindParent) > 0): - #preItems.extend(tree) - #else: - #postItems.extend(tree) - - #for ch in preItems: - #self.render(painter, sourceRect, targetRect, item=ch) - ### paint root here - #for ch in postItems: - #self.render(painter, sourceRect, targetRect, item=ch) - - self.getScene().render(painter, QtCore.QRectF(targetRect), QtCore.QRectF(sourceRect)) - - #def writePs(self, fileName=None, item=None): - #if fileName is None: - #self.fileSaveDialog(self.writeSvg, filter="PostScript (*.ps)") - #return - #if item is None: - #item = self - #printer = QtGui.QPrinter(QtGui.QPrinter.HighResolution) - #printer.setOutputFileName(fileName) - #painter = QtGui.QPainter(printer) - #self.render(painter) - #painter.end() - - #def writeToPrinter(self): - #pass diff --git a/exporters/ImageExporter.py b/exporters/ImageExporter.py index 9fb77e2a..c8abb02b 100644 --- a/exporters/ImageExporter.py +++ b/exporters/ImageExporter.py @@ -1,7 +1,7 @@ from .Exporter import Exporter -from pyqtgraph.parametertree import Parameter -from pyqtgraph.Qt import QtGui, QtCore, QtSvg, USE_PYSIDE -import pyqtgraph as pg +from ..parametertree import Parameter +from ..Qt import QtGui, QtCore, QtSvg, USE_PYSIDE\ +from .. import functions as fn import numpy as np __all__ = ['ImageExporter'] @@ -73,7 +73,7 @@ class ImageExporter(Exporter): bg[:,:,1] = color.green() bg[:,:,2] = color.red() bg[:,:,3] = color.alpha() - self.png = pg.makeQImage(bg, alpha=True) + self.png = fn.makeQImage(bg, alpha=True) ## set resolution of image: origTargetRect = self.getTargetRect() @@ -98,4 +98,5 @@ class ImageExporter(Exporter): else: self.png.save(fileName) +ImageExporter.register() \ No newline at end of file diff --git a/exporters/Matplotlib.py b/exporters/Matplotlib.py index 76f878d2..c2980b49 100644 --- a/exporters/Matplotlib.py +++ b/exporters/Matplotlib.py @@ -1,7 +1,7 @@ -import pyqtgraph as pg -from pyqtgraph.Qt import QtGui, QtCore +from ..Qt import QtGui, QtCore from .Exporter import Exporter - +from .. import PlotItem +from .. import functions as fn __all__ = ['MatplotlibExporter'] @@ -17,7 +17,7 @@ class MatplotlibExporter(Exporter): def export(self, fileName=None): - if isinstance(self.item, pg.PlotItem): + if isinstance(self.item, PlotItem): mpw = MatplotlibWindow() MatplotlibExporter.windows.append(mpw) fig = mpw.getFigure() @@ -29,23 +29,23 @@ class MatplotlibExporter(Exporter): for item in self.item.curves: x, y = item.getData() opts = item.opts - pen = pg.mkPen(opts['pen']) + pen = fn.mkPen(opts['pen']) if pen.style() == QtCore.Qt.NoPen: linestyle = '' else: linestyle = '-' - color = tuple([c/255. for c in pg.colorTuple(pen.color())]) + color = tuple([c/255. for c in fn.colorTuple(pen.color())]) symbol = opts['symbol'] if symbol == 't': symbol = '^' - symbolPen = pg.mkPen(opts['symbolPen']) - symbolBrush = pg.mkBrush(opts['symbolBrush']) - markeredgecolor = tuple([c/255. for c in pg.colorTuple(symbolPen.color())]) - markerfacecolor = tuple([c/255. for c in pg.colorTuple(symbolBrush.color())]) + symbolPen = fn.mkPen(opts['symbolPen']) + symbolBrush = fn.mkBrush(opts['symbolBrush']) + markeredgecolor = tuple([c/255. for c in fn.colorTuple(symbolPen.color())]) + markerfacecolor = tuple([c/255. for c in fn.colorTuple(symbolBrush.color())]) if opts['fillLevel'] is not None and opts['fillBrush'] is not None: - fillBrush = pg.mkBrush(opts['fillBrush']) - fillcolor = tuple([c/255. for c in pg.colorTuple(fillBrush.color())]) + fillBrush = fn.mkBrush(opts['fillBrush']) + fillcolor = tuple([c/255. for c in fn.colorTuple(fillBrush.color())]) ax.fill_between(x=x, y1=y, y2=opts['fillLevel'], facecolor=fillcolor) ax.plot(x, y, marker=symbol, color=color, linewidth=pen.width(), linestyle=linestyle, markeredgecolor=markeredgecolor, markerfacecolor=markerfacecolor) @@ -57,11 +57,12 @@ class MatplotlibExporter(Exporter): else: raise Exception("Matplotlib export currently only works with plot items") +MatplotlibExporter.register() class MatplotlibWindow(QtGui.QMainWindow): def __init__(self): - import pyqtgraph.widgets.MatplotlibWidget + from .. import widgets.MatplotlibWidget QtGui.QMainWindow.__init__(self) self.mpl = pyqtgraph.widgets.MatplotlibWidget.MatplotlibWidget() self.setCentralWidget(self.mpl) @@ -72,3 +73,5 @@ class MatplotlibWindow(QtGui.QMainWindow): def closeEvent(self, ev): MatplotlibExporter.windows.remove(self) + + diff --git a/exporters/PrintExporter.py b/exporters/PrintExporter.py index 5b31b45d..3e2d45fa 100644 --- a/exporters/PrintExporter.py +++ b/exporters/PrintExporter.py @@ -1,6 +1,6 @@ from .Exporter import Exporter -from pyqtgraph.parametertree import Parameter -from pyqtgraph.Qt import QtGui, QtCore, QtSvg +from ..parametertree import Parameter +from ..Qt import QtGui, QtCore, QtSvg import re __all__ = ['PrintExporter'] @@ -63,3 +63,6 @@ class PrintExporter(Exporter): finally: self.setExportMode(False) painter.end() + + +#PrintExporter.register() diff --git a/exporters/SVGExporter.py b/exporters/SVGExporter.py index 62b49d30..4a02965b 100644 --- a/exporters/SVGExporter.py +++ b/exporters/SVGExporter.py @@ -1,8 +1,9 @@ from .Exporter import Exporter -from pyqtgraph.python2_3 import asUnicode -from pyqtgraph.parametertree import Parameter -from pyqtgraph.Qt import QtGui, QtCore, QtSvg -import pyqtgraph as pg +from ..python2_3 import asUnicode +from ..parametertree import Parameter +from ..Qt import QtGui, QtCore, QtSvg +from .. import debug +from .. import functions as fn import re import xml.dom.minidom as xml import numpy as np @@ -156,7 +157,7 @@ def _generateItemSvg(item, nodes=None, root=None): ## ## Both 2 and 3 can be addressed by drawing all items in world coordinates. - prof = pg.debug.Profiler('generateItemSvg %s' % str(item), disabled=True) + profiler = debug.Profiler() if nodes is None: ## nodes maps all node IDs to their XML element. ## this allows us to ensure all elements receive unique names. @@ -196,17 +197,12 @@ def _generateItemSvg(item, nodes=None, root=None): tr2 = QtGui.QTransform() tr2.translate(-rootPos.x(), -rootPos.y()) tr = tr * tr2 - #print item, pg.SRTTransform(tr) - #tr.translate(item.pos().x(), item.pos().y()) - #tr = tr * item.transform() 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() @@ -235,12 +231,12 @@ def _generateItemSvg(item, nodes=None, root=None): print(doc.toxml()) raise - prof.mark('render') + profiler('render') ## Get rid of group transformation matrices by applying ## transformation to inner coordinates correctCoordinates(g1, item) - prof.mark('correct') + profiler('correct') ## 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) @@ -290,7 +286,7 @@ def _generateItemSvg(item, nodes=None, root=None): childGroup = g1.ownerDocument.createElement('g') childGroup.setAttribute('clip-path', 'url(#%s)' % clip) g1.appendChild(childGroup) - prof.mark('clipping') + profiler('clipping') ## Add all child items as sub-elements. childs.sort(key=lambda c: c.zValue()) @@ -299,8 +295,7 @@ def _generateItemSvg(item, nodes=None, root=None): if cg is None: continue childGroup.appendChild(cg) ### this isn't quite right--some items draw below their parent (good enough for now) - prof.mark('children') - prof.finish() + profiler('children') return g1 def correctCoordinates(node, item): @@ -351,7 +346,7 @@ def correctCoordinates(node, item): if ch.tagName == 'polyline': removeTransform = True coords = np.array([[float(a) for a in c.split(',')] for c in ch.getAttribute('points').strip().split(' ')]) - coords = pg.transformCoordinates(tr, coords, transpose=True) + coords = fn.transformCoordinates(tr, coords, transpose=True) ch.setAttribute('points', ' '.join([','.join([str(a) for a in c]) for c in coords])) elif ch.tagName == 'path': removeTransform = True @@ -366,7 +361,7 @@ def correctCoordinates(node, item): x = x[1:] else: t = '' - nc = pg.transformCoordinates(tr, np.array([[float(x),float(y)]]), transpose=True) + nc = fn.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': @@ -376,7 +371,7 @@ def correctCoordinates(node, item): #[float(ch.getAttribute('x')), float(ch.getAttribute('y'))], #[float(ch.getAttribute('font-size')), 0], #[0,0]]) - #c = pg.transformCoordinates(tr, c, transpose=True) + #c = fn.transformCoordinates(tr, c, transpose=True) #ch.setAttribute('x', str(c[0,0])) #ch.setAttribute('y', str(c[0,1])) #fs = c[1]-c[2] @@ -398,13 +393,17 @@ def correctCoordinates(node, 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) + s = fn.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') + +SVGExporter.register() + + def itemTransform(item, root): ## Return the transformation mapping item to root ## (actually to parent coordinate system of root) @@ -440,35 +439,9 @@ def itemTransform(item, root): 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. diff --git a/exporters/__init__.py b/exporters/__init__.py index 3f3c1f1d..8be1c3b6 100644 --- a/exporters/__init__.py +++ b/exporters/__init__.py @@ -1,27 +1,11 @@ -Exporters = [] -from pyqtgraph import importModules -#from .. import frozenSupport -import os -d = os.path.split(__file__)[0] -#files = [] -#for f in frozenSupport.listdir(d): - #if frozenSupport.isdir(os.path.join(d, f)) and f != '__pycache__': - #files.append(f) - #elif f[-3:] == '.py' and f not in ['__init__.py', 'Exporter.py']: - #files.append(f[:-3]) - -#for modName in files: - #mod = __import__(modName, globals(), locals(), fromlist=['*']) -for mod in importModules('', globals(), locals(), excludes=['Exporter']).values(): - if hasattr(mod, '__all__'): - names = mod.__all__ - else: - names = [n for n in dir(mod) if n[0] != '_'] - for k in names: - if hasattr(mod, k): - Exporters.append(getattr(mod, k)) +from .Exporter import Exporter +from .ImageExporter import * +from .SVGExporter import * +from .Matplotlib import * +from .CSVExporter import * +from .PrintExporter import * def listExporters(): - return Exporters[:] + return Exporter.Exporters[:] diff --git a/flowchart/Flowchart.py b/flowchart/Flowchart.py index 81f9e163..8d1ea4ce 100644 --- a/flowchart/Flowchart.py +++ b/flowchart/Flowchart.py @@ -1,8 +1,9 @@ # -*- coding: utf-8 -*- -from pyqtgraph.Qt import QtCore, QtGui, USE_PYSIDE +from ..Qt import QtCore, QtGui, USE_PYSIDE from .Node import * -from pyqtgraph.pgcollections import OrderedDict -from pyqtgraph.widgets.TreeWidget import * +from ..pgcollections import OrderedDict +from ..widgets.TreeWidget import * +from .. import FileDialog, DataTreeWidget ## pyside and pyqt use incompatible ui files. if USE_PYSIDE: @@ -14,11 +15,10 @@ else: from .Terminal import Terminal from numpy import ndarray -from . import library -from pyqtgraph.debug import printExc -import pyqtgraph.configfile as configfile -import pyqtgraph.dockarea as dockarea -import pyqtgraph as pg +from .library import LIBRARY +from ..debug import printExc +from .. import configfile as configfile +from .. import dockarea as dockarea from . import FlowchartGraphicsView def strDict(d): @@ -67,7 +67,8 @@ class Flowchart(Node): sigChartLoaded = QtCore.Signal() sigStateChanged = QtCore.Signal() - def __init__(self, terminals=None, name=None, filePath=None): + def __init__(self, terminals=None, name=None, filePath=None, library=None): + self.library = library or LIBRARY if name is None: name = "Flowchart" if terminals is None: @@ -105,6 +106,10 @@ class Flowchart(Node): for name, opts in terminals.items(): self.addTerminal(name, **opts) + def setLibrary(self, lib): + self.library = lib + self.widget().chartWidget.buildMenu() + def setInput(self, **args): """Set the input values of the flowchart. This will automatically propagate the new values throughout the flowchart, (possibly) causing the output to change. @@ -194,7 +199,7 @@ class Flowchart(Node): break n += 1 - node = library.getNodeType(nodeType)(name) + node = self.library.getNodeType(nodeType)(name) self.addNode(node, name, pos) return node @@ -532,7 +537,7 @@ class Flowchart(Node): startDir = self.filePath if startDir is None: startDir = '.' - self.fileDialog = pg.FileDialog(None, "Load Flowchart..", startDir, "Flowchart (*.fc)") + self.fileDialog = FileDialog(None, "Load Flowchart..", startDir, "Flowchart (*.fc)") #self.fileDialog.setFileMode(QtGui.QFileDialog.AnyFile) #self.fileDialog.setAcceptMode(QtGui.QFileDialog.AcceptSave) self.fileDialog.show() @@ -553,7 +558,7 @@ class Flowchart(Node): startDir = self.filePath if startDir is None: startDir = '.' - self.fileDialog = pg.FileDialog(None, "Save Flowchart..", startDir, "Flowchart (*.fc)") + self.fileDialog = FileDialog(None, "Save Flowchart..", startDir, "Flowchart (*.fc)") #self.fileDialog.setFileMode(QtGui.QFileDialog.AnyFile) self.fileDialog.setAcceptMode(QtGui.QFileDialog.AcceptSave) #self.fileDialog.setDirectory(startDir) @@ -816,7 +821,7 @@ class FlowchartWidget(dockarea.DockArea): self.selDescLabel = QtGui.QLabel() self.selNameLabel = QtGui.QLabel() self.selDescLabel.setWordWrap(True) - self.selectedTree = pg.DataTreeWidget() + self.selectedTree = DataTreeWidget() #self.selectedTree.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAsNeeded) #self.selInfoLayout.addWidget(self.selNameLabel) self.selInfoLayout.addWidget(self.selDescLabel) @@ -846,13 +851,13 @@ class FlowchartWidget(dockarea.DockArea): self.nodeMenu.triggered.disconnect(self.nodeMenuTriggered) self.nodeMenu = None self.subMenus = [] - library.loadLibrary(reloadLibs=True) + self.chart.library.reload() self.buildMenu() def buildMenu(self, pos=None): self.nodeMenu = QtGui.QMenu() self.subMenus = [] - for section, nodes in library.getNodeTree().items(): + for section, nodes in self.chart.library.getNodeTree().items(): menu = QtGui.QMenu(section) self.nodeMenu.addMenu(menu) for name in nodes: diff --git a/flowchart/FlowchartCtrlTemplate.ui b/flowchart/FlowchartCtrlTemplate.ui index 610846b6..0361ad3e 100644 --- a/flowchart/FlowchartCtrlTemplate.ui +++ b/flowchart/FlowchartCtrlTemplate.ui @@ -107,12 +107,12 @@ TreeWidget QTreeWidget -
pyqtgraph.widgets.TreeWidget
+
..widgets.TreeWidget
FeedbackButton QPushButton -
pyqtgraph.widgets.FeedbackButton
+
..widgets.FeedbackButton
diff --git a/flowchart/FlowchartCtrlTemplate_pyqt.py b/flowchart/FlowchartCtrlTemplate_pyqt.py index 0410cdf3..8afd43f8 100644 --- a/flowchart/FlowchartCtrlTemplate_pyqt.py +++ b/flowchart/FlowchartCtrlTemplate_pyqt.py @@ -1,9 +1,9 @@ # -*- coding: utf-8 -*- -# Form implementation generated from reading ui file './flowchart/FlowchartCtrlTemplate.ui' +# Form implementation generated from reading ui file './pyqtgraph/flowchart/FlowchartCtrlTemplate.ui' # -# Created: Sun Sep 9 14:41:30 2012 -# by: PyQt4 UI code generator 4.9.1 +# Created: Mon Dec 23 10:10:50 2013 +# by: PyQt4 UI code generator 4.10 # # WARNING! All changes made in this file will be lost! @@ -12,7 +12,16 @@ from PyQt4 import QtCore, QtGui try: _fromUtf8 = QtCore.QString.fromUtf8 except AttributeError: - _fromUtf8 = lambda s: s + def _fromUtf8(s): + return s + +try: + _encoding = QtGui.QApplication.UnicodeUTF8 + def _translate(context, text, disambig): + return QtGui.QApplication.translate(context, text, disambig, _encoding) +except AttributeError: + def _translate(context, text, disambig): + return QtGui.QApplication.translate(context, text, disambig) class Ui_Form(object): def setupUi(self, Form): @@ -60,12 +69,12 @@ class Ui_Form(object): QtCore.QMetaObject.connectSlotsByName(Form) def retranslateUi(self, Form): - Form.setWindowTitle(QtGui.QApplication.translate("Form", "Form", None, QtGui.QApplication.UnicodeUTF8)) - self.loadBtn.setText(QtGui.QApplication.translate("Form", "Load..", None, QtGui.QApplication.UnicodeUTF8)) - self.saveBtn.setText(QtGui.QApplication.translate("Form", "Save", None, QtGui.QApplication.UnicodeUTF8)) - self.saveAsBtn.setText(QtGui.QApplication.translate("Form", "As..", None, QtGui.QApplication.UnicodeUTF8)) - self.reloadBtn.setText(QtGui.QApplication.translate("Form", "Reload Libs", None, QtGui.QApplication.UnicodeUTF8)) - self.showChartBtn.setText(QtGui.QApplication.translate("Form", "Flowchart", None, QtGui.QApplication.UnicodeUTF8)) + Form.setWindowTitle(_translate("Form", "Form", None)) + self.loadBtn.setText(_translate("Form", "Load..", None)) + self.saveBtn.setText(_translate("Form", "Save", None)) + self.saveAsBtn.setText(_translate("Form", "As..", None)) + self.reloadBtn.setText(_translate("Form", "Reload Libs", None)) + self.showChartBtn.setText(_translate("Form", "Flowchart", None)) -from pyqtgraph.widgets.FeedbackButton import FeedbackButton -from pyqtgraph.widgets.TreeWidget import TreeWidget +from ..widgets.TreeWidget import TreeWidget +from ..widgets.FeedbackButton import FeedbackButton diff --git a/flowchart/FlowchartCtrlTemplate_pyside.py b/flowchart/FlowchartCtrlTemplate_pyside.py index f579c957..b722000e 100644 --- a/flowchart/FlowchartCtrlTemplate_pyside.py +++ b/flowchart/FlowchartCtrlTemplate_pyside.py @@ -1,9 +1,9 @@ # -*- coding: utf-8 -*- -# Form implementation generated from reading ui file './flowchart/FlowchartCtrlTemplate.ui' +# Form implementation generated from reading ui file './pyqtgraph/flowchart/FlowchartCtrlTemplate.ui' # -# Created: Sun Sep 9 14:41:30 2012 -# by: pyside-uic 0.2.13 running on PySide 1.1.0 +# Created: Mon Dec 23 10:10:51 2013 +# by: pyside-uic 0.2.14 running on PySide 1.1.2 # # WARNING! All changes made in this file will be lost! @@ -62,5 +62,5 @@ class Ui_Form(object): self.reloadBtn.setText(QtGui.QApplication.translate("Form", "Reload Libs", None, QtGui.QApplication.UnicodeUTF8)) self.showChartBtn.setText(QtGui.QApplication.translate("Form", "Flowchart", None, QtGui.QApplication.UnicodeUTF8)) -from pyqtgraph.widgets.FeedbackButton import FeedbackButton -from pyqtgraph.widgets.TreeWidget import TreeWidget +from ..widgets.TreeWidget import TreeWidget +from ..widgets.FeedbackButton import FeedbackButton diff --git a/flowchart/FlowchartGraphicsView.py b/flowchart/FlowchartGraphicsView.py index 0ec4d5c8..ab4b2914 100644 --- a/flowchart/FlowchartGraphicsView.py +++ b/flowchart/FlowchartGraphicsView.py @@ -1,8 +1,8 @@ # -*- coding: utf-8 -*- -from pyqtgraph.Qt import QtGui, QtCore -from pyqtgraph.widgets.GraphicsView import GraphicsView -from pyqtgraph.GraphicsScene import GraphicsScene -from pyqtgraph.graphicsItems.ViewBox import ViewBox +from ..Qt import QtGui, QtCore +from ..widgets.GraphicsView import GraphicsView +from ..GraphicsScene import GraphicsScene +from ..graphicsItems.ViewBox import ViewBox #class FlowchartGraphicsView(QtGui.QGraphicsView): class FlowchartGraphicsView(GraphicsView): diff --git a/flowchart/FlowchartTemplate.ui b/flowchart/FlowchartTemplate.ui index 31b1359c..8b0c19da 100644 --- a/flowchart/FlowchartTemplate.ui +++ b/flowchart/FlowchartTemplate.ui @@ -85,12 +85,12 @@ DataTreeWidget QTreeWidget -
pyqtgraph.widgets.DataTreeWidget
+
..widgets.DataTreeWidget
FlowchartGraphicsView QGraphicsView -
pyqtgraph.flowchart.FlowchartGraphicsView
+
..flowchart.FlowchartGraphicsView
diff --git a/flowchart/FlowchartTemplate_pyqt.py b/flowchart/FlowchartTemplate_pyqt.py index c07dd734..06b10bfe 100644 --- a/flowchart/FlowchartTemplate_pyqt.py +++ b/flowchart/FlowchartTemplate_pyqt.py @@ -1,9 +1,9 @@ # -*- coding: utf-8 -*- -# Form implementation generated from reading ui file './flowchart/FlowchartTemplate.ui' +# Form implementation generated from reading ui file './pyqtgraph/flowchart/FlowchartTemplate.ui' # -# Created: Sun Feb 24 19:47:29 2013 -# by: PyQt4 UI code generator 4.9.3 +# Created: Mon Dec 23 10:10:51 2013 +# by: PyQt4 UI code generator 4.10 # # WARNING! All changes made in this file will be lost! @@ -12,7 +12,16 @@ from PyQt4 import QtCore, QtGui try: _fromUtf8 = QtCore.QString.fromUtf8 except AttributeError: - _fromUtf8 = lambda s: s + def _fromUtf8(s): + return s + +try: + _encoding = QtGui.QApplication.UnicodeUTF8 + def _translate(context, text, disambig): + return QtGui.QApplication.translate(context, text, disambig, _encoding) +except AttributeError: + def _translate(context, text, disambig): + return QtGui.QApplication.translate(context, text, disambig) class Ui_Form(object): def setupUi(self, Form): @@ -53,7 +62,7 @@ class Ui_Form(object): QtCore.QMetaObject.connectSlotsByName(Form) def retranslateUi(self, Form): - Form.setWindowTitle(QtGui.QApplication.translate("Form", "Form", None, QtGui.QApplication.UnicodeUTF8)) + Form.setWindowTitle(_translate("Form", "Form", None)) -from pyqtgraph.widgets.DataTreeWidget import DataTreeWidget -from pyqtgraph.flowchart.FlowchartGraphicsView import FlowchartGraphicsView +from ..flowchart.FlowchartGraphicsView import FlowchartGraphicsView +from ..widgets.DataTreeWidget import DataTreeWidget diff --git a/flowchart/FlowchartTemplate_pyside.py b/flowchart/FlowchartTemplate_pyside.py index c73f3c00..2c693c60 100644 --- a/flowchart/FlowchartTemplate_pyside.py +++ b/flowchart/FlowchartTemplate_pyside.py @@ -1,9 +1,9 @@ # -*- coding: utf-8 -*- -# Form implementation generated from reading ui file './flowchart/FlowchartTemplate.ui' +# Form implementation generated from reading ui file './pyqtgraph/flowchart/FlowchartTemplate.ui' # -# Created: Sun Feb 24 19:47:30 2013 -# by: pyside-uic 0.2.13 running on PySide 1.1.1 +# Created: Mon Dec 23 10:10:51 2013 +# by: pyside-uic 0.2.14 running on PySide 1.1.2 # # WARNING! All changes made in this file will be lost! @@ -50,5 +50,5 @@ class Ui_Form(object): def retranslateUi(self, Form): Form.setWindowTitle(QtGui.QApplication.translate("Form", "Form", None, QtGui.QApplication.UnicodeUTF8)) -from pyqtgraph.widgets.DataTreeWidget import DataTreeWidget -from pyqtgraph.flowchart.FlowchartGraphicsView import FlowchartGraphicsView +from ..flowchart.FlowchartGraphicsView import FlowchartGraphicsView +from ..widgets.DataTreeWidget import DataTreeWidget diff --git a/flowchart/Node.py b/flowchart/Node.py index cd73b42b..b6ed1e0f 100644 --- a/flowchart/Node.py +++ b/flowchart/Node.py @@ -1,10 +1,10 @@ # -*- coding: utf-8 -*- -from pyqtgraph.Qt import QtCore, QtGui -from pyqtgraph.graphicsItems.GraphicsObject import GraphicsObject -import pyqtgraph.functions as fn +from ..Qt import QtCore, QtGui +from ..graphicsItems.GraphicsObject import GraphicsObject +from .. import functions as fn from .Terminal import * -from pyqtgraph.pgcollections import OrderedDict -from pyqtgraph.debug import * +from ..pgcollections import OrderedDict +from ..debug import * import numpy as np from .eq import * @@ -617,9 +617,6 @@ class NodeGraphicsItem(GraphicsObject): def getMenu(self): return self.menu - - def getContextMenus(self, event): - return [self.menu] def raiseContextMenu(self, ev): menu = self.scene().addParentContextMenus(self, self.getMenu(), ev) diff --git a/flowchart/NodeLibrary.py b/flowchart/NodeLibrary.py new file mode 100644 index 00000000..a30ffb2a --- /dev/null +++ b/flowchart/NodeLibrary.py @@ -0,0 +1,84 @@ +from ..pgcollections import OrderedDict +from .Node import Node + +def isNodeClass(cls): + try: + if not issubclass(cls, Node): + return False + except: + return False + return hasattr(cls, 'nodeName') + + + +class NodeLibrary: + """ + A library of flowchart Node types. Custom libraries may be built to provide + each flowchart with a specific set of allowed Node types. + """ + + def __init__(self): + self.nodeList = OrderedDict() + self.nodeTree = OrderedDict() + + def addNodeType(self, nodeClass, paths, override=False): + """ + Register a new node type. If the type's name is already in use, + an exception will be raised (unless override=True). + + Arguments: + + nodeClass - a subclass of Node (must have typ.nodeName) + paths - list of tuples specifying the location(s) this + type will appear in the library tree. + override - if True, overwrite any class having the same name + """ + if not isNodeClass(nodeClass): + raise Exception("Object %s is not a Node subclass" % str(nodeClass)) + + name = nodeClass.nodeName + if not override and name in self.nodeList: + raise Exception("Node type name '%s' is already registered." % name) + + self.nodeList[name] = nodeClass + for path in paths: + root = self.nodeTree + for n in path: + if n not in root: + root[n] = OrderedDict() + root = root[n] + root[name] = nodeClass + + def getNodeType(self, name): + try: + return self.nodeList[name] + except KeyError: + raise Exception("No node type called '%s'" % name) + + def getNodeTree(self): + return self.nodeTree + + def copy(self): + """ + Return a copy of this library. + """ + lib = NodeLibrary() + lib.nodeList = self.nodeList.copy() + lib.nodeTree = self.treeCopy(self.nodeTree) + return lib + + @staticmethod + def treeCopy(tree): + copy = OrderedDict() + for k,v in tree.items(): + if isNodeClass(v): + copy[k] = v + else: + copy[k] = NodeLibrary.treeCopy(v) + return copy + + def reload(self): + """ + Reload Node classes in this library. + """ + raise NotImplementedError() diff --git a/flowchart/Terminal.py b/flowchart/Terminal.py index 45805cd8..6a6db62e 100644 --- a/flowchart/Terminal.py +++ b/flowchart/Terminal.py @@ -1,9 +1,9 @@ # -*- coding: utf-8 -*- -from pyqtgraph.Qt import QtCore, QtGui +from ..Qt import QtCore, QtGui import weakref -from pyqtgraph.graphicsItems.GraphicsObject import GraphicsObject -import pyqtgraph.functions as fn -from pyqtgraph.Point import Point +from ..graphicsItems.GraphicsObject import GraphicsObject +from .. import functions as fn +from ..Point import Point #from PySide import QtCore, QtGui from .eq import * @@ -436,10 +436,6 @@ class TerminalGraphicsItem(GraphicsObject): def toggleMulti(self): multi = self.menu.multiAct.isChecked() self.term.setMultiValue(multi) - - ## probably never need this - #def getContextMenus(self, ev): - #return [self.getMenu()] def removeSelf(self): self.term.node().removeTerminal(self.term) diff --git a/flowchart/eq.py b/flowchart/eq.py index 031ebce8..89ebe09f 100644 --- a/flowchart/eq.py +++ b/flowchart/eq.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- from numpy import ndarray, bool_ -from pyqtgraph.metaarray import MetaArray +from ..metaarray import MetaArray def eq(a, b): """The great missing equivalence function: Guaranteed evaluation to a single bool value.""" diff --git a/flowchart/library/Data.py b/flowchart/library/Data.py index cbef848a..52458bd9 100644 --- a/flowchart/library/Data.py +++ b/flowchart/library/Data.py @@ -1,12 +1,12 @@ # -*- coding: utf-8 -*- from ..Node import Node -from pyqtgraph.Qt import QtGui, QtCore +from ...Qt import QtGui, QtCore import numpy as np from .common import * -from pyqtgraph.SRTTransform import SRTTransform -from pyqtgraph.Point import Point -from pyqtgraph.widgets.TreeWidget import TreeWidget -from pyqtgraph.graphicsItems.LinearRegionItem import LinearRegionItem +from ...SRTTransform import SRTTransform +from ...Point import Point +from ...widgets.TreeWidget import TreeWidget +from ...graphicsItems.LinearRegionItem import LinearRegionItem from . import functions diff --git a/flowchart/library/Display.py b/flowchart/library/Display.py index 9068c0ec..2c352fb2 100644 --- a/flowchart/library/Display.py +++ b/flowchart/library/Display.py @@ -1,11 +1,10 @@ # -*- coding: utf-8 -*- from ..Node import Node import weakref -#from pyqtgraph import graphicsItems -from pyqtgraph.Qt import QtCore, QtGui -from pyqtgraph.graphicsItems.ScatterPlotItem import ScatterPlotItem -from pyqtgraph.graphicsItems.PlotCurveItem import PlotCurveItem -from pyqtgraph import PlotDataItem +from ...Qt import QtCore, QtGui +from ...graphicsItems.ScatterPlotItem import ScatterPlotItem +from ...graphicsItems.PlotCurveItem import PlotCurveItem +from ... import PlotDataItem from .common import * import numpy as np @@ -272,4 +271,4 @@ class ScatterPlot(CtrlNode): #pos = file. - \ No newline at end of file + diff --git a/flowchart/library/Filters.py b/flowchart/library/Filters.py index 090c261c..518c8c18 100644 --- a/flowchart/library/Filters.py +++ b/flowchart/library/Filters.py @@ -1,14 +1,14 @@ # -*- coding: utf-8 -*- -from pyqtgraph.Qt import QtCore, QtGui +from ...Qt import QtCore, QtGui from ..Node import Node from scipy.signal import detrend from scipy.ndimage import median_filter, gaussian_filter -#from pyqtgraph.SignalProxy import SignalProxy +#from ...SignalProxy import SignalProxy from . import functions from .common import * import numpy as np -import pyqtgraph.metaarray as metaarray +from ... import metaarray as metaarray class Downsample(CtrlNode): diff --git a/flowchart/library/__init__.py b/flowchart/library/__init__.py index 1e44edff..d8038aa4 100644 --- a/flowchart/library/__init__.py +++ b/flowchart/library/__init__.py @@ -1,103 +1,28 @@ # -*- coding: utf-8 -*- -from pyqtgraph.pgcollections import OrderedDict -from pyqtgraph import importModules +from ...pgcollections import OrderedDict import os, types -from pyqtgraph.debug import printExc -from ..Node import Node -import pyqtgraph.reload as reload +from ...debug import printExc +from ..NodeLibrary import NodeLibrary, isNodeClass +from ... import reload as reload -NODE_LIST = OrderedDict() ## maps name:class for all registered Node subclasses -NODE_TREE = OrderedDict() ## categorized tree of Node subclasses +# Build default library +LIBRARY = NodeLibrary() -def getNodeType(name): - try: - return NODE_LIST[name] - except KeyError: - raise Exception("No node type called '%s'" % name) +# For backward compatibility, expose the default library's properties here: +NODE_LIST = LIBRARY.nodeList +NODE_TREE = LIBRARY.nodeTree +registerNodeType = LIBRARY.addNodeType +getNodeTree = LIBRARY.getNodeTree +getNodeType = LIBRARY.getNodeType -def getNodeTree(): - return NODE_TREE - -def registerNodeType(cls, paths, override=False): - """ - Register a new node type. If the type's name is already in use, - an exception will be raised (unless override=True). +# Add all nodes to the default library +from . import Data, Display, Filters, Operators +for mod in [Data, Display, Filters, Operators]: + nodes = [getattr(mod, name) for name in dir(mod) if isNodeClass(getattr(mod, name))] + for node in nodes: + LIBRARY.addNodeType(node, [(mod.__name__.split('.')[-1],)]) - Arguments: - cls - a subclass of Node (must have typ.nodeName) - paths - list of tuples specifying the location(s) this - type will appear in the library tree. - override - if True, overwrite any class having the same name - """ - if not isNodeClass(cls): - raise Exception("Object %s is not a Node subclass" % str(cls)) - - name = cls.nodeName - if not override and name in NODE_LIST: - raise Exception("Node type name '%s' is already registered." % name) - - NODE_LIST[name] = cls - for path in paths: - root = NODE_TREE - for n in path: - if n not in root: - root[n] = OrderedDict() - root = root[n] - root[name] = cls -def isNodeClass(cls): - try: - if not issubclass(cls, Node): - return False - except: - return False - return hasattr(cls, 'nodeName') - -def loadLibrary(reloadLibs=False, libPath=None): - """Import all Node subclasses found within files in the library module.""" - - global NODE_LIST, NODE_TREE - #if libPath is None: - #libPath = os.path.dirname(os.path.abspath(__file__)) - - if reloadLibs: - reload.reloadAll(libPath) - - mods = importModules('', globals(), locals()) - #for f in frozenSupport.listdir(libPath): - #pathName, ext = os.path.splitext(f) - #if ext not in ('.py', '.pyc') or '__init__' in pathName or '__pycache__' in pathName: - #continue - #try: - ##print "importing from", f - #mod = __import__(pathName, globals(), locals()) - #except: - #printExc("Error loading flowchart library %s:" % pathName) - #continue - - for name, mod in mods.items(): - nodes = [] - for n in dir(mod): - o = getattr(mod, n) - if isNodeClass(o): - #print " ", str(o) - registerNodeType(o, [(name,)], override=reloadLibs) - #nodes.append((o.nodeName, o)) - #if len(nodes) > 0: - #NODE_TREE[name] = OrderedDict(nodes) - #NODE_LIST.extend(nodes) - #NODE_LIST = OrderedDict(NODE_LIST) - -def reloadLibrary(): - loadLibrary(reloadLibs=True) - -loadLibrary() -#NODE_LIST = [] -#for o in locals().values(): - #if type(o) is type(AddNode) and issubclass(o, Node) and o is not Node and hasattr(o, 'nodeName'): - #NODE_LIST.append((o.nodeName, o)) -#NODE_LIST.sort(lambda a,b: cmp(a[0], b[0])) -#NODE_LIST = OrderedDict(NODE_LIST) \ No newline at end of file diff --git a/flowchart/library/common.py b/flowchart/library/common.py index 65f8c1fd..548dc440 100644 --- a/flowchart/library/common.py +++ b/flowchart/library/common.py @@ -1,12 +1,12 @@ # -*- coding: utf-8 -*- -from pyqtgraph.Qt import QtCore, QtGui -from pyqtgraph.widgets.SpinBox import SpinBox -#from pyqtgraph.SignalProxy import SignalProxy -from pyqtgraph.WidgetGroup import WidgetGroup +from ...Qt import QtCore, QtGui +from ...widgets.SpinBox import SpinBox +#from ...SignalProxy import SignalProxy +from ...WidgetGroup import WidgetGroup #from ColorMapper import ColorMapper from ..Node import Node import numpy as np -from pyqtgraph.widgets.ColorButton import ColorButton +from ...widgets.ColorButton import ColorButton try: import metaarray HAVE_METAARRAY = True diff --git a/flowchart/library/functions.py b/flowchart/library/functions.py index 0476e02f..9efb8f36 100644 --- a/flowchart/library/functions.py +++ b/flowchart/library/functions.py @@ -1,6 +1,6 @@ import scipy import numpy as np -from pyqtgraph.metaarray import MetaArray +from ...metaarray import MetaArray def downsample(data, n, axis=0, xvals='subsample'): """Downsample by averaging points together across axis. diff --git a/functions.py b/functions.py index 337dfb67..12588cf1 100644 --- a/functions.py +++ b/functions.py @@ -24,7 +24,7 @@ SI_PREFIXES_ASCII = 'yzafpnum kMGTPEZY' from .Qt import QtGui, QtCore, USE_PYSIDE -import pyqtgraph as pg +from . import getConfigOption, setConfigOptions import numpy as np import decimal, re import ctypes @@ -33,11 +33,11 @@ import sys, struct try: import scipy.ndimage HAVE_SCIPY = True - if pg.getConfigOption('useWeave'): + if getConfigOption('useWeave'): try: import scipy.weave except ImportError: - pg.setConfigOptions(useWeave=False) + setConfigOptions(useWeave=False) except ImportError: HAVE_SCIPY = False @@ -620,7 +620,7 @@ def rescaleData(data, scale, offset, dtype=None): dtype = np.dtype(dtype) try: - if not pg.getConfigOption('useWeave'): + if not getConfigOption('useWeave'): raise Exception('Weave is disabled; falling back to slower version.') ## require native dtype when using weave @@ -647,10 +647,10 @@ def rescaleData(data, scale, offset, dtype=None): newData = newData.astype(dtype) data = newData.reshape(data.shape) except: - if pg.getConfigOption('useWeave'): - if pg.getConfigOption('weaveDebug'): + if getConfigOption('useWeave'): + if getConfigOption('weaveDebug'): debug.printExc("Error; disabling weave.") - pg.setConfigOption('useWeave', False) + setConfigOptions(useWeave=False) #p = np.poly1d([scale, -offset*scale]) #data = p(data).astype(dtype) @@ -775,32 +775,13 @@ def makeARGB(data, lut=None, levels=None, scale=None, useRGBA=False): is BGRA). ============ ================================================================================== """ - prof = debug.Profiler('functions.makeARGB', disabled=True) + profile = debug.Profiler() if lut is not None and not isinstance(lut, np.ndarray): lut = np.array(lut) if levels is not None and not isinstance(levels, np.ndarray): levels = np.array(levels) - ## sanity checks - #if data.ndim == 3: - #if data.shape[2] not in (3,4): - #raise Exception("data.shape[2] must be 3 or 4") - ##if lut is not None: - ##raise Exception("can not use lookup table with 3D data") - #elif data.ndim != 2: - #raise Exception("data must be 2D or 3D") - - #if lut is not None: - ##if lut.ndim == 2: - ##if lut.shape[1] : - ##raise Exception("lut.shape[1] must be 3 or 4") - ##elif lut.ndim != 1: - ##raise Exception("lut must be 1D or 2D") - #if lut.dtype != np.ubyte: - #raise Exception('lookup table must have dtype=ubyte (got %s instead)' % str(lut.dtype)) - - if levels is not None: if levels.ndim == 1: if len(levels) != 2: @@ -813,18 +794,8 @@ def makeARGB(data, lut=None, levels=None, scale=None, useRGBA=False): else: print(levels) raise Exception("levels argument must be 1D or 2D.") - #levels = np.array(levels) - #if levels.shape == (2,): - #pass - #elif levels.shape in [(3,2), (4,2)]: - #if data.ndim == 3: - #raise Exception("Can not use 2D levels with 3D data.") - #if lut is not None: - #raise Exception('Can not use 2D levels and lookup table together.') - #else: - #raise Exception("Levels must have shape (2,) or (3,2) or (4,2)") - - prof.mark('1') + + profile() if scale is None: if lut is not None: @@ -851,8 +822,8 @@ def makeARGB(data, lut=None, levels=None, scale=None, useRGBA=False): if minVal == maxVal: maxVal += 1e-16 data = rescaleData(data, scale/(maxVal-minVal), minVal, dtype=int) - prof.mark('2') + profile() ## apply LUT if given if lut is not None: @@ -860,41 +831,43 @@ def makeARGB(data, lut=None, levels=None, scale=None, useRGBA=False): else: if data.dtype is not np.ubyte: data = np.clip(data, 0, 255).astype(np.ubyte) - prof.mark('3') + profile() ## copy data into ARGB ordered array imgData = np.empty(data.shape[:2]+(4,), dtype=np.ubyte) - if data.ndim == 2: - data = data[..., np.newaxis] - prof.mark('4') + profile() if useRGBA: order = [0,1,2,3] ## array comes out RGBA else: order = [2,1,0,3] ## for some reason, the colors line up as BGR in the final image. - if data.shape[2] == 1: + if data.ndim == 2: + # This is tempting: + # imgData[..., :3] = data[..., np.newaxis] + # ..but it turns out this is faster: for i in range(3): - imgData[..., order[i]] = data[..., 0] + imgData[..., i] = data + elif data.shape[2] == 1: + for i in range(3): + imgData[..., i] = data[..., 0] else: for i in range(0, data.shape[2]): - imgData[..., order[i]] = data[..., i] + imgData[..., i] = data[..., order[i]] - prof.mark('5') + profile() - if data.shape[2] == 4: - alpha = True - else: + if data.ndim == 2 or data.shape[2] == 3: alpha = False imgData[..., 3] = 255 + else: + alpha = True - prof.mark('6') - - prof.finish() + profile() return imgData, alpha - + def makeQImage(imgData, alpha=None, copy=True, transpose=True): """ @@ -923,7 +896,7 @@ def makeQImage(imgData, alpha=None, copy=True, transpose=True): =========== =================================================================== """ ## create QImage from buffer - prof = debug.Profiler('functions.makeQImage', disabled=True) + profile = debug.Profiler() ## If we didn't explicitly specify alpha, check the array shape. if alpha is None: @@ -947,7 +920,9 @@ def makeQImage(imgData, alpha=None, copy=True, transpose=True): if transpose: imgData = imgData.transpose((1, 0, 2)) ## QImage expects the row/column order to be opposite - + + profile() + if not imgData.flags['C_CONTIGUOUS']: if copy is False: extra = ' (try setting transpose=False)' if transpose else '' @@ -988,11 +963,10 @@ def makeQImage(imgData, alpha=None, copy=True, transpose=True): #except AttributeError: ## happens when image data is non-contiguous #buf = imgData.data - #prof.mark('1') + #profiler() #qimage = QtGui.QImage(buf, imgData.shape[1], imgData.shape[0], imgFormat) - #prof.mark('2') + #profiler() #qimage.data = imgData - #prof.finish() #return qimage def imageToArray(img, copy=False, transpose=True): @@ -1112,16 +1086,16 @@ def arrayToQPath(x, y, connect='all'): path = QtGui.QPainterPath() - #prof = debug.Profiler('PlotCurveItem.generatePath', disabled=True) + #profiler = debug.Profiler() n = x.shape[0] # create empty array, pad with extra space on either end arr = np.empty(n+2, dtype=[('x', '>f8'), ('y', '>f8'), ('c', '>i4')]) # write first two integers - #prof.mark('allocate empty') + #profiler('allocate empty') byteview = arr.view(dtype=np.ubyte) byteview[:12] = 0 byteview.data[12:20] = struct.pack('>ii', n, 0) - #prof.mark('pack header') + #profiler('pack header') # Fill array with vertex values arr[1:-1]['x'] = x arr[1:-1]['y'] = y @@ -1142,11 +1116,11 @@ def arrayToQPath(x, y, connect='all'): else: raise Exception('connect argument must be "all", "pairs", or array') - #prof.mark('fill array') + #profiler('fill array') # write last 0 lastInd = 20*(n+1) byteview.data[lastInd:lastInd+4] = struct.pack('>i', 0) - #prof.mark('footer') + #profiler('footer') # create datastream object and stream into path ## Avoiding this method because QByteArray(str) leaks memory in PySide @@ -1157,13 +1131,11 @@ def arrayToQPath(x, y, connect='all'): buf = QtCore.QByteArray.fromRawData(path.strn) except TypeError: buf = QtCore.QByteArray(bytes(path.strn)) - #prof.mark('create buffer') + #profiler('create buffer') ds = QtCore.QDataStream(buf) ds >> path - #prof.mark('load') - - #prof.finish() + #profiler('load') return path @@ -1890,7 +1862,7 @@ def isosurface(data, level): faces = np.empty((totFaces, 3), dtype=np.uint32) ptr = 0 #import debug - #p = debug.Profiler('isosurface', disabled=False) + #p = debug.Profiler() ## this helps speed up an indexing operation later on cs = np.array(cutEdges.strides)//cutEdges.itemsize @@ -1902,32 +1874,32 @@ def isosurface(data, level): for i in range(1,6): ### expensive: - #p.mark('1') + #profiler() cells = np.argwhere(nFaces == i) ## all cells which require i faces (argwhere is expensive) - #p.mark('2') + #profiler() if cells.shape[0] == 0: continue #cellInds = index[(cells*ins[np.newaxis,:]).sum(axis=1)] cellInds = index[cells[:,0], cells[:,1], cells[:,2]] ## index values of cells to process for this round - #p.mark('3') + #profiler() ### expensive: verts = faceShiftTables[i][cellInds] - #p.mark('4') + #profiler() verts[...,:3] += cells[:,np.newaxis,np.newaxis,:] ## we now have indexes into cutEdges verts = verts.reshape((verts.shape[0]*i,)+verts.shape[2:]) - #p.mark('5') + #profiler() ### expensive: #print verts.shape verts = (verts * cs[np.newaxis, np.newaxis, :]).sum(axis=2) #vertInds = cutEdges[verts[...,0], verts[...,1], verts[...,2], verts[...,3]] ## and these are the vertex indexes we want. vertInds = cutEdges[verts] - #p.mark('6') + #profiler() nv = vertInds.shape[0] - #p.mark('7') + #profiler() faces[ptr:ptr+nv] = vertInds #.reshape((nv, 3)) - #p.mark('8') + #profiler() ptr += nv return vertexes, faces diff --git a/graphicsItems/ArrowItem.py b/graphicsItems/ArrowItem.py index dcede02a..b15fc664 100644 --- a/graphicsItems/ArrowItem.py +++ b/graphicsItems/ArrowItem.py @@ -1,5 +1,5 @@ -from pyqtgraph.Qt import QtGui, QtCore -import pyqtgraph.functions as fn +from ..Qt import QtGui, QtCore +from .. import functions as fn import numpy as np __all__ = ['ArrowItem'] diff --git a/graphicsItems/AxisItem.py b/graphicsItems/AxisItem.py index 429ff49c..1d0b36b6 100644 --- a/graphicsItems/AxisItem.py +++ b/graphicsItems/AxisItem.py @@ -1,11 +1,11 @@ -from pyqtgraph.Qt import QtGui, QtCore -from pyqtgraph.python2_3 import asUnicode +from ..Qt import QtGui, QtCore +from ..python2_3 import asUnicode import numpy as np -from pyqtgraph.Point import Point -import pyqtgraph.debug as debug +from ..Point import Point +from .. import debug as debug import weakref -import pyqtgraph.functions as fn -import pyqtgraph as pg +from .. import functions as fn +from .. import getConfigOption from .GraphicsWidget import GraphicsWidget __all__ = ['AxisItem'] @@ -268,8 +268,8 @@ class AxisItem(GraphicsWidget): def pen(self): if self._pen is None: - return fn.mkPen(pg.getConfigOption('foreground')) - return pg.mkPen(self._pen) + return fn.mkPen(getConfigOption('foreground')) + return fn.mkPen(self._pen) def setPen(self, pen): """ @@ -280,8 +280,8 @@ class AxisItem(GraphicsWidget): self._pen = pen self.picture = None if pen is None: - pen = pg.getConfigOption('foreground') - self.labelStyle['color'] = '#' + pg.colorStr(pg.mkPen(pen).color())[:6] + pen = getConfigOption('foreground') + self.labelStyle['color'] = '#' + fn.colorStr(fn.mkPen(pen).color())[:6] self.setLabel() self.update() @@ -404,25 +404,22 @@ class AxisItem(GraphicsWidget): return self.mapRectFromParent(self.geometry()) | linkedView.mapRectToItem(self, linkedView.boundingRect()) def paint(self, p, opt, widget): - prof = debug.Profiler('AxisItem.paint', disabled=True) + profiler = debug.Profiler() if self.picture is None: try: picture = QtGui.QPicture() painter = QtGui.QPainter(picture) specs = self.generateDrawSpecs(painter) - prof.mark('generate specs') + profiler('generate specs') if specs is not None: self.drawPicture(painter, *specs) - prof.mark('draw picture') + profiler('draw picture') finally: painter.end() self.picture = picture #p.setRenderHint(p.Antialiasing, False) ## Sometimes we get a segfault here ??? #p.setRenderHint(p.TextAntialiasing, True) self.picture.play(p) - prof.finish() - - def setTicks(self, ticks): """Explicitly determine which ticks to display. @@ -626,8 +623,8 @@ class AxisItem(GraphicsWidget): be drawn, then generates from this a set of drawing commands to be interpreted by drawPicture(). """ - prof = debug.Profiler("AxisItem.generateDrawSpecs", disabled=True) - + profiler = debug.Profiler() + #bounds = self.boundingRect() bounds = self.mapRectFromParent(self.geometry()) @@ -706,7 +703,7 @@ class AxisItem(GraphicsWidget): xMin = min(xRange) xMax = max(xRange) - prof.mark('init') + profiler('init') tickPositions = [] # remembers positions of previously drawn ticks @@ -744,7 +741,7 @@ class AxisItem(GraphicsWidget): color.setAlpha(lineAlpha) tickPen.setColor(color) tickSpecs.append((tickPen, Point(p1), Point(p2))) - prof.mark('compute ticks') + profiler('compute ticks') ## This is where the long axis line should be drawn @@ -857,7 +854,7 @@ class AxisItem(GraphicsWidget): #p.setPen(self.pen()) #p.drawText(rect, textFlags, vstr) textSpecs.append((rect, textFlags, vstr)) - prof.mark('compute text') + profiler('compute text') ## update max text size if needed. self._updateMaxTextSize(textSize2) @@ -865,8 +862,8 @@ class AxisItem(GraphicsWidget): return (axisSpec, tickSpecs, textSpecs) def drawPicture(self, p, axisSpec, tickSpecs, textSpecs): - prof = debug.Profiler("AxisItem.drawPicture", disabled=True) - + profiler = debug.Profiler() + p.setRenderHint(p.Antialiasing, False) p.setRenderHint(p.TextAntialiasing, True) @@ -880,8 +877,8 @@ class AxisItem(GraphicsWidget): for pen, p1, p2 in tickSpecs: p.setPen(pen) p.drawLine(p1, p2) - prof.mark('draw ticks') - + profiler('draw ticks') + ## Draw all text if self.tickFont is not None: p.setFont(self.tickFont) @@ -889,10 +886,8 @@ class AxisItem(GraphicsWidget): for rect, flags, text in textSpecs: p.drawText(rect, flags, text) #p.drawRect(rect) - - prof.mark('draw text') - prof.finish() - + profiler('draw text') + def show(self): if self.orientation in ['left', 'right']: diff --git a/graphicsItems/BarGraphItem.py b/graphicsItems/BarGraphItem.py index 0527e9f1..9f9dbcde 100644 --- a/graphicsItems/BarGraphItem.py +++ b/graphicsItems/BarGraphItem.py @@ -1,8 +1,10 @@ -import pyqtgraph as pg -from pyqtgraph.Qt import QtGui, QtCore +from ..Qt import QtGui, QtCore from .GraphicsObject import GraphicsObject +from .. import getConfigOption +from .. import functions as fn import numpy as np + __all__ = ['BarGraphItem'] class BarGraphItem(GraphicsObject): @@ -61,7 +63,7 @@ class BarGraphItem(GraphicsObject): pens = self.opts['pens'] if pen is None and pens is None: - pen = pg.getConfigOption('foreground') + pen = getConfigOption('foreground') brush = self.opts['brush'] brushes = self.opts['brushes'] @@ -112,13 +114,13 @@ class BarGraphItem(GraphicsObject): raise Exception('must specify either y1 or height') height = y1 - y0 - p.setPen(pg.mkPen(pen)) - p.setBrush(pg.mkBrush(brush)) + p.setPen(fn.mkPen(pen)) + p.setBrush(fn.mkBrush(brush)) for i in range(len(x0)): if pens is not None: - p.setPen(pg.mkPen(pens[i])) + p.setPen(fn.mkPen(pens[i])) if brushes is not None: - p.setBrush(pg.mkBrush(brushes[i])) + p.setBrush(fn.mkBrush(brushes[i])) if np.isscalar(y0): y = y0 diff --git a/graphicsItems/ButtonItem.py b/graphicsItems/ButtonItem.py index 741f2666..1c796823 100644 --- a/graphicsItems/ButtonItem.py +++ b/graphicsItems/ButtonItem.py @@ -1,4 +1,4 @@ -from pyqtgraph.Qt import QtGui, QtCore +from ..Qt import QtGui, QtCore from .GraphicsObject import GraphicsObject __all__ = ['ButtonItem'] diff --git a/graphicsItems/CurvePoint.py b/graphicsItems/CurvePoint.py index 668830f7..f981bdf8 100644 --- a/graphicsItems/CurvePoint.py +++ b/graphicsItems/CurvePoint.py @@ -1,7 +1,7 @@ -from pyqtgraph.Qt import QtGui, QtCore +from ..Qt import QtGui, QtCore from . import ArrowItem import numpy as np -from pyqtgraph.Point import Point +from ..Point import Point import weakref from .GraphicsObject import GraphicsObject diff --git a/graphicsItems/ErrorBarItem.py b/graphicsItems/ErrorBarItem.py index 656b9e2e..7b681389 100644 --- a/graphicsItems/ErrorBarItem.py +++ b/graphicsItems/ErrorBarItem.py @@ -1,6 +1,7 @@ -import pyqtgraph as pg -from pyqtgraph.Qt import QtGui, QtCore +from ..Qt import QtGui, QtCore from .GraphicsObject import GraphicsObject +from .. import getConfigOption +from .. import functions as fn __all__ = ['ErrorBarItem'] @@ -121,8 +122,8 @@ class ErrorBarItem(GraphicsObject): self.drawPath() pen = self.opts['pen'] if pen is None: - pen = pg.getConfigOption('foreground') - p.setPen(pg.mkPen(pen)) + pen = getConfigOption('foreground') + p.setPen(fn.mkPen(pen)) p.drawPath(self.path) def boundingRect(self): diff --git a/graphicsItems/FillBetweenItem.py b/graphicsItems/FillBetweenItem.py index e0011177..13e5fa6b 100644 --- a/graphicsItems/FillBetweenItem.py +++ b/graphicsItems/FillBetweenItem.py @@ -1,23 +1,24 @@ -import pyqtgraph as pg +from ..Qt import QtGui +from .. import functions as fn -class FillBetweenItem(pg.QtGui.QGraphicsPathItem): +class FillBetweenItem(QtGui.QGraphicsPathItem): """ GraphicsItem filling the space between two PlotDataItems. """ def __init__(self, p1, p2, brush=None): - pg.QtGui.QGraphicsPathItem.__init__(self) + QtGui.QGraphicsPathItem.__init__(self) self.p1 = p1 self.p2 = p2 p1.sigPlotChanged.connect(self.updatePath) p2.sigPlotChanged.connect(self.updatePath) if brush is not None: - self.setBrush(pg.mkBrush(brush)) + self.setBrush(fn.mkBrush(brush)) self.setZValue(min(p1.zValue(), p2.zValue())-1) self.updatePath() def updatePath(self): p1 = self.p1.curve.path p2 = self.p2.curve.path - path = pg.QtGui.QPainterPath() + path = QtGui.QPainterPath() path.addPolygon(p1.toSubpathPolygons()[0] + p2.toReversed().toSubpathPolygons()[0]) self.setPath(path) diff --git a/graphicsItems/GradientEditorItem.py b/graphicsItems/GradientEditorItem.py index 955106d8..f5158a74 100644 --- a/graphicsItems/GradientEditorItem.py +++ b/graphicsItems/GradientEditorItem.py @@ -1,11 +1,11 @@ -from pyqtgraph.Qt import QtGui, QtCore -from pyqtgraph.python2_3 import sortList -import pyqtgraph.functions as fn +from ..Qt import QtGui, QtCore +from ..python2_3 import sortList +from .. import functions as fn from .GraphicsObject import GraphicsObject from .GraphicsWidget import GraphicsWidget import weakref -from pyqtgraph.pgcollections import OrderedDict -from pyqtgraph.colormap import ColorMap +from ..pgcollections import OrderedDict +from ..colormap import ColorMap import numpy as np diff --git a/graphicsItems/GradientLegend.py b/graphicsItems/GradientLegend.py index 4528b7ed..28c2cd63 100644 --- a/graphicsItems/GradientLegend.py +++ b/graphicsItems/GradientLegend.py @@ -1,6 +1,6 @@ -from pyqtgraph.Qt import QtGui, QtCore +from ..Qt import QtGui, QtCore from .UIGraphicsItem import * -import pyqtgraph.functions as fn +from .. import functions as fn __all__ = ['GradientLegend'] diff --git a/graphicsItems/GraphItem.py b/graphicsItems/GraphItem.py index b1f34baa..97759522 100644 --- a/graphicsItems/GraphItem.py +++ b/graphicsItems/GraphItem.py @@ -1,8 +1,9 @@ from .. import functions as fn from .GraphicsObject import GraphicsObject from .ScatterPlotItem import ScatterPlotItem -import pyqtgraph as pg +from ..Qt import QtGui, QtCore import numpy as np +from .. import getConfigOption __all__ = ['GraphItem'] @@ -71,11 +72,11 @@ class GraphItem(GraphicsObject): self.picture = None def generatePicture(self): - self.picture = pg.QtGui.QPicture() + self.picture = QtGui.QPicture() if self.pen is None or self.pos is None or self.adjacency is None: return - p = pg.QtGui.QPainter(self.picture) + p = QtGui.QPainter(self.picture) try: pts = self.pos[self.adjacency] pen = self.pen @@ -86,14 +87,14 @@ class GraphItem(GraphicsObject): if np.any(pen != lastPen): lastPen = pen if pen.dtype.fields is None: - p.setPen(pg.mkPen(color=(pen[0], pen[1], pen[2], pen[3]), width=1)) + p.setPen(fn.mkPen(color=(pen[0], pen[1], pen[2], pen[3]), width=1)) else: - p.setPen(pg.mkPen(color=(pen['red'], pen['green'], pen['blue'], pen['alpha']), width=pen['width'])) - p.drawLine(pg.QtCore.QPointF(*pts[i][0]), pg.QtCore.QPointF(*pts[i][1])) + p.setPen(fn.mkPen(color=(pen['red'], pen['green'], pen['blue'], pen['alpha']), width=pen['width'])) + p.drawLine(QtCore.QPointF(*pts[i][0]), QtCore.QPointF(*pts[i][1])) else: if pen == 'default': - pen = pg.getConfigOption('foreground') - p.setPen(pg.mkPen(pen)) + pen = getConfigOption('foreground') + p.setPen(fn.mkPen(pen)) pts = pts.reshape((pts.shape[0]*pts.shape[1], pts.shape[2])) path = fn.arrayToQPath(x=pts[:,0], y=pts[:,1], connect='pairs') p.drawPath(path) @@ -103,7 +104,7 @@ class GraphItem(GraphicsObject): def paint(self, p, *args): if self.picture == None: self.generatePicture() - if pg.getConfigOption('antialias') is True: + if getConfigOption('antialias') is True: p.setRenderHint(p.Antialiasing) self.picture.play(p) diff --git a/graphicsItems/GraphicsItem.py b/graphicsItems/GraphicsItem.py index a129436e..8d2238b8 100644 --- a/graphicsItems/GraphicsItem.py +++ b/graphicsItems/GraphicsItem.py @@ -1,9 +1,9 @@ -from pyqtgraph.Qt import QtGui, QtCore -from pyqtgraph.GraphicsScene import GraphicsScene -from pyqtgraph.Point import Point -import pyqtgraph.functions as fn +from ..Qt import QtGui, QtCore +from ..GraphicsScene import GraphicsScene +from ..Point import Point +from .. import functions as fn import weakref -from pyqtgraph.pgcollections import OrderedDict +from ..pgcollections import OrderedDict import operator, sys class FiniteCache(OrderedDict): @@ -585,3 +585,6 @@ class GraphicsItem(object): #def update(self): #self._qtBaseClass.update(self) #print "Update:", self + + def getContextMenus(self, event): + return [self.getMenu()] if hasattr(self, "getMenu") else [] diff --git a/graphicsItems/GraphicsLayout.py b/graphicsItems/GraphicsLayout.py index 9d48e627..a4016522 100644 --- a/graphicsItems/GraphicsLayout.py +++ b/graphicsItems/GraphicsLayout.py @@ -1,5 +1,5 @@ -from pyqtgraph.Qt import QtGui, QtCore -import pyqtgraph.functions as fn +from ..Qt import QtGui, QtCore +from .. import functions as fn from .GraphicsWidget import GraphicsWidget ## Must be imported at the end to avoid cyclic-dependency hell: from .ViewBox import ViewBox diff --git a/graphicsItems/GraphicsObject.py b/graphicsItems/GraphicsObject.py index d8f55d27..1ea9a08b 100644 --- a/graphicsItems/GraphicsObject.py +++ b/graphicsItems/GraphicsObject.py @@ -1,4 +1,4 @@ -from pyqtgraph.Qt import QtGui, QtCore, USE_PYSIDE +from ..Qt import QtGui, QtCore, USE_PYSIDE if not USE_PYSIDE: import sip from .GraphicsItem import GraphicsItem diff --git a/graphicsItems/GraphicsWidget.py b/graphicsItems/GraphicsWidget.py index 7650b125..c379ce8e 100644 --- a/graphicsItems/GraphicsWidget.py +++ b/graphicsItems/GraphicsWidget.py @@ -1,5 +1,5 @@ -from pyqtgraph.Qt import QtGui, QtCore -from pyqtgraph.GraphicsScene import GraphicsScene +from ..Qt import QtGui, QtCore +from ..GraphicsScene import GraphicsScene from .GraphicsItem import GraphicsItem __all__ = ['GraphicsWidget'] diff --git a/graphicsItems/GridItem.py b/graphicsItems/GridItem.py index 29b0aa2c..87f90a62 100644 --- a/graphicsItems/GridItem.py +++ b/graphicsItems/GridItem.py @@ -1,8 +1,8 @@ -from pyqtgraph.Qt import QtGui, QtCore +from ..Qt import QtGui, QtCore from .UIGraphicsItem import * import numpy as np -from pyqtgraph.Point import Point -import pyqtgraph.functions as fn +from ..Point import Point +from .. import functions as fn __all__ = ['GridItem'] class GridItem(UIGraphicsItem): diff --git a/graphicsItems/HistogramLUTItem.py b/graphicsItems/HistogramLUTItem.py index 5a3b63d6..8474202c 100644 --- a/graphicsItems/HistogramLUTItem.py +++ b/graphicsItems/HistogramLUTItem.py @@ -3,8 +3,8 @@ GraphicsWidget displaying an image histogram along with gradient editor. Can be """ -from pyqtgraph.Qt import QtGui, QtCore -import pyqtgraph.functions as fn +from ..Qt import QtGui, QtCore +from .. import functions as fn from .GraphicsWidget import GraphicsWidget from .ViewBox import * from .GradientEditorItem import * @@ -12,10 +12,10 @@ from .LinearRegionItem import * from .PlotDataItem import * from .AxisItem import * from .GridItem import * -from pyqtgraph.Point import Point -import pyqtgraph.functions as fn +from ..Point import Point +from .. import functions as fn import numpy as np -import pyqtgraph.debug as debug +from .. import debug as debug __all__ = ['HistogramLUTItem'] @@ -184,19 +184,18 @@ class HistogramLUTItem(GraphicsWidget): self.update() def imageChanged(self, autoLevel=False, autoRange=False): - prof = debug.Profiler('HistogramLUTItem.imageChanged', disabled=True) + profiler = debug.Profiler() h = self.imageItem.getHistogram() - prof.mark('get histogram') + profiler('get histogram') if h[0] is None: return self.plot.setData(*h) - prof.mark('set plot') + profiler('set plot') if autoLevel: mn = h[0][0] mx = h[0][-1] self.region.setRegion([mn, mx]) - prof.mark('set region') - prof.finish() + profiler('set region') def getLevels(self): return self.region.getRegion() diff --git a/graphicsItems/ImageItem.py b/graphicsItems/ImageItem.py index 530db7fb..120312ad 100644 --- a/graphicsItems/ImageItem.py +++ b/graphicsItems/ImageItem.py @@ -1,8 +1,8 @@ -from pyqtgraph.Qt import QtGui, QtCore +from ..Qt import QtGui, QtCore import numpy as np import collections -import pyqtgraph.functions as fn -import pyqtgraph.debug as debug +from .. import functions as fn +from .. import debug as debug from .GraphicsObject import GraphicsObject __all__ = ['ImageItem'] @@ -188,8 +188,8 @@ class ImageItem(GraphicsObject): border Sets the pen used when drawing the image border. Default is None. ================= ========================================================================= """ - prof = debug.Profiler('ImageItem.setImage', disabled=True) - + profile = debug.Profiler() + gotNewData = False if image is None: if self.image is None: @@ -201,9 +201,9 @@ class ImageItem(GraphicsObject): if shapeChanged: self.prepareGeometryChange() self.informViewBoundsChanged() - - prof.mark('1') - + + profile() + if autoLevels is None: if 'levels' in kargs: autoLevels = False @@ -218,23 +218,22 @@ class ImageItem(GraphicsObject): mn = 0 mx = 255 kargs['levels'] = [mn,mx] - prof.mark('2') - + + profile() + self.setOpts(update=False, **kargs) - prof.mark('3') - + + profile() + self.qimage = None self.update() - prof.mark('4') + + profile() if gotNewData: self.sigImageChanged.emit() - prof.finish() - - - def updateImage(self, *args, **kargs): ## used for re-rendering qimage from self.image. @@ -250,7 +249,7 @@ class ImageItem(GraphicsObject): def render(self): - prof = debug.Profiler('ImageItem.render', disabled=True) + profile = debug.Profiler() if self.image is None or self.image.size == 0: return if isinstance(self.lut, collections.Callable): @@ -260,30 +259,27 @@ class ImageItem(GraphicsObject): #print lut.shape #print self.lut - argb, alpha = fn.makeARGB(self.image, lut=lut, levels=self.levels) - self.qimage = fn.makeQImage(argb, alpha) - prof.finish() - + argb, alpha = fn.makeARGB(self.image.transpose((1, 0, 2)[:self.image.ndim]), lut=lut, levels=self.levels) + self.qimage = fn.makeQImage(argb, alpha, transpose=False) def paint(self, p, *args): - prof = debug.Profiler('ImageItem.paint', disabled=True) + profile = debug.Profiler() if self.image is None: return if self.qimage is None: self.render() if self.qimage is None: return - prof.mark('render QImage') + profile('render QImage') if self.paintMode is not None: p.setCompositionMode(self.paintMode) - prof.mark('set comp mode') - + profile('set comp mode') + p.drawImage(QtCore.QPointF(0,0), self.qimage) - prof.mark('p.drawImage') + profile('p.drawImage') if self.border is not None: p.setPen(self.border) p.drawRect(self.boundingRect()) - prof.finish() def save(self, fileName, *args): """Save this image to file. Note that this saves the visible image (after scale/color changes), not the original data.""" diff --git a/graphicsItems/InfiniteLine.py b/graphicsItems/InfiniteLine.py index 4f0df863..edf6b19e 100644 --- a/graphicsItems/InfiniteLine.py +++ b/graphicsItems/InfiniteLine.py @@ -1,7 +1,7 @@ -from pyqtgraph.Qt import QtGui, QtCore -from pyqtgraph.Point import Point +from ..Qt import QtGui, QtCore +from ..Point import Point from .GraphicsObject import GraphicsObject -import pyqtgraph.functions as fn +from .. import functions as fn import numpy as np import weakref diff --git a/graphicsItems/IsocurveItem.py b/graphicsItems/IsocurveItem.py index 01ef57b6..71113ba8 100644 --- a/graphicsItems/IsocurveItem.py +++ b/graphicsItems/IsocurveItem.py @@ -1,8 +1,8 @@ from .GraphicsObject import * -import pyqtgraph.functions as fn -from pyqtgraph.Qt import QtGui, QtCore +from .. import functions as fn +from ..Qt import QtGui, QtCore class IsocurveItem(GraphicsObject): diff --git a/graphicsItems/ItemGroup.py b/graphicsItems/ItemGroup.py index 930fdf80..4eb0ee0d 100644 --- a/graphicsItems/ItemGroup.py +++ b/graphicsItems/ItemGroup.py @@ -1,4 +1,4 @@ -from pyqtgraph.Qt import QtGui, QtCore +from ..Qt import QtGui, QtCore from .GraphicsObject import GraphicsObject __all__ = ['ItemGroup'] diff --git a/graphicsItems/LabelItem.py b/graphicsItems/LabelItem.py index 6101c4bc..37980ee3 100644 --- a/graphicsItems/LabelItem.py +++ b/graphicsItems/LabelItem.py @@ -1,8 +1,8 @@ -from pyqtgraph.Qt import QtGui, QtCore -import pyqtgraph.functions as fn -import pyqtgraph as pg +from ..Qt import QtGui, QtCore +from .. import functions as fn from .GraphicsWidget import GraphicsWidget from .GraphicsWidgetAnchor import GraphicsWidgetAnchor +from .. import getConfigOption __all__ = ['LabelItem'] @@ -54,7 +54,7 @@ class LabelItem(GraphicsWidget, GraphicsWidgetAnchor): color = self.opts['color'] if color is None: - color = pg.getConfigOption('foreground') + color = getConfigOption('foreground') color = fn.mkColor(color) optlist.append('color: #' + fn.colorStr(color)[:6]) if 'size' in opts: diff --git a/graphicsItems/LegendItem.py b/graphicsItems/LegendItem.py index 69ddffea..a1228789 100644 --- a/graphicsItems/LegendItem.py +++ b/graphicsItems/LegendItem.py @@ -3,8 +3,9 @@ from .LabelItem import LabelItem from ..Qt import QtGui, QtCore from .. import functions as fn from ..Point import Point +from .ScatterPlotItem import ScatterPlotItem +from .PlotDataItem import PlotDataItem from .GraphicsWidgetAnchor import GraphicsWidgetAnchor -import pyqtgraph as pg __all__ = ['LegendItem'] class LegendItem(GraphicsWidget, GraphicsWidgetAnchor): @@ -152,21 +153,21 @@ class ItemSample(GraphicsWidget): p.setPen(fn.mkPen(None)) p.drawPolygon(QtGui.QPolygonF([QtCore.QPointF(2,18), QtCore.QPointF(18,2), QtCore.QPointF(18,18)])) - if not isinstance(self.item, pg.ScatterPlotItem): + if not isinstance(self.item, ScatterPlotItem): p.setPen(fn.mkPen(opts['pen'])) p.drawLine(2, 18, 18, 2) symbol = opts.get('symbol', None) if symbol is not None: - if isinstance(self.item, pg.PlotDataItem): + if isinstance(self.item, PlotDataItem): opts = self.item.scatter.opts - pen = pg.mkPen(opts['pen']) - brush = pg.mkBrush(opts['brush']) + pen = fn.mkPen(opts['pen']) + brush = fn.mkBrush(opts['brush']) size = opts['size'] p.translate(10,10) - path = pg.graphicsItems.ScatterPlotItem.drawSymbol(p, symbol, size, pen, brush) + path = ScatterPlotItem.drawSymbol(p, symbol, size, pen, brush) diff --git a/graphicsItems/LinearRegionItem.py b/graphicsItems/LinearRegionItem.py index a35e8efc..4f9d28dc 100644 --- a/graphicsItems/LinearRegionItem.py +++ b/graphicsItems/LinearRegionItem.py @@ -1,8 +1,8 @@ -from pyqtgraph.Qt import QtGui, QtCore +from ..Qt import QtGui, QtCore from .UIGraphicsItem import UIGraphicsItem from .InfiniteLine import InfiniteLine -import pyqtgraph.functions as fn -import pyqtgraph.debug as debug +from .. import functions as fn +from .. import debug as debug __all__ = ['LinearRegionItem'] @@ -140,12 +140,11 @@ class LinearRegionItem(UIGraphicsItem): return br.normalized() def paint(self, p, *args): - #prof = debug.Profiler('LinearRegionItem.paint') + profiler = debug.Profiler() UIGraphicsItem.paint(self, p, *args) p.setBrush(self.currentBrush) p.setPen(fn.mkPen(None)) p.drawRect(self.boundingRect()) - #prof.finish() def dataBounds(self, axis, frac=1.0, orthoRange=None): if axis == self.orientation: diff --git a/graphicsItems/PlotCurveItem.py b/graphicsItems/PlotCurveItem.py index 28214552..b2beaa99 100644 --- a/graphicsItems/PlotCurveItem.py +++ b/graphicsItems/PlotCurveItem.py @@ -1,17 +1,17 @@ -from pyqtgraph.Qt import QtGui, QtCore +from ..Qt import QtGui, QtCore try: - from pyqtgraph.Qt import QtOpenGL + from ..Qt import QtOpenGL HAVE_OPENGL = True except: HAVE_OPENGL = False import numpy as np from .GraphicsObject import GraphicsObject -import pyqtgraph.functions as fn -from pyqtgraph import debug -from pyqtgraph.Point import Point -import pyqtgraph as pg +from .. import functions as fn +from ..Point import Point import struct, sys +from .. import getConfigOption +from .. import debug __all__ = ['PlotCurveItem'] class PlotCurveItem(GraphicsObject): @@ -53,9 +53,6 @@ class PlotCurveItem(GraphicsObject): """ GraphicsObject.__init__(self, kargs.get('parent', None)) self.clear() - self.path = None - self.fillPath = None - self._boundsCache = [None, None] ## this is disastrous for performance. #self.setCacheMode(QtGui.QGraphicsItem.DeviceCoordinateCache) @@ -68,8 +65,9 @@ class PlotCurveItem(GraphicsObject): 'brush': None, 'stepMode': False, 'name': None, - 'antialias': pg.getConfigOption('antialias'),\ + 'antialias': getConfigOption('antialias'), 'connect': 'all', + 'mouseWidth': 8, # width of shape responding to mouse click } self.setClickable(kargs.get('clickable', False)) self.setData(*args, **kargs) @@ -80,9 +78,20 @@ class PlotCurveItem(GraphicsObject): return ints return interface in ints - def setClickable(self, s): - """Sets whether the item responds to mouse clicks.""" + def name(self): + return self.opts.get('name', None) + + def setClickable(self, s, width=None): + """Sets whether the item responds to mouse clicks. + + The *width* argument specifies the width in pixels orthogonal to the + curve that will respond to a mouse click. + """ self.clickable = s + if width is not None: + self.opts['mouseWidth'] = width + self._mouseShape = None + self._boundingRect = None def getData(self): @@ -148,6 +157,8 @@ class PlotCurveItem(GraphicsObject): w += pen.widthF()*0.7072 if spen is not None and spen.isCosmetic() and spen.style() != QtCore.Qt.NoPen: w = max(w, spen.widthF()*0.7072) + if self.clickable: + w = max(w, self.opts['mouseWidth']//2 + 1) return w def boundingRect(self): @@ -171,6 +182,7 @@ class PlotCurveItem(GraphicsObject): #px += self._maxSpotWidth * 0.5 #py += self._maxSpotWidth * 0.5 self._boundingRect = QtCore.QRectF(xmn-px, ymn-py, (2*px)+xmx-xmn, (2*py)+ymx-ymn) + return self._boundingRect def viewTransformChanged(self): @@ -281,7 +293,7 @@ class PlotCurveItem(GraphicsObject): self.updateData(*args, **kargs) def updateData(self, *args, **kargs): - prof = debug.Profiler('PlotCurveItem.updateData', disabled=True) + profiler = debug.Profiler() if len(args) == 1: kargs['y'] = args[0] @@ -304,7 +316,7 @@ class PlotCurveItem(GraphicsObject): if 'complex' in str(data.dtype): raise Exception("Can not plot complex data types.") - prof.mark("data checks") + profiler("data checks") #self.setCacheMode(QtGui.QGraphicsItem.NoCache) ## Disabling and re-enabling the cache works around a bug in Qt 4.6 causing the cached results to display incorrectly ## Test this bug with test_PlotWidget and zoom in on the animated plot @@ -314,7 +326,7 @@ class PlotCurveItem(GraphicsObject): self.yData = kargs['y'].view(np.ndarray) self.xData = kargs['x'].view(np.ndarray) - prof.mark('copy') + profiler('copy') if 'stepMode' in kargs: self.opts['stepMode'] = kargs['stepMode'] @@ -328,6 +340,7 @@ class PlotCurveItem(GraphicsObject): self.path = None self.fillPath = None + self._mouseShape = None #self.xDisp = self.yDisp = None if 'name' in kargs: @@ -346,12 +359,11 @@ class PlotCurveItem(GraphicsObject): self.opts['antialias'] = kargs['antialias'] - prof.mark('set') + profiler('set') self.update() - prof.mark('update') + profiler('update') self.sigPlotChanged.emit(self) - prof.mark('emit') - prof.finish() + profiler('emit') def generatePath(self, x, y): if self.opts['stepMode']: @@ -377,35 +389,31 @@ class PlotCurveItem(GraphicsObject): return path - def shape(self): + def getPath(self): if self.path is None: - try: - self.path = self.generatePath(*self.getData()) - except: + x,y = self.getData() + if x is None or len(x) == 0 or y is None or len(y) == 0: return QtGui.QPainterPath() + self.path = self.generatePath(*self.getData()) + self.fillPath = None + self._mouseShape = None return self.path - @pg.debug.warnOnException ## raising an exception here causes crash + @debug.warnOnException ## raising an exception here causes crash def paint(self, p, opt, widget): - prof = debug.Profiler('PlotCurveItem.paint '+str(id(self)), disabled=True) + profiler = debug.Profiler() if self.xData is None: return - if HAVE_OPENGL and pg.getConfigOption('enableExperimental') and isinstance(widget, QtOpenGL.QGLWidget): + if HAVE_OPENGL and getConfigOption('enableExperimental') and isinstance(widget, QtOpenGL.QGLWidget): self.paintGL(p, opt, widget) return x = None y = None - if self.path is None: - x,y = self.getData() - if x is None or len(x) == 0 or y is None or len(y) == 0: - return - self.path = self.generatePath(x,y) - self.fillPath = None - - path = self.path - prof.mark('generate path') + path = self.getPath() + + profiler('generate path') if self._exportOpts is not False: aa = self._exportOpts.get('antialias', True) @@ -426,9 +434,9 @@ class PlotCurveItem(GraphicsObject): p2.closeSubpath() self.fillPath = p2 - prof.mark('generate fill path') + profiler('generate fill path') p.fillPath(self.fillPath, self.opts['brush']) - prof.mark('draw fill path') + profiler('draw fill path') sp = fn.mkPen(self.opts['shadowPen']) cp = fn.mkPen(self.opts['pen']) @@ -451,10 +459,9 @@ class PlotCurveItem(GraphicsObject): p.drawPath(path) p.setPen(cp) p.drawPath(path) - prof.mark('drawPath') + profiler('drawPath') #print "Render hints:", int(p.renderHints()) - prof.finish() #p.setPen(QtGui.QPen(QtGui.QColor(255,0,0))) #p.drawRect(self.boundingRect()) @@ -524,13 +531,36 @@ class PlotCurveItem(GraphicsObject): self.xDisp = None ## display values (after log / fft) self.yDisp = None self.path = None + self.fillPath = None + self._mouseShape = None + self._mouseBounds = None + self._boundsCache = [None, None] #del self.xData, self.yData, self.xDisp, self.yDisp, self.path + + def mouseShape(self): + """ + Return a QPainterPath representing the clickable shape of the curve + + """ + if self._mouseShape is None: + view = self.getViewBox() + if view is None: + return QtGui.QPainterPath() + stroker = QtGui.QPainterPathStroker() + path = self.getPath() + path = self.mapToItem(view, path) + stroker.setWidth(self.opts['mouseWidth']) + mousePath = stroker.createStroke(path) + self._mouseShape = self.mapFromItem(view, mousePath) + return self._mouseShape def mouseClickEvent(self, ev): if not self.clickable or ev.button() != QtCore.Qt.LeftButton: return - ev.accept() - self.sigClicked.emit(self) + if self.mouseShape().contains(ev.pos()): + ev.accept() + self.sigClicked.emit(self) + class ROIPlotItem(PlotCurveItem): diff --git a/graphicsItems/PlotDataItem.py b/graphicsItems/PlotDataItem.py index 87b47227..e8c4145c 100644 --- a/graphicsItems/PlotDataItem.py +++ b/graphicsItems/PlotDataItem.py @@ -1,12 +1,12 @@ -import pyqtgraph.metaarray as metaarray -from pyqtgraph.Qt import QtCore +from .. import metaarray as metaarray +from ..Qt import QtCore from .GraphicsObject import GraphicsObject from .PlotCurveItem import PlotCurveItem from .ScatterPlotItem import ScatterPlotItem import numpy as np -import pyqtgraph.functions as fn -import pyqtgraph.debug as debug -import pyqtgraph as pg +from .. import functions as fn +from .. import debug as debug +from .. import getConfigOption class PlotDataItem(GraphicsObject): """ @@ -152,7 +152,7 @@ class PlotDataItem(GraphicsObject): 'symbolBrush': (50, 50, 150), 'pxMode': True, - 'antialias': pg.getConfigOption('antialias'), + 'antialias': getConfigOption('antialias'), 'pointMode': None, 'downsample': 1, @@ -170,6 +170,9 @@ class PlotDataItem(GraphicsObject): return ints return interface in ints + def name(self): + return self.opts.get('name', None) + def boundingRect(self): return QtCore.QRectF() ## let child items handle this @@ -333,7 +336,7 @@ class PlotDataItem(GraphicsObject): See :func:`__init__() ` for details; it accepts the same arguments. """ #self.clear() - prof = debug.Profiler('PlotDataItem.setData (0x%x)' % id(self), disabled=True) + profiler = debug.Profiler() y = None x = None if len(args) == 1: @@ -383,7 +386,7 @@ class PlotDataItem(GraphicsObject): if 'y' in kargs: y = kargs['y'] - prof.mark('interpret data') + profiler('interpret data') ## pull in all style arguments. ## Use self.opts to fill in anything not present in kargs. @@ -432,10 +435,10 @@ class PlotDataItem(GraphicsObject): self.xClean = self.yClean = None self.xDisp = None self.yDisp = None - prof.mark('set data') + profiler('set data') self.updateItems() - prof.mark('update items') + profiler('update items') self.informViewBoundsChanged() #view = self.getViewBox() @@ -443,9 +446,7 @@ class PlotDataItem(GraphicsObject): #view.itemBoundsChanged(self) ## inform view so it can update its range if it wants self.sigPlotChanged.emit(self) - prof.mark('emit') - prof.finish() - + profiler('emit') def updateItems(self): diff --git a/graphicsItems/PlotItem/PlotItem.py b/graphicsItems/PlotItem/PlotItem.py index ec0960ba..baff1aa9 100644 --- a/graphicsItems/PlotItem/PlotItem.py +++ b/graphicsItems/PlotItem/PlotItem.py @@ -16,16 +16,16 @@ This class is very heavily featured: - Control panel with a huge feature set including averaging, decimation, display, power spectrum, svg/png export, plot linking, and more. """ -from pyqtgraph.Qt import QtGui, QtCore, QtSvg, USE_PYSIDE -import pyqtgraph.pixmaps +from ...Qt import QtGui, QtCore, QtSvg, USE_PYSIDE +from ... import pixmaps if USE_PYSIDE: from .plotConfigTemplate_pyside import * else: from .plotConfigTemplate_pyqt import * -import pyqtgraph.functions as fn -from pyqtgraph.widgets.FileDialog import FileDialog +from ... import functions as fn +from ...widgets.FileDialog import FileDialog import weakref import numpy as np import os @@ -37,7 +37,7 @@ from .. LegendItem import LegendItem from .. GraphicsWidget import GraphicsWidget from .. ButtonItem import ButtonItem from .. InfiniteLine import InfiniteLine -from pyqtgraph.WidgetGroup import WidgetGroup +from ...WidgetGroup import WidgetGroup __all__ = ['PlotItem'] @@ -129,7 +129,7 @@ class PlotItem(GraphicsWidget): path = os.path.dirname(__file__) #self.autoImageFile = os.path.join(path, 'auto.png') #self.lockImageFile = os.path.join(path, 'lock.png') - self.autoBtn = ButtonItem(pyqtgraph.pixmaps.getPixmap('auto'), 14, self) + self.autoBtn = ButtonItem(pixmaps.getPixmap('auto'), 14, self) self.autoBtn.mode = 'auto' self.autoBtn.clicked.connect(self.autoBtnClicked) #self.autoBtn.hide() @@ -339,9 +339,8 @@ class PlotItem(GraphicsWidget): self.ctrl.gridAlphaSlider.setValue(v) #def paint(self, *args): - #prof = debug.Profiler('PlotItem.paint', disabled=True) + #prof = debug.Profiler() #QtGui.QGraphicsWidget.paint(self, *args) - #prof.finish() ## bad idea. #def __getattr__(self, attr): ## wrap ms @@ -515,7 +514,9 @@ class PlotItem(GraphicsWidget): if 'ignoreBounds' in kargs: vbargs['ignoreBounds'] = kargs['ignoreBounds'] self.vb.addItem(item, *args, **vbargs) + name = None if hasattr(item, 'implements') and item.implements('plotData'): + name = item.name() self.dataItems.append(item) #self.plotChanged() @@ -548,7 +549,7 @@ class PlotItem(GraphicsWidget): #c.connect(c, QtCore.SIGNAL('plotChanged'), self.plotChanged) #item.sigPlotChanged.connect(self.plotChanged) #self.plotChanged() - name = kargs.get('name', getattr(item, 'opts', {}).get('name', None)) + #name = kargs.get('name', getattr(item, 'opts', {}).get('name', None)) if name is not None and hasattr(self, 'legend') and self.legend is not None: self.legend.addItem(item, name=name) diff --git a/graphicsItems/PlotItem/plotConfigTemplate_pyqt.py b/graphicsItems/PlotItem/plotConfigTemplate_pyqt.py index 5335ee76..e09c9978 100644 --- a/graphicsItems/PlotItem/plotConfigTemplate_pyqt.py +++ b/graphicsItems/PlotItem/plotConfigTemplate_pyqt.py @@ -2,8 +2,8 @@ # Form implementation generated from reading ui file './pyqtgraph/graphicsItems/PlotItem/plotConfigTemplate.ui' # -# Created: Mon Jul 1 23:21:08 2013 -# by: PyQt4 UI code generator 4.9.3 +# Created: Mon Dec 23 10:10:51 2013 +# by: PyQt4 UI code generator 4.10 # # WARNING! All changes made in this file will be lost! @@ -12,7 +12,16 @@ from PyQt4 import QtCore, QtGui try: _fromUtf8 = QtCore.QString.fromUtf8 except AttributeError: - _fromUtf8 = lambda s: s + def _fromUtf8(s): + return s + +try: + _encoding = QtGui.QApplication.UnicodeUTF8 + def _translate(context, text, disambig): + return QtGui.QApplication.translate(context, text, disambig, _encoding) +except AttributeError: + def _translate(context, text, disambig): + return QtGui.QApplication.translate(context, text, disambig) class Ui_Form(object): def setupUi(self, Form): @@ -139,35 +148,35 @@ class Ui_Form(object): QtCore.QMetaObject.connectSlotsByName(Form) def retranslateUi(self, Form): - Form.setWindowTitle(QtGui.QApplication.translate("Form", "Form", None, QtGui.QApplication.UnicodeUTF8)) - self.averageGroup.setToolTip(QtGui.QApplication.translate("Form", "Display averages of the curves displayed in this plot. The parameter list allows you to choose parameters to average over (if any are available).", None, QtGui.QApplication.UnicodeUTF8)) - self.averageGroup.setTitle(QtGui.QApplication.translate("Form", "Average", None, QtGui.QApplication.UnicodeUTF8)) - self.clipToViewCheck.setToolTip(QtGui.QApplication.translate("Form", "Plot only the portion of each curve that is visible. This assumes X values are uniformly spaced.", None, QtGui.QApplication.UnicodeUTF8)) - self.clipToViewCheck.setText(QtGui.QApplication.translate("Form", "Clip to View", None, QtGui.QApplication.UnicodeUTF8)) - self.maxTracesCheck.setToolTip(QtGui.QApplication.translate("Form", "If multiple curves are displayed in this plot, check this box to limit the number of traces that are displayed.", None, QtGui.QApplication.UnicodeUTF8)) - self.maxTracesCheck.setText(QtGui.QApplication.translate("Form", "Max Traces:", None, QtGui.QApplication.UnicodeUTF8)) - self.downsampleCheck.setText(QtGui.QApplication.translate("Form", "Downsample", None, QtGui.QApplication.UnicodeUTF8)) - self.peakRadio.setToolTip(QtGui.QApplication.translate("Form", "Downsample by drawing a saw wave that follows the min and max of the original data. This method produces the best visual representation of the data but is slower.", None, QtGui.QApplication.UnicodeUTF8)) - self.peakRadio.setText(QtGui.QApplication.translate("Form", "Peak", None, QtGui.QApplication.UnicodeUTF8)) - self.maxTracesSpin.setToolTip(QtGui.QApplication.translate("Form", "If multiple curves are displayed in this plot, check \"Max Traces\" and set this value to limit the number of traces that are displayed.", None, QtGui.QApplication.UnicodeUTF8)) - self.forgetTracesCheck.setToolTip(QtGui.QApplication.translate("Form", "If MaxTraces is checked, remove curves from memory after they are hidden (saves memory, but traces can not be un-hidden).", None, QtGui.QApplication.UnicodeUTF8)) - self.forgetTracesCheck.setText(QtGui.QApplication.translate("Form", "Forget hidden traces", None, QtGui.QApplication.UnicodeUTF8)) - self.meanRadio.setToolTip(QtGui.QApplication.translate("Form", "Downsample by taking the mean of N samples.", None, QtGui.QApplication.UnicodeUTF8)) - self.meanRadio.setText(QtGui.QApplication.translate("Form", "Mean", None, QtGui.QApplication.UnicodeUTF8)) - self.subsampleRadio.setToolTip(QtGui.QApplication.translate("Form", "Downsample by taking the first of N samples. This method is fastest and least accurate.", None, QtGui.QApplication.UnicodeUTF8)) - self.subsampleRadio.setText(QtGui.QApplication.translate("Form", "Subsample", None, QtGui.QApplication.UnicodeUTF8)) - self.autoDownsampleCheck.setToolTip(QtGui.QApplication.translate("Form", "Automatically downsample data based on the visible range. This assumes X values are uniformly spaced.", None, QtGui.QApplication.UnicodeUTF8)) - self.autoDownsampleCheck.setText(QtGui.QApplication.translate("Form", "Auto", None, QtGui.QApplication.UnicodeUTF8)) - self.downsampleSpin.setToolTip(QtGui.QApplication.translate("Form", "Downsample data before plotting. (plot every Nth sample)", None, QtGui.QApplication.UnicodeUTF8)) - self.downsampleSpin.setSuffix(QtGui.QApplication.translate("Form", "x", None, QtGui.QApplication.UnicodeUTF8)) - self.fftCheck.setText(QtGui.QApplication.translate("Form", "Power Spectrum (FFT)", None, QtGui.QApplication.UnicodeUTF8)) - self.logXCheck.setText(QtGui.QApplication.translate("Form", "Log X", None, QtGui.QApplication.UnicodeUTF8)) - self.logYCheck.setText(QtGui.QApplication.translate("Form", "Log Y", None, QtGui.QApplication.UnicodeUTF8)) - self.pointsGroup.setTitle(QtGui.QApplication.translate("Form", "Points", None, QtGui.QApplication.UnicodeUTF8)) - self.autoPointsCheck.setText(QtGui.QApplication.translate("Form", "Auto", None, QtGui.QApplication.UnicodeUTF8)) - self.xGridCheck.setText(QtGui.QApplication.translate("Form", "Show X Grid", None, QtGui.QApplication.UnicodeUTF8)) - self.yGridCheck.setText(QtGui.QApplication.translate("Form", "Show Y Grid", None, QtGui.QApplication.UnicodeUTF8)) - self.label.setText(QtGui.QApplication.translate("Form", "Opacity", None, QtGui.QApplication.UnicodeUTF8)) - self.alphaGroup.setTitle(QtGui.QApplication.translate("Form", "Alpha", None, QtGui.QApplication.UnicodeUTF8)) - self.autoAlphaCheck.setText(QtGui.QApplication.translate("Form", "Auto", None, QtGui.QApplication.UnicodeUTF8)) + Form.setWindowTitle(_translate("Form", "Form", None)) + self.averageGroup.setToolTip(_translate("Form", "Display averages of the curves displayed in this plot. The parameter list allows you to choose parameters to average over (if any are available).", None)) + self.averageGroup.setTitle(_translate("Form", "Average", None)) + self.clipToViewCheck.setToolTip(_translate("Form", "Plot only the portion of each curve that is visible. This assumes X values are uniformly spaced.", None)) + self.clipToViewCheck.setText(_translate("Form", "Clip to View", None)) + self.maxTracesCheck.setToolTip(_translate("Form", "If multiple curves are displayed in this plot, check this box to limit the number of traces that are displayed.", None)) + self.maxTracesCheck.setText(_translate("Form", "Max Traces:", None)) + self.downsampleCheck.setText(_translate("Form", "Downsample", None)) + self.peakRadio.setToolTip(_translate("Form", "Downsample by drawing a saw wave that follows the min and max of the original data. This method produces the best visual representation of the data but is slower.", None)) + self.peakRadio.setText(_translate("Form", "Peak", None)) + self.maxTracesSpin.setToolTip(_translate("Form", "If multiple curves are displayed in this plot, check \"Max Traces\" and set this value to limit the number of traces that are displayed.", None)) + self.forgetTracesCheck.setToolTip(_translate("Form", "If MaxTraces is checked, remove curves from memory after they are hidden (saves memory, but traces can not be un-hidden).", None)) + self.forgetTracesCheck.setText(_translate("Form", "Forget hidden traces", None)) + self.meanRadio.setToolTip(_translate("Form", "Downsample by taking the mean of N samples.", None)) + self.meanRadio.setText(_translate("Form", "Mean", None)) + self.subsampleRadio.setToolTip(_translate("Form", "Downsample by taking the first of N samples. This method is fastest and least accurate.", None)) + self.subsampleRadio.setText(_translate("Form", "Subsample", None)) + self.autoDownsampleCheck.setToolTip(_translate("Form", "Automatically downsample data based on the visible range. This assumes X values are uniformly spaced.", None)) + self.autoDownsampleCheck.setText(_translate("Form", "Auto", None)) + self.downsampleSpin.setToolTip(_translate("Form", "Downsample data before plotting. (plot every Nth sample)", None)) + self.downsampleSpin.setSuffix(_translate("Form", "x", None)) + self.fftCheck.setText(_translate("Form", "Power Spectrum (FFT)", None)) + self.logXCheck.setText(_translate("Form", "Log X", None)) + self.logYCheck.setText(_translate("Form", "Log Y", None)) + self.pointsGroup.setTitle(_translate("Form", "Points", None)) + self.autoPointsCheck.setText(_translate("Form", "Auto", None)) + self.xGridCheck.setText(_translate("Form", "Show X Grid", None)) + self.yGridCheck.setText(_translate("Form", "Show Y Grid", None)) + self.label.setText(_translate("Form", "Opacity", None)) + self.alphaGroup.setTitle(_translate("Form", "Alpha", None)) + self.autoAlphaCheck.setText(_translate("Form", "Auto", None)) diff --git a/graphicsItems/PlotItem/plotConfigTemplate_pyside.py b/graphicsItems/PlotItem/plotConfigTemplate_pyside.py index b8e0b19e..aff31211 100644 --- a/graphicsItems/PlotItem/plotConfigTemplate_pyside.py +++ b/graphicsItems/PlotItem/plotConfigTemplate_pyside.py @@ -2,8 +2,8 @@ # Form implementation generated from reading ui file './pyqtgraph/graphicsItems/PlotItem/plotConfigTemplate.ui' # -# Created: Mon Jul 1 23:21:08 2013 -# by: pyside-uic 0.2.13 running on PySide 1.1.2 +# Created: Mon Dec 23 10:10:52 2013 +# by: pyside-uic 0.2.14 running on PySide 1.1.2 # # WARNING! All changes made in this file will be lost! diff --git a/graphicsItems/ROI.py b/graphicsItems/ROI.py index f6ce4680..0dee2fd4 100644 --- a/graphicsItems/ROI.py +++ b/graphicsItems/ROI.py @@ -12,16 +12,16 @@ The ROI class is meant to serve as the base for more specific types; see several of how to build an ROI at the bottom of the file. """ -from pyqtgraph.Qt import QtCore, QtGui +from ..Qt import QtCore, QtGui #if not hasattr(QtCore, 'Signal'): #QtCore.Signal = QtCore.pyqtSignal import numpy as np from numpy.linalg import norm import scipy.ndimage as ndimage -from pyqtgraph.Point import * -from pyqtgraph.SRTTransform import SRTTransform +from ..Point import * +from ..SRTTransform import SRTTransform from math import cos, sin -import pyqtgraph.functions as fn +from .. import functions as fn from .GraphicsObject import GraphicsObject from .UIGraphicsItem import UIGraphicsItem @@ -1202,11 +1202,7 @@ class Handle(UIGraphicsItem): def getMenu(self): return self.menu - - - def getContextMenus(self, event): - return [self.menu] - + def raiseContextMenu(self, ev): menu = self.scene().addParentContextMenus(self, self.getMenu(), ev) diff --git a/graphicsItems/ScaleBar.py b/graphicsItems/ScaleBar.py index 768f6978..66258678 100644 --- a/graphicsItems/ScaleBar.py +++ b/graphicsItems/ScaleBar.py @@ -1,10 +1,10 @@ -from pyqtgraph.Qt import QtGui, QtCore +from ..Qt import QtGui, QtCore from .GraphicsObject import * from .GraphicsWidgetAnchor import * from .TextItem import TextItem import numpy as np -import pyqtgraph.functions as fn -import pyqtgraph as pg +from .. import functions as fn +from .. import getConfigOption __all__ = ['ScaleBar'] @@ -19,7 +19,7 @@ class ScaleBar(GraphicsObject, GraphicsWidgetAnchor): self.setAcceptedMouseButtons(QtCore.Qt.NoButton) if brush is None: - brush = pg.getConfigOption('foreground') + brush = getConfigOption('foreground') self.brush = fn.mkBrush(brush) self.pen = fn.mkPen(pen) self._width = width diff --git a/graphicsItems/ScatterPlotItem.py b/graphicsItems/ScatterPlotItem.py index f1a5201d..926c9045 100644 --- a/graphicsItems/ScatterPlotItem.py +++ b/graphicsItems/ScatterPlotItem.py @@ -1,14 +1,14 @@ -from pyqtgraph.Qt import QtGui, QtCore, USE_PYSIDE -from pyqtgraph.Point import Point -import pyqtgraph.functions as fn +from ..Qt import QtGui, QtCore, USE_PYSIDE +from ..Point import Point +from .. import functions as fn from .GraphicsItem import GraphicsItem from .GraphicsObject import GraphicsObject import numpy as np import weakref -import pyqtgraph.debug as debug -from pyqtgraph.pgcollections import OrderedDict -import pyqtgraph as pg -#import pyqtgraph as pg +from .. import getConfigOption +from .. import debug as debug +from ..pgcollections import OrderedDict +from .. import debug __all__ = ['ScatterPlotItem', 'SpotItem'] @@ -219,7 +219,7 @@ class ScatterPlotItem(GraphicsObject): """ Accepts the same arguments as setData() """ - prof = debug.Profiler('ScatterPlotItem.__init__', disabled=True) + profiler = debug.Profiler() GraphicsObject.__init__(self) self.picture = None # QPicture used for rendering when pxmode==False @@ -233,18 +233,18 @@ class ScatterPlotItem(GraphicsObject): self.opts = { 'pxMode': True, 'useCache': True, ## If useCache is False, symbols are re-drawn on every paint. - 'antialias': pg.getConfigOption('antialias'), + 'antialias': getConfigOption('antialias'), + 'name': None, } self.setPen(200,200,200, update=False) self.setBrush(100,100,150, update=False) self.setSymbol('o', update=False) self.setSize(7, update=False) - prof.mark('1') + profiler() self.setData(*args, **kargs) - prof.mark('setData') - prof.finish() - + profiler('setData') + #self.setCacheMode(self.DeviceCoordinateCache) def setData(self, *args, **kargs): @@ -282,6 +282,8 @@ class ScatterPlotItem(GraphicsObject): *antialias* Whether to draw symbols with antialiasing. Note that if pxMode is True, symbols are always rendered with antialiasing (since the rendered symbols can be cached, this incurs very little performance cost) + *name* The name of this item. Names are used for automatically + generating LegendItem entries and by some exporters. ====================== =============================================================================================== """ oldData = self.data ## this causes cached pixmaps to be preserved while new data is registered. @@ -411,6 +413,9 @@ class ScatterPlotItem(GraphicsObject): return ints return interface in ints + def name(self): + return self.opts.get('name', None) + def setPen(self, *args, **kargs): """Set the pen(s) used to draw the outline around each spot. If a list or array is provided, then the pen for each spot will be set separately. @@ -688,7 +693,7 @@ class ScatterPlotItem(GraphicsObject): GraphicsObject.setExportMode(self, *args, **kwds) self.invalidate() - @pg.debug.warnOnException ## raising an exception here causes crash + @debug.warnOnException ## raising an exception here causes crash def paint(self, p, *args): #p.setPen(fn.mkPen('r')) diff --git a/graphicsItems/TextItem.py b/graphicsItems/TextItem.py index 911057f4..2b5ea51c 100644 --- a/graphicsItems/TextItem.py +++ b/graphicsItems/TextItem.py @@ -1,7 +1,7 @@ -from pyqtgraph.Qt import QtCore, QtGui -import pyqtgraph as pg +from ..Qt import QtCore, QtGui +from ..Point import Point from .UIGraphicsItem import * -import pyqtgraph.functions as fn +from .. import functions as fn class TextItem(UIGraphicsItem): """ @@ -27,7 +27,7 @@ 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.anchor = Point(anchor) #self.angle = 0 UIGraphicsItem.__init__(self) self.textItem = QtGui.QGraphicsTextItem() @@ -38,13 +38,13 @@ class TextItem(UIGraphicsItem): self.setText(text, color) else: self.setHtml(html) - self.fill = pg.mkBrush(fill) - self.border = pg.mkPen(border) + self.fill = fn.mkBrush(fill) + self.border = fn.mkPen(border) 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) + color = fn.mkColor(color) self.textItem.setDefaultTextColor(color) self.textItem.setPlainText(text) self.updateText() @@ -89,7 +89,7 @@ class TextItem(UIGraphicsItem): #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())) + apos = self.textItem.mapToParent(Point(br.width()*self.anchor.x(), br.height()*self.anchor.y())) #print br, apos self.textItem.setPos(-apos.x(), -apos.y()) diff --git a/graphicsItems/UIGraphicsItem.py b/graphicsItems/UIGraphicsItem.py index 19fda424..6f756334 100644 --- a/graphicsItems/UIGraphicsItem.py +++ b/graphicsItems/UIGraphicsItem.py @@ -1,4 +1,4 @@ -from pyqtgraph.Qt import QtGui, QtCore, USE_PYSIDE +from ..Qt import QtGui, QtCore, USE_PYSIDE import weakref from .GraphicsObject import GraphicsObject if not USE_PYSIDE: diff --git a/graphicsItems/VTickGroup.py b/graphicsItems/VTickGroup.py index c6880f91..4b315678 100644 --- a/graphicsItems/VTickGroup.py +++ b/graphicsItems/VTickGroup.py @@ -3,8 +3,8 @@ if __name__ == '__main__': path = os.path.abspath(os.path.dirname(__file__)) sys.path.insert(0, os.path.join(path, '..', '..')) -from pyqtgraph.Qt import QtGui, QtCore -import pyqtgraph.functions as fn +from ..Qt import QtGui, QtCore +from .. import functions as fn import weakref from .UIGraphicsItem import UIGraphicsItem @@ -96,18 +96,4 @@ class VTickGroup(UIGraphicsItem): p.setPen(self.pen) p.drawPath(self.path) - -if __name__ == '__main__': - app = QtGui.QApplication([]) - import pyqtgraph as pg - vt = VTickGroup([1,3,4,7,9], [0.8, 1.0]) - p = pg.plot() - p.addItem(vt) - - if sys.flags.interactive == 0: - app.exec_() - - - - \ No newline at end of file diff --git a/graphicsItems/ViewBox/ViewBox.py b/graphicsItems/ViewBox/ViewBox.py index 3cbb1ea2..70012ec4 100644 --- a/graphicsItems/ViewBox/ViewBox.py +++ b/graphicsItems/ViewBox/ViewBox.py @@ -1,15 +1,15 @@ -from pyqtgraph.Qt import QtGui, QtCore -from pyqtgraph.python2_3 import sortList +from ...Qt import QtGui, QtCore +from ...python2_3 import sortList import numpy as np -from pyqtgraph.Point import Point -import pyqtgraph.functions as fn +from ...Point import Point +from ... import functions as fn from .. ItemGroup import ItemGroup from .. GraphicsWidget import GraphicsWidget -from pyqtgraph.GraphicsScene import GraphicsScene -import pyqtgraph +from ...GraphicsScene import GraphicsScene import weakref from copy import deepcopy -import pyqtgraph.debug as debug +from ... import debug as debug +from ... import getConfigOption __all__ = ['ViewBox'] @@ -113,7 +113,7 @@ class ViewBox(GraphicsWidget): ## a name string indicates that the view *should* link to another, but no view with that name exists yet. 'mouseEnabled': [enableMouse, enableMouse], - 'mouseMode': ViewBox.PanMode if pyqtgraph.getConfigOption('leftButtonPan') else ViewBox.RectMode, + 'mouseMode': ViewBox.PanMode if getConfigOption('leftButtonPan') else ViewBox.RectMode, 'enableMenu': enableMenu, 'wheelScaleFactor': -1.0 / 8.0, @@ -1065,33 +1065,17 @@ class ViewBox(GraphicsWidget): if ev.button() == QtCore.Qt.RightButton and self.menuEnabled(): ev.accept() self.raiseContextMenu(ev) - + def raiseContextMenu(self, ev): - #print "viewbox.raiseContextMenu called." - - #menu = self.getMenu(ev) menu = self.getMenu(ev) self.scene().addParentContextMenus(self, menu, ev) - #print "2:", [str(a.text()) for a in self.menu.actions()] - pos = ev.screenPos() - #pos2 = ev.scenePos() - #print "3:", [str(a.text()) for a in self.menu.actions()] - #self.sigActionPositionChanged.emit(pos2) + menu.popup(ev.screenPos().toPoint()) - menu.popup(QtCore.QPoint(pos.x(), pos.y())) - #print "4:", [str(a.text()) for a in self.menu.actions()] - def getMenu(self, ev): - self._menuCopy = self.menu.copy() ## temporary storage to prevent menu disappearing - return self._menuCopy - + return self.menu + def getContextMenus(self, event): - if self.menuEnabled(): - return self.menu.subMenus() - else: - return None - #return [self.getMenu(event)] - + return self.menu.actions() if self.menuEnabled() else [] def mouseDragEvent(self, ev, axis=None): ## if axis is specified, event will only affect that axis. @@ -1221,7 +1205,7 @@ class ViewBox(GraphicsWidget): [[xmin, xmax], [ymin, ymax]] Values may be None if there are no specific bounds for an axis. """ - prof = debug.Profiler('updateAutoRange', disabled=True) + profiler = debug.Profiler() if items is None: items = self.addedItems @@ -1298,7 +1282,7 @@ class ViewBox(GraphicsWidget): range[0] = [min(bounds.left(), range[0][0]), max(bounds.right(), range[0][1])] else: range[0] = [bounds.left(), bounds.right()] - prof.mark('2') + profiler() #print "range", range @@ -1322,10 +1306,7 @@ class ViewBox(GraphicsWidget): continue range[1][0] = min(range[1][0], bounds.top() - px*pxSize) range[1][1] = max(range[1][1], bounds.bottom() + px*pxSize) - - #print "final range", range - - prof.finish() + return range def childrenBoundingRect(self, *args, **kwds): diff --git a/graphicsItems/ViewBox/ViewBoxMenu.py b/graphicsItems/ViewBox/ViewBoxMenu.py index 5242ecdd..af142771 100644 --- a/graphicsItems/ViewBox/ViewBoxMenu.py +++ b/graphicsItems/ViewBox/ViewBoxMenu.py @@ -1,6 +1,6 @@ -from pyqtgraph.Qt import QtCore, QtGui, USE_PYSIDE -from pyqtgraph.python2_3 import asUnicode -from pyqtgraph.WidgetGroup import WidgetGroup +from ...Qt import QtCore, QtGui, USE_PYSIDE +from ...python2_3 import asUnicode +from ...WidgetGroup import WidgetGroup if USE_PYSIDE: from .axisCtrlTemplate_pyside import Ui_Form as AxisCtrlTemplate @@ -88,22 +88,6 @@ class ViewBoxMenu(QtGui.QMenu): self.updateState() - def copy(self): - m = QtGui.QMenu() - for sm in self.subMenus(): - if isinstance(sm, QtGui.QMenu): - m.addMenu(sm) - else: - m.addAction(sm) - m.setTitle(self.title()) - return m - - def subMenus(self): - if not self.valid: - self.updateState() - return [self.viewAll] + self.axes + [self.leftMenu] - - def setExportMethods(self, methods): self.exportMethods = methods self.export.clear() @@ -159,6 +143,10 @@ class ViewBoxMenu(QtGui.QMenu): self.ctrl[1].invertCheck.setChecked(state['yInverted']) self.valid = True + def popup(self, *args): + if not self.valid: + self.updateState() + QtGui.QMenu.popup(self, *args) def autoRange(self): self.view().autoRange() ## don't let signal call this directly--it'll add an unwanted argument @@ -275,4 +263,4 @@ class ViewBoxMenu(QtGui.QMenu): from .ViewBox import ViewBox - \ No newline at end of file + diff --git a/graphicsItems/ViewBox/axisCtrlTemplate_pyqt.py b/graphicsItems/ViewBox/axisCtrlTemplate_pyqt.py index db14033e..d8ef1925 100644 --- a/graphicsItems/ViewBox/axisCtrlTemplate_pyqt.py +++ b/graphicsItems/ViewBox/axisCtrlTemplate_pyqt.py @@ -1,9 +1,9 @@ # -*- coding: utf-8 -*- -# Form implementation generated from reading ui file './graphicsItems/ViewBox/axisCtrlTemplate.ui' +# Form implementation generated from reading ui file './pyqtgraph/graphicsItems/ViewBox/axisCtrlTemplate.ui' # -# Created: Sun Sep 9 14:41:31 2012 -# by: PyQt4 UI code generator 4.9.1 +# Created: Mon Dec 23 10:10:51 2013 +# by: PyQt4 UI code generator 4.10 # # WARNING! All changes made in this file will be lost! @@ -12,7 +12,16 @@ from PyQt4 import QtCore, QtGui try: _fromUtf8 = QtCore.QString.fromUtf8 except AttributeError: - _fromUtf8 = lambda s: s + def _fromUtf8(s): + return s + +try: + _encoding = QtGui.QApplication.UnicodeUTF8 + def _translate(context, text, disambig): + return QtGui.QApplication.translate(context, text, disambig, _encoding) +except AttributeError: + def _translate(context, text, disambig): + return QtGui.QApplication.translate(context, text, disambig) class Ui_Form(object): def setupUi(self, Form): @@ -69,25 +78,25 @@ class Ui_Form(object): QtCore.QMetaObject.connectSlotsByName(Form) def retranslateUi(self, Form): - Form.setWindowTitle(QtGui.QApplication.translate("Form", "Form", None, QtGui.QApplication.UnicodeUTF8)) - self.label.setText(QtGui.QApplication.translate("Form", "Link Axis:", None, QtGui.QApplication.UnicodeUTF8)) - self.linkCombo.setToolTip(QtGui.QApplication.translate("Form", "

Links this axis with another view. When linked, both views will display the same data range.

", None, QtGui.QApplication.UnicodeUTF8)) - self.autoPercentSpin.setToolTip(QtGui.QApplication.translate("Form", "

Percent of data to be visible when auto-scaling. It may be useful to decrease this value for data with spiky noise.

", None, QtGui.QApplication.UnicodeUTF8)) - self.autoPercentSpin.setSuffix(QtGui.QApplication.translate("Form", "%", None, QtGui.QApplication.UnicodeUTF8)) - self.autoRadio.setToolTip(QtGui.QApplication.translate("Form", "

Automatically resize this axis whenever the displayed data is changed.

", None, QtGui.QApplication.UnicodeUTF8)) - self.autoRadio.setText(QtGui.QApplication.translate("Form", "Auto", None, QtGui.QApplication.UnicodeUTF8)) - self.manualRadio.setToolTip(QtGui.QApplication.translate("Form", "

Set the range for this axis manually. This disables automatic scaling.

", None, QtGui.QApplication.UnicodeUTF8)) - self.manualRadio.setText(QtGui.QApplication.translate("Form", "Manual", None, QtGui.QApplication.UnicodeUTF8)) - self.minText.setToolTip(QtGui.QApplication.translate("Form", "

Minimum value to display for this axis.

", None, QtGui.QApplication.UnicodeUTF8)) - self.minText.setText(QtGui.QApplication.translate("Form", "0", None, QtGui.QApplication.UnicodeUTF8)) - self.maxText.setToolTip(QtGui.QApplication.translate("Form", "

Maximum value to display for this axis.

", None, QtGui.QApplication.UnicodeUTF8)) - self.maxText.setText(QtGui.QApplication.translate("Form", "0", None, QtGui.QApplication.UnicodeUTF8)) - self.invertCheck.setToolTip(QtGui.QApplication.translate("Form", "

Inverts the display of this axis. (+y points downward instead of upward)

", None, QtGui.QApplication.UnicodeUTF8)) - self.invertCheck.setText(QtGui.QApplication.translate("Form", "Invert Axis", None, QtGui.QApplication.UnicodeUTF8)) - self.mouseCheck.setToolTip(QtGui.QApplication.translate("Form", "

Enables mouse interaction (panning, scaling) for this axis.

", None, QtGui.QApplication.UnicodeUTF8)) - self.mouseCheck.setText(QtGui.QApplication.translate("Form", "Mouse Enabled", None, QtGui.QApplication.UnicodeUTF8)) - self.visibleOnlyCheck.setToolTip(QtGui.QApplication.translate("Form", "

When checked, the axis will only auto-scale to data that is visible along the orthogonal axis.

", None, QtGui.QApplication.UnicodeUTF8)) - self.visibleOnlyCheck.setText(QtGui.QApplication.translate("Form", "Visible Data Only", None, QtGui.QApplication.UnicodeUTF8)) - self.autoPanCheck.setToolTip(QtGui.QApplication.translate("Form", "

When checked, the axis will automatically pan to center on the current data, but the scale along this axis will not change.

", None, QtGui.QApplication.UnicodeUTF8)) - self.autoPanCheck.setText(QtGui.QApplication.translate("Form", "Auto Pan Only", None, QtGui.QApplication.UnicodeUTF8)) + Form.setWindowTitle(_translate("Form", "Form", None)) + self.label.setText(_translate("Form", "Link Axis:", None)) + self.linkCombo.setToolTip(_translate("Form", "

Links this axis with another view. When linked, both views will display the same data range.

", None)) + self.autoPercentSpin.setToolTip(_translate("Form", "

Percent of data to be visible when auto-scaling. It may be useful to decrease this value for data with spiky noise.

", None)) + self.autoPercentSpin.setSuffix(_translate("Form", "%", None)) + self.autoRadio.setToolTip(_translate("Form", "

Automatically resize this axis whenever the displayed data is changed.

", None)) + self.autoRadio.setText(_translate("Form", "Auto", None)) + self.manualRadio.setToolTip(_translate("Form", "

Set the range for this axis manually. This disables automatic scaling.

", None)) + self.manualRadio.setText(_translate("Form", "Manual", None)) + self.minText.setToolTip(_translate("Form", "

Minimum value to display for this axis.

", None)) + self.minText.setText(_translate("Form", "0", None)) + self.maxText.setToolTip(_translate("Form", "

Maximum value to display for this axis.

", None)) + self.maxText.setText(_translate("Form", "0", None)) + self.invertCheck.setToolTip(_translate("Form", "

Inverts the display of this axis. (+y points downward instead of upward)

", None)) + self.invertCheck.setText(_translate("Form", "Invert Axis", None)) + self.mouseCheck.setToolTip(_translate("Form", "

Enables mouse interaction (panning, scaling) for this axis.

", None)) + self.mouseCheck.setText(_translate("Form", "Mouse Enabled", None)) + self.visibleOnlyCheck.setToolTip(_translate("Form", "

When checked, the axis will only auto-scale to data that is visible along the orthogonal axis.

", None)) + self.visibleOnlyCheck.setText(_translate("Form", "Visible Data Only", None)) + self.autoPanCheck.setToolTip(_translate("Form", "

When checked, the axis will automatically pan to center on the current data, but the scale along this axis will not change.

", None)) + self.autoPanCheck.setText(_translate("Form", "Auto Pan Only", None)) diff --git a/graphicsItems/ViewBox/axisCtrlTemplate_pyside.py b/graphicsItems/ViewBox/axisCtrlTemplate_pyside.py index 18510bc2..9ddeb5d1 100644 --- a/graphicsItems/ViewBox/axisCtrlTemplate_pyside.py +++ b/graphicsItems/ViewBox/axisCtrlTemplate_pyside.py @@ -1,9 +1,9 @@ # -*- coding: utf-8 -*- -# Form implementation generated from reading ui file './graphicsItems/ViewBox/axisCtrlTemplate.ui' +# Form implementation generated from reading ui file './pyqtgraph/graphicsItems/ViewBox/axisCtrlTemplate.ui' # -# Created: Sun Sep 9 14:41:32 2012 -# by: pyside-uic 0.2.13 running on PySide 1.1.0 +# Created: Mon Dec 23 10:10:51 2013 +# by: pyside-uic 0.2.14 running on PySide 1.1.2 # # WARNING! All changes made in this file will be lost! diff --git a/imageview/ImageView.py b/imageview/ImageView.py index 77f34419..d4458a0e 100644 --- a/imageview/ImageView.py +++ b/imageview/ImageView.py @@ -12,29 +12,29 @@ Widget used for displaying 2D or 3D data. Features: - ROI plotting - Image normalization through a variety of methods """ -from pyqtgraph.Qt import QtCore, QtGui, USE_PYSIDE +from ..Qt import QtCore, QtGui, USE_PYSIDE if USE_PYSIDE: from .ImageViewTemplate_pyside import * else: from .ImageViewTemplate_pyqt import * -from pyqtgraph.graphicsItems.ImageItem import * -from pyqtgraph.graphicsItems.ROI import * -from pyqtgraph.graphicsItems.LinearRegionItem import * -from pyqtgraph.graphicsItems.InfiniteLine import * -from pyqtgraph.graphicsItems.ViewBox import * +from ..graphicsItems.ImageItem import * +from ..graphicsItems.ROI import * +from ..graphicsItems.LinearRegionItem import * +from ..graphicsItems.InfiniteLine import * +from ..graphicsItems.ViewBox import * #from widgets import ROI import sys #from numpy import ndarray -import pyqtgraph.ptime as ptime +from .. import ptime as ptime import numpy as np -import pyqtgraph.debug as debug +from .. import debug as debug -from pyqtgraph.SignalProxy import SignalProxy +from ..SignalProxy import SignalProxy #try: - #import pyqtgraph.metaarray as metaarray + #from .. import metaarray as metaarray #HAVE_METAARRAY = True #except: #HAVE_METAARRAY = False @@ -190,7 +190,7 @@ class ImageView(QtGui.QWidget): image data. ================== ======================================================================= """ - prof = debug.Profiler('ImageView.setImage', disabled=True) + profiler = debug.Profiler() if hasattr(img, 'implements') and img.implements('MetaArray'): img = img.asarray() @@ -209,7 +209,7 @@ class ImageView(QtGui.QWidget): else: self.tVals = np.arange(img.shape[0]) - prof.mark('1') + profiler() if axes is None: if img.ndim == 2: @@ -234,13 +234,9 @@ class ImageView(QtGui.QWidget): for x in ['t', 'x', 'y', 'c']: self.axes[x] = self.axes.get(x, None) - prof.mark('2') - - self.imageDisp = None - - - prof.mark('3') - + + profiler() + self.currentIndex = 0 self.updateImage(autoHistogramRange=autoHistogramRange) if levels is None and autoLevels: @@ -250,9 +246,9 @@ class ImageView(QtGui.QWidget): if self.ui.roiBtn.isChecked(): self.roiChanged() - prof.mark('4') - - + + profiler() + if self.axes['t'] is not None: #self.ui.roiPlot.show() self.ui.roiPlot.setXRange(self.tVals.min(), self.tVals.max()) @@ -271,8 +267,8 @@ class ImageView(QtGui.QWidget): s.setBounds([start, stop]) #else: #self.ui.roiPlot.hide() - prof.mark('5') - + profiler() + self.imageItem.resetTransform() if scale is not None: self.imageItem.scale(*scale) @@ -280,15 +276,15 @@ class ImageView(QtGui.QWidget): self.imageItem.setPos(*pos) if transform is not None: self.imageItem.setTransform(transform) - prof.mark('6') - + + profiler() + if autoRange: self.autoRange() self.roiClicked() - prof.mark('7') - prof.finish() - + profiler() + def play(self, rate): """Begin automatically stepping frames forward at the given rate (in fps). This can also be accessed by pressing the spacebar.""" diff --git a/imageview/ImageViewTemplate.ui b/imageview/ImageViewTemplate.ui index 497c0c59..9a3dab03 100644 --- a/imageview/ImageViewTemplate.ui +++ b/imageview/ImageViewTemplate.ui @@ -233,18 +233,18 @@ PlotWidget QWidget -
pyqtgraph.widgets.PlotWidget
+
..widgets.PlotWidget
1
GraphicsView QGraphicsView -
pyqtgraph.widgets.GraphicsView
+
..widgets.GraphicsView
HistogramLUTWidget QGraphicsView -
pyqtgraph.widgets.HistogramLUTWidget
+
..widgets.HistogramLUTWidget
diff --git a/imageview/ImageViewTemplate_pyqt.py b/imageview/ImageViewTemplate_pyqt.py index e6423276..78156317 100644 --- a/imageview/ImageViewTemplate_pyqt.py +++ b/imageview/ImageViewTemplate_pyqt.py @@ -1,9 +1,9 @@ # -*- coding: utf-8 -*- -# Form implementation generated from reading ui file './imageview/ImageViewTemplate.ui' +# Form implementation generated from reading ui file './pyqtgraph/imageview/ImageViewTemplate.ui' # -# Created: Sun Sep 9 14:41:30 2012 -# by: PyQt4 UI code generator 4.9.1 +# Created: Mon Dec 23 10:10:52 2013 +# by: PyQt4 UI code generator 4.10 # # WARNING! All changes made in this file will be lost! @@ -12,7 +12,16 @@ from PyQt4 import QtCore, QtGui try: _fromUtf8 = QtCore.QString.fromUtf8 except AttributeError: - _fromUtf8 = lambda s: s + def _fromUtf8(s): + return s + +try: + _encoding = QtGui.QApplication.UnicodeUTF8 + def _translate(context, text, disambig): + return QtGui.QApplication.translate(context, text, disambig, _encoding) +except AttributeError: + def _translate(context, text, disambig): + return QtGui.QApplication.translate(context, text, disambig) class Ui_Form(object): def setupUi(self, Form): @@ -138,23 +147,23 @@ class Ui_Form(object): QtCore.QMetaObject.connectSlotsByName(Form) def retranslateUi(self, Form): - Form.setWindowTitle(QtGui.QApplication.translate("Form", "Form", None, QtGui.QApplication.UnicodeUTF8)) - self.roiBtn.setText(QtGui.QApplication.translate("Form", "ROI", None, QtGui.QApplication.UnicodeUTF8)) - self.normBtn.setText(QtGui.QApplication.translate("Form", "Norm", None, QtGui.QApplication.UnicodeUTF8)) - self.normGroup.setTitle(QtGui.QApplication.translate("Form", "Normalization", None, QtGui.QApplication.UnicodeUTF8)) - self.normSubtractRadio.setText(QtGui.QApplication.translate("Form", "Subtract", None, QtGui.QApplication.UnicodeUTF8)) - self.normDivideRadio.setText(QtGui.QApplication.translate("Form", "Divide", None, QtGui.QApplication.UnicodeUTF8)) - self.label_5.setText(QtGui.QApplication.translate("Form", "Operation:", None, QtGui.QApplication.UnicodeUTF8)) - self.label_3.setText(QtGui.QApplication.translate("Form", "Mean:", None, QtGui.QApplication.UnicodeUTF8)) - self.label_4.setText(QtGui.QApplication.translate("Form", "Blur:", None, QtGui.QApplication.UnicodeUTF8)) - self.normROICheck.setText(QtGui.QApplication.translate("Form", "ROI", None, QtGui.QApplication.UnicodeUTF8)) - self.label_8.setText(QtGui.QApplication.translate("Form", "X", None, QtGui.QApplication.UnicodeUTF8)) - self.label_9.setText(QtGui.QApplication.translate("Form", "Y", None, QtGui.QApplication.UnicodeUTF8)) - self.label_10.setText(QtGui.QApplication.translate("Form", "T", None, QtGui.QApplication.UnicodeUTF8)) - self.normOffRadio.setText(QtGui.QApplication.translate("Form", "Off", None, QtGui.QApplication.UnicodeUTF8)) - self.normTimeRangeCheck.setText(QtGui.QApplication.translate("Form", "Time range", None, QtGui.QApplication.UnicodeUTF8)) - self.normFrameCheck.setText(QtGui.QApplication.translate("Form", "Frame", None, QtGui.QApplication.UnicodeUTF8)) + Form.setWindowTitle(_translate("Form", "Form", None)) + self.roiBtn.setText(_translate("Form", "ROI", None)) + self.normBtn.setText(_translate("Form", "Norm", None)) + self.normGroup.setTitle(_translate("Form", "Normalization", None)) + self.normSubtractRadio.setText(_translate("Form", "Subtract", None)) + self.normDivideRadio.setText(_translate("Form", "Divide", None)) + self.label_5.setText(_translate("Form", "Operation:", None)) + self.label_3.setText(_translate("Form", "Mean:", None)) + self.label_4.setText(_translate("Form", "Blur:", None)) + self.normROICheck.setText(_translate("Form", "ROI", None)) + self.label_8.setText(_translate("Form", "X", None)) + self.label_9.setText(_translate("Form", "Y", None)) + self.label_10.setText(_translate("Form", "T", None)) + self.normOffRadio.setText(_translate("Form", "Off", None)) + self.normTimeRangeCheck.setText(_translate("Form", "Time range", None)) + self.normFrameCheck.setText(_translate("Form", "Frame", None)) -from pyqtgraph.widgets.GraphicsView import GraphicsView -from pyqtgraph.widgets.PlotWidget import PlotWidget -from pyqtgraph.widgets.HistogramLUTWidget import HistogramLUTWidget +from ..widgets.HistogramLUTWidget import HistogramLUTWidget +from ..widgets.GraphicsView import GraphicsView +from ..widgets.PlotWidget import PlotWidget diff --git a/imageview/ImageViewTemplate_pyside.py b/imageview/ImageViewTemplate_pyside.py index c17bbfe1..2f8b570b 100644 --- a/imageview/ImageViewTemplate_pyside.py +++ b/imageview/ImageViewTemplate_pyside.py @@ -1,9 +1,9 @@ # -*- coding: utf-8 -*- -# Form implementation generated from reading ui file './imageview/ImageViewTemplate.ui' +# Form implementation generated from reading ui file './pyqtgraph/imageview/ImageViewTemplate.ui' # -# Created: Sun Sep 9 14:41:31 2012 -# by: pyside-uic 0.2.13 running on PySide 1.1.0 +# Created: Mon Dec 23 10:10:52 2013 +# by: pyside-uic 0.2.14 running on PySide 1.1.2 # # WARNING! All changes made in this file will be lost! @@ -150,6 +150,6 @@ class Ui_Form(object): self.normTimeRangeCheck.setText(QtGui.QApplication.translate("Form", "Time range", None, QtGui.QApplication.UnicodeUTF8)) self.normFrameCheck.setText(QtGui.QApplication.translate("Form", "Frame", None, QtGui.QApplication.UnicodeUTF8)) -from pyqtgraph.widgets.GraphicsView import GraphicsView -from pyqtgraph.widgets.PlotWidget import PlotWidget -from pyqtgraph.widgets.HistogramLUTWidget import HistogramLUTWidget +from ..widgets.HistogramLUTWidget import HistogramLUTWidget +from ..widgets.GraphicsView import GraphicsView +from ..widgets.PlotWidget import PlotWidget diff --git a/metaarray/MetaArray.py b/metaarray/MetaArray.py index f55c60dc..d24a7d05 100644 --- a/metaarray/MetaArray.py +++ b/metaarray/MetaArray.py @@ -929,7 +929,7 @@ class MetaArray(object): if proc == False: raise Exception('remote read failed') if proc == None: - import pyqtgraph.multiprocess as mp + from .. import multiprocess as mp #print "new process" proc = mp.Process(executable='/usr/bin/python') proc.setProxyOptions(deferGetattr=True) @@ -1471,4 +1471,4 @@ if __name__ == '__main__': ma2 = MetaArray(file=tf, mmap=True) print("\nArrays are equivalent:", (ma == ma2).all()) os.remove(tf) - \ No newline at end of file + diff --git a/multiprocess/parallelizer.py b/multiprocess/parallelizer.py index e96692e2..4ad30b6e 100644 --- a/multiprocess/parallelizer.py +++ b/multiprocess/parallelizer.py @@ -63,8 +63,8 @@ class Parallelize(object): self.showProgress = True if isinstance(progressDialog, basestring): progressDialog = {'labelText': progressDialog} - import pyqtgraph as pg - self.progressDlg = pg.ProgressDialog(**progressDialog) + from ..widgets.ProgressDialog import ProgressDialog + self.progressDlg = ProgressDialog(**progressDialog) if workers is None: workers = self.suggestedWorkerCount() diff --git a/multiprocess/processes.py b/multiprocess/processes.py index 4d32c999..5a4ccb99 100644 --- a/multiprocess/processes.py +++ b/multiprocess/processes.py @@ -1,7 +1,8 @@ from .remoteproxy import RemoteEventHandler, ClosedError, NoResultError, LocalObjectProxy, ObjectProxy import subprocess, atexit, os, sys, time, random, socket, signal import multiprocessing.connection -import pyqtgraph as pg +from ..Qt import USE_PYSIDE + try: import cPickle as pickle except ImportError: @@ -118,7 +119,7 @@ class Process(RemoteEventHandler): ppid=pid, targetStr=targetStr, path=sysPath, - pyside=pg.Qt.USE_PYSIDE, + pyside=USE_PYSIDE, debug=debug ) pickle.dump(data, self.proc.stdin) @@ -337,7 +338,7 @@ class RemoteQtEventHandler(RemoteEventHandler): RemoteEventHandler.__init__(self, *args, **kwds) def startEventTimer(self): - from pyqtgraph.Qt import QtGui, QtCore + from ..Qt import QtGui, QtCore self.timer = QtCore.QTimer() self.timer.timeout.connect(self.processRequests) self.timer.start(10) @@ -346,7 +347,7 @@ class RemoteQtEventHandler(RemoteEventHandler): try: RemoteEventHandler.processRequests(self) except ClosedError: - from pyqtgraph.Qt import QtGui, QtCore + from ..Qt import QtGui, QtCore QtGui.QApplication.instance().quit() self.timer.stop() #raise SystemExit @@ -384,7 +385,7 @@ class QtProcess(Process): self.startEventTimer() def startEventTimer(self): - from pyqtgraph.Qt import QtGui, QtCore ## avoid module-level import to keep bootstrap snappy. + from ..Qt import QtGui, QtCore ## avoid module-level import to keep bootstrap snappy. self.timer = QtCore.QTimer() if self._processRequests: app = QtGui.QApplication.instance() @@ -415,7 +416,7 @@ def startQtEventLoop(name, port, authkey, ppid, debug=False): conn = multiprocessing.connection.Client(('localhost', int(port)), authkey=authkey) if debug: print('[%d] connected; starting remote proxy.' % os.getpid()) - from pyqtgraph.Qt import QtGui, QtCore + from ..Qt import QtGui, QtCore #from PyQt4 import QtGui, QtCore app = QtGui.QApplication.instance() #print app diff --git a/opengl/GLGraphicsItem.py b/opengl/GLGraphicsItem.py index 9680fba7..cdfaa683 100644 --- a/opengl/GLGraphicsItem.py +++ b/opengl/GLGraphicsItem.py @@ -1,5 +1,5 @@ -from pyqtgraph.Qt import QtGui, QtCore -from pyqtgraph import Transform3D +from ..Qt import QtGui, QtCore +from .. import Transform3D from OpenGL.GL import * from OpenGL import GL diff --git a/opengl/GLViewWidget.py b/opengl/GLViewWidget.py index 89fef92e..d74a13ce 100644 --- a/opengl/GLViewWidget.py +++ b/opengl/GLViewWidget.py @@ -1,9 +1,9 @@ -from pyqtgraph.Qt import QtCore, QtGui, QtOpenGL +from ..Qt import QtCore, QtGui, QtOpenGL from OpenGL.GL import * import OpenGL.GL.framebufferobjects as glfbo import numpy as np -from pyqtgraph import Vector -import pyqtgraph.functions as fn +from .. import Vector +from .. import functions as fn ##Vector = QtGui.QVector3D @@ -179,7 +179,7 @@ class GLViewWidget(QtOpenGL.QGLWidget): self._itemNames[id(i)] = i i.paint() except: - import pyqtgraph.debug + from .. import debug pyqtgraph.debug.printExc() msg = "Error while drawing item %s." % str(item) ver = glGetString(GL_VERSION) @@ -345,7 +345,7 @@ class GLViewWidget(QtOpenGL.QGLWidget): ## Only to be called from within exception handler. ver = glGetString(GL_VERSION).split()[0] if int(ver.split('.')[0]) < 2: - import pyqtgraph.debug + from .. import debug pyqtgraph.debug.printExc() raise Exception(msg + " The original exception is printed above; however, pyqtgraph requires OpenGL version 2.0 or greater for many of its 3D features and your OpenGL version is %s. Installing updated display drivers may resolve this issue." % ver) else: diff --git a/opengl/MeshData.py b/opengl/MeshData.py index 71e566c9..3046459d 100644 --- a/opengl/MeshData.py +++ b/opengl/MeshData.py @@ -1,5 +1,5 @@ -from pyqtgraph.Qt import QtGui -import pyqtgraph.functions as fn +from ..Qt import QtGui +from .. import functions as fn import numpy as np class MeshData(object): diff --git a/opengl/__init__.py b/opengl/__init__.py index 5345e187..931003e4 100644 --- a/opengl/__init__.py +++ b/opengl/__init__.py @@ -1,28 +1,20 @@ from .GLViewWidget import GLViewWidget -from pyqtgraph import importAll -#import os -#def importAll(path): - #d = os.path.join(os.path.split(__file__)[0], path) - #files = [] - #for f in os.listdir(d): - #if os.path.isdir(os.path.join(d, f)) and f != '__pycache__': - #files.append(f) - #elif f[-3:] == '.py' and f != '__init__.py': - #files.append(f[:-3]) - - #for modName in files: - #mod = __import__(path+"."+modName, globals(), locals(), fromlist=['*']) - #if hasattr(mod, '__all__'): - #names = mod.__all__ - #else: - #names = [n for n in dir(mod) if n[0] != '_'] - #for k in names: - #if hasattr(mod, k): - #globals()[k] = getattr(mod, k) +## dynamic imports cause too many problems. +#from .. import importAll +#importAll('items', globals(), locals()) + +from .items.GLGridItem import * +from .items.GLBarGraphItem import * +from .items.GLScatterPlotItem import * +from .items.GLMeshItem import * +from .items.GLLinePlotItem import * +from .items.GLAxisItem import * +from .items.GLImageItem import * +from .items.GLSurfacePlotItem import * +from .items.GLBoxItem import * +from .items.GLVolumeItem import * -importAll('items', globals(), locals()) -\ from .MeshData import MeshData ## for backward compatibility: #MeshData.MeshData = MeshData ## breaks autodoc. diff --git a/opengl/glInfo.py b/opengl/glInfo.py index 28da1f69..84346d81 100644 --- a/opengl/glInfo.py +++ b/opengl/glInfo.py @@ -1,4 +1,4 @@ -from pyqtgraph.Qt import QtCore, QtGui, QtOpenGL +from ..Qt import QtCore, QtGui, QtOpenGL from OpenGL.GL import * app = QtGui.QApplication([]) diff --git a/opengl/items/GLAxisItem.py b/opengl/items/GLAxisItem.py index 860ac497..c6c206e4 100644 --- a/opengl/items/GLAxisItem.py +++ b/opengl/items/GLAxisItem.py @@ -1,6 +1,6 @@ from OpenGL.GL import * from .. GLGraphicsItem import GLGraphicsItem -from pyqtgraph import QtGui +from ... import QtGui __all__ = ['GLAxisItem'] diff --git a/opengl/items/GLBoxItem.py b/opengl/items/GLBoxItem.py index bc25afd1..f0a6ae6c 100644 --- a/opengl/items/GLBoxItem.py +++ b/opengl/items/GLBoxItem.py @@ -1,7 +1,7 @@ from OpenGL.GL import * from .. GLGraphicsItem import GLGraphicsItem -from pyqtgraph.Qt import QtGui -import pyqtgraph as pg +from ...Qt import QtGui +from ... import functions as fn __all__ = ['GLBoxItem'] @@ -38,7 +38,7 @@ class GLBoxItem(GLGraphicsItem): def setColor(self, *args): """Set the color of the box. Arguments are the same as those accepted by functions.mkColor()""" - self.__color = pg.Color(*args) + self.__color = fn.Color(*args) def color(self): return self.__color diff --git a/opengl/items/GLGridItem.py b/opengl/items/GLGridItem.py index 01a2b178..2c4642c8 100644 --- a/opengl/items/GLGridItem.py +++ b/opengl/items/GLGridItem.py @@ -1,6 +1,6 @@ from OpenGL.GL import * from .. GLGraphicsItem import GLGraphicsItem -from pyqtgraph import QtGui +from ... import QtGui __all__ = ['GLGridItem'] diff --git a/opengl/items/GLImageItem.py b/opengl/items/GLImageItem.py index aca68f3d..2cab23a3 100644 --- a/opengl/items/GLImageItem.py +++ b/opengl/items/GLImageItem.py @@ -1,6 +1,6 @@ from OpenGL.GL import * from .. GLGraphicsItem import GLGraphicsItem -from pyqtgraph.Qt import QtGui +from ...Qt import QtGui import numpy as np __all__ = ['GLImageItem'] diff --git a/opengl/items/GLLinePlotItem.py b/opengl/items/GLLinePlotItem.py index 23d227c9..a578dd1d 100644 --- a/opengl/items/GLLinePlotItem.py +++ b/opengl/items/GLLinePlotItem.py @@ -2,7 +2,7 @@ from OpenGL.GL import * from OpenGL.arrays import vbo from .. GLGraphicsItem import GLGraphicsItem from .. import shaders -from pyqtgraph import QtGui +from ... import QtGui import numpy as np __all__ = ['GLLinePlotItem'] diff --git a/opengl/items/GLMeshItem.py b/opengl/items/GLMeshItem.py index 5b245e64..14d178f8 100644 --- a/opengl/items/GLMeshItem.py +++ b/opengl/items/GLMeshItem.py @@ -1,9 +1,9 @@ from OpenGL.GL import * from .. GLGraphicsItem import GLGraphicsItem from .. MeshData import MeshData -from pyqtgraph.Qt import QtGui -import pyqtgraph as pg +from ...Qt import QtGui from .. import shaders +from ... import functions as fn import numpy as np @@ -177,7 +177,7 @@ class GLMeshItem(GLGraphicsItem): if self.colors is None: color = self.opts['color'] if isinstance(color, QtGui.QColor): - glColor4f(*pg.glColor(color)) + glColor4f(*fn.glColor(color)) else: glColor4f(*color) else: @@ -209,7 +209,7 @@ class GLMeshItem(GLGraphicsItem): if self.edgeColors is None: color = self.opts['edgeColor'] if isinstance(color, QtGui.QColor): - glColor4f(*pg.glColor(color)) + glColor4f(*fn.glColor(color)) else: glColor4f(*color) else: diff --git a/opengl/items/GLScatterPlotItem.py b/opengl/items/GLScatterPlotItem.py index b02a9dda..9ddd3b34 100644 --- a/opengl/items/GLScatterPlotItem.py +++ b/opengl/items/GLScatterPlotItem.py @@ -2,7 +2,7 @@ from OpenGL.GL import * from OpenGL.arrays import vbo from .. GLGraphicsItem import GLGraphicsItem from .. import shaders -from pyqtgraph import QtGui +from ... import QtGui import numpy as np __all__ = ['GLScatterPlotItem'] diff --git a/opengl/items/GLSurfacePlotItem.py b/opengl/items/GLSurfacePlotItem.py index 88d50fac..9c41a878 100644 --- a/opengl/items/GLSurfacePlotItem.py +++ b/opengl/items/GLSurfacePlotItem.py @@ -1,8 +1,7 @@ from OpenGL.GL import * from .GLMeshItem import GLMeshItem from .. MeshData import MeshData -from pyqtgraph.Qt import QtGui -import pyqtgraph as pg +from ...Qt import QtGui import numpy as np diff --git a/opengl/items/GLVolumeItem.py b/opengl/items/GLVolumeItem.py index 4980239d..84f23e12 100644 --- a/opengl/items/GLVolumeItem.py +++ b/opengl/items/GLVolumeItem.py @@ -1,6 +1,6 @@ from OpenGL.GL import * from .. GLGraphicsItem import GLGraphicsItem -from pyqtgraph.Qt import QtGui +from ...Qt import QtGui import numpy as np __all__ = ['GLVolumeItem'] diff --git a/parametertree/Parameter.py b/parametertree/Parameter.py index 9a7ece25..45e46e55 100644 --- a/parametertree/Parameter.py +++ b/parametertree/Parameter.py @@ -1,6 +1,6 @@ -from pyqtgraph.Qt import QtGui, QtCore +from ..Qt import QtGui, QtCore import os, weakref, re -from pyqtgraph.pgcollections import OrderedDict +from ..pgcollections import OrderedDict from .ParameterItem import ParameterItem PARAM_TYPES = {} diff --git a/parametertree/ParameterItem.py b/parametertree/ParameterItem.py index 46499fd3..5a90becf 100644 --- a/parametertree/ParameterItem.py +++ b/parametertree/ParameterItem.py @@ -1,4 +1,4 @@ -from pyqtgraph.Qt import QtGui, QtCore +from ..Qt import QtGui, QtCore import os, weakref, re class ParameterItem(QtGui.QTreeWidgetItem): diff --git a/parametertree/ParameterTree.py b/parametertree/ParameterTree.py index 866875e5..953f3bb7 100644 --- a/parametertree/ParameterTree.py +++ b/parametertree/ParameterTree.py @@ -1,5 +1,5 @@ -from pyqtgraph.Qt import QtCore, QtGui -from pyqtgraph.widgets.TreeWidget import TreeWidget +from ..Qt import QtCore, QtGui +from ..widgets.TreeWidget import TreeWidget import os, weakref, re from .ParameterItem import ParameterItem #import functions as fn diff --git a/parametertree/parameterTypes.py b/parametertree/parameterTypes.py index 3300171f..f58145dd 100644 --- a/parametertree/parameterTypes.py +++ b/parametertree/parameterTypes.py @@ -1,14 +1,14 @@ -from pyqtgraph.Qt import QtCore, QtGui -from pyqtgraph.python2_3 import asUnicode +from ..Qt import QtCore, QtGui +from ..python2_3 import asUnicode from .Parameter import Parameter, registerParameterType from .ParameterItem import ParameterItem -from pyqtgraph.widgets.SpinBox import SpinBox -from pyqtgraph.widgets.ColorButton import ColorButton -#from pyqtgraph.widgets.GradientWidget import GradientWidget ## creates import loop -import pyqtgraph as pg -import pyqtgraph.pixmaps as pixmaps +from ..widgets.SpinBox import SpinBox +from ..widgets.ColorButton import ColorButton +#from ..widgets.GradientWidget import GradientWidget ## creates import loop +from .. import pixmaps as pixmaps +from .. import functions as fn import os -from pyqtgraph.pgcollections import OrderedDict +from ..pgcollections import OrderedDict class WidgetParameterItem(ParameterItem): """ @@ -141,7 +141,7 @@ class WidgetParameterItem(ParameterItem): self.hideWidget = False w.setFlat(True) elif t == 'colormap': - from pyqtgraph.widgets.GradientWidget import GradientWidget ## need this here to avoid import loop + from ..widgets.GradientWidget import GradientWidget ## need this here to avoid import loop w = GradientWidget(orientation='bottom') w.sigChanged = w.sigGradientChangeFinished w.sigChanging = w.sigGradientChanged @@ -304,11 +304,11 @@ class SimpleParameter(Parameter): self.saveState = self.saveColorState def colorValue(self): - return pg.mkColor(Parameter.value(self)) + return fn.mkColor(Parameter.value(self)) def saveColorState(self): state = Parameter.saveState(self) - state['value'] = pg.colorTuple(self.value()) + state['value'] = fn.colorTuple(self.value()) return state diff --git a/widgets/BusyCursor.py b/widgets/BusyCursor.py index b013dda0..d99fe589 100644 --- a/widgets/BusyCursor.py +++ b/widgets/BusyCursor.py @@ -1,4 +1,4 @@ -from pyqtgraph.Qt import QtGui, QtCore +from ..Qt import QtGui, QtCore __all__ = ['BusyCursor'] diff --git a/widgets/CheckTable.py b/widgets/CheckTable.py index dd33fd75..22015126 100644 --- a/widgets/CheckTable.py +++ b/widgets/CheckTable.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -from pyqtgraph.Qt import QtGui, QtCore +from ..Qt import QtGui, QtCore from . import VerticalLabel __all__ = ['CheckTable'] diff --git a/widgets/ColorButton.py b/widgets/ColorButton.py index ee91801a..40f6740f 100644 --- a/widgets/ColorButton.py +++ b/widgets/ColorButton.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- -from pyqtgraph.Qt import QtGui, QtCore -import pyqtgraph.functions as functions +from ..Qt import QtGui, QtCore +from .. import functions as functions __all__ = ['ColorButton'] diff --git a/widgets/ColorMapWidget.py b/widgets/ColorMapWidget.py index 26539d7e..1874f5d1 100644 --- a/widgets/ColorMapWidget.py +++ b/widgets/ColorMapWidget.py @@ -1,8 +1,8 @@ -from pyqtgraph.Qt import QtGui, QtCore -import pyqtgraph.parametertree as ptree +from ..Qt import QtGui, QtCore +from .. import parametertree as ptree import numpy as np -from pyqtgraph.pgcollections import OrderedDict -import pyqtgraph.functions as fn +from ..pgcollections import OrderedDict +from .. import functions as fn __all__ = ['ColorMapWidget'] diff --git a/widgets/ComboBox.py b/widgets/ComboBox.py index 1884648c..72ac384f 100644 --- a/widgets/ComboBox.py +++ b/widgets/ComboBox.py @@ -1,5 +1,5 @@ -from pyqtgraph.Qt import QtGui, QtCore -from pyqtgraph.SignalProxy import SignalProxy +from ..Qt import QtGui, QtCore +from ..SignalProxy import SignalProxy class ComboBox(QtGui.QComboBox): diff --git a/widgets/DataFilterWidget.py b/widgets/DataFilterWidget.py index c94f6c68..cae8be86 100644 --- a/widgets/DataFilterWidget.py +++ b/widgets/DataFilterWidget.py @@ -1,8 +1,8 @@ -from pyqtgraph.Qt import QtGui, QtCore -import pyqtgraph.parametertree as ptree +from ..Qt import QtGui, QtCore +from .. import parametertree as ptree import numpy as np -from pyqtgraph.pgcollections import OrderedDict -import pyqtgraph as pg +from ..pgcollections import OrderedDict +from .. import functions as fn __all__ = ['DataFilterWidget'] @@ -108,7 +108,7 @@ class RangeFilterItem(ptree.types.SimpleParameter): return mask def describe(self): - return "%s < %s < %s" % (pg.siFormat(self['Min'], suffix=self.units), self.fieldName, pg.siFormat(self['Max'], suffix=self.units)) + return "%s < %s < %s" % (fn.siFormat(self['Min'], suffix=self.units), self.fieldName, fn.siFormat(self['Max'], suffix=self.units)) class EnumFilterItem(ptree.types.SimpleParameter): def __init__(self, name, opts): diff --git a/widgets/DataTreeWidget.py b/widgets/DataTreeWidget.py index a6b5cac8..b99121bf 100644 --- a/widgets/DataTreeWidget.py +++ b/widgets/DataTreeWidget.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- -from pyqtgraph.Qt import QtGui, QtCore -from pyqtgraph.pgcollections import OrderedDict +from ..Qt import QtGui, QtCore +from ..pgcollections import OrderedDict import types, traceback import numpy as np diff --git a/widgets/FeedbackButton.py b/widgets/FeedbackButton.py index f788f4b6..30114d4e 100644 --- a/widgets/FeedbackButton.py +++ b/widgets/FeedbackButton.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -from pyqtgraph.Qt import QtCore, QtGui +from ..Qt import QtCore, QtGui __all__ = ['FeedbackButton'] diff --git a/widgets/FileDialog.py b/widgets/FileDialog.py index 33b838a2..faa0994c 100644 --- a/widgets/FileDialog.py +++ b/widgets/FileDialog.py @@ -1,4 +1,4 @@ -from pyqtgraph.Qt import QtGui, QtCore +from ..Qt import QtGui, QtCore import sys __all__ = ['FileDialog'] diff --git a/widgets/GradientWidget.py b/widgets/GradientWidget.py index 1723a94b..ce0cbeb9 100644 --- a/widgets/GradientWidget.py +++ b/widgets/GradientWidget.py @@ -1,11 +1,11 @@ # -*- coding: utf-8 -*- -from pyqtgraph.Qt import QtGui, QtCore +from ..Qt import QtGui, QtCore from .GraphicsView import GraphicsView -from pyqtgraph.graphicsItems.GradientEditorItem import GradientEditorItem +from ..graphicsItems.GradientEditorItem import GradientEditorItem import weakref import numpy as np -__all__ = ['TickSlider', 'GradientWidget', 'BlackWhiteSlider'] +__all__ = ['GradientWidget'] class GradientWidget(GraphicsView): diff --git a/widgets/GraphicsLayoutWidget.py b/widgets/GraphicsLayoutWidget.py index 1e667278..3c34ca58 100644 --- a/widgets/GraphicsLayoutWidget.py +++ b/widgets/GraphicsLayoutWidget.py @@ -1,5 +1,5 @@ -from pyqtgraph.Qt import QtGui -from pyqtgraph.graphicsItems.GraphicsLayout import GraphicsLayout +from ..Qt import QtGui +from ..graphicsItems.GraphicsLayout import GraphicsLayout from .GraphicsView import GraphicsView __all__ = ['GraphicsLayoutWidget'] diff --git a/widgets/GraphicsView.py b/widgets/GraphicsView.py index fb535929..f3f4856a 100644 --- a/widgets/GraphicsView.py +++ b/widgets/GraphicsView.py @@ -5,23 +5,22 @@ Copyright 2010 Luke Campagnola Distributed under MIT/X11 license. See license.txt for more infomation. """ -from pyqtgraph.Qt import QtCore, QtGui -import pyqtgraph as pg +from ..Qt import QtCore, QtGui, USE_PYSIDE try: - from pyqtgraph.Qt import QtOpenGL + from ..Qt import QtOpenGL HAVE_OPENGL = True except ImportError: HAVE_OPENGL = False -from pyqtgraph.Point import Point +from ..Point import Point import sys, os from .FileDialog import FileDialog -from pyqtgraph.GraphicsScene import GraphicsScene +from ..GraphicsScene import GraphicsScene import numpy as np -import pyqtgraph.functions as fn -import pyqtgraph.debug as debug -import pyqtgraph +from .. import functions as fn +from .. import debug as debug +from .. import getConfigOption __all__ = ['GraphicsView'] @@ -73,7 +72,7 @@ class GraphicsView(QtGui.QGraphicsView): QtGui.QGraphicsView.__init__(self, parent) if useOpenGL is None: - useOpenGL = pyqtgraph.getConfigOption('useOpenGL') + useOpenGL = getConfigOption('useOpenGL') self.useOpenGL(useOpenGL) @@ -108,7 +107,7 @@ class GraphicsView(QtGui.QGraphicsView): ## Workaround for PySide crash ## This ensures that the scene will outlive the view. - if pyqtgraph.Qt.USE_PYSIDE: + if USE_PYSIDE: self.sceneObj._view_ref_workaround = self ## by default we set up a central widget with a grid layout. @@ -138,7 +137,7 @@ class GraphicsView(QtGui.QGraphicsView): """ self._background = background if background == 'default': - background = pyqtgraph.getConfigOption('background') + background = getConfigOption('background') brush = fn.mkBrush(background) self.setBackgroundBrush(brush) diff --git a/widgets/HistogramLUTWidget.py b/widgets/HistogramLUTWidget.py index cbe8eb61..9aec837c 100644 --- a/widgets/HistogramLUTWidget.py +++ b/widgets/HistogramLUTWidget.py @@ -3,9 +3,9 @@ Widget displaying an image histogram along with gradient editor. Can be used to This is a wrapper around HistogramLUTItem """ -from pyqtgraph.Qt import QtGui, QtCore +from ..Qt import QtGui, QtCore from .GraphicsView import GraphicsView -from pyqtgraph.graphicsItems.HistogramLUTItem import HistogramLUTItem +from ..graphicsItems.HistogramLUTItem import HistogramLUTItem __all__ = ['HistogramLUTWidget'] diff --git a/widgets/JoystickButton.py b/widgets/JoystickButton.py index 201a957a..6f73c8dc 100644 --- a/widgets/JoystickButton.py +++ b/widgets/JoystickButton.py @@ -1,4 +1,4 @@ -from pyqtgraph.Qt import QtGui, QtCore +from ..Qt import QtGui, QtCore __all__ = ['JoystickButton'] diff --git a/widgets/LayoutWidget.py b/widgets/LayoutWidget.py index f567ad74..65d04d3f 100644 --- a/widgets/LayoutWidget.py +++ b/widgets/LayoutWidget.py @@ -1,4 +1,4 @@ -from pyqtgraph.Qt import QtGui, QtCore +from ..Qt import QtGui, QtCore __all__ = ['LayoutWidget'] class LayoutWidget(QtGui.QWidget): diff --git a/widgets/MatplotlibWidget.py b/widgets/MatplotlibWidget.py index 6a22c973..959e188a 100644 --- a/widgets/MatplotlibWidget.py +++ b/widgets/MatplotlibWidget.py @@ -1,4 +1,4 @@ -from pyqtgraph.Qt import QtGui, QtCore, USE_PYSIDE +from ..Qt import QtGui, QtCore, USE_PYSIDE import matplotlib if USE_PYSIDE: diff --git a/widgets/MultiPlotWidget.py b/widgets/MultiPlotWidget.py index 400bee92..58b71296 100644 --- a/widgets/MultiPlotWidget.py +++ b/widgets/MultiPlotWidget.py @@ -6,7 +6,7 @@ Distributed under MIT/X11 license. See license.txt for more infomation. """ from .GraphicsView import GraphicsView -import pyqtgraph.graphicsItems.MultiPlotItem as MultiPlotItem +from ..graphicsItems import MultiPlotItem as MultiPlotItem __all__ = ['MultiPlotWidget'] class MultiPlotWidget(GraphicsView): @@ -42,4 +42,4 @@ class MultiPlotWidget(GraphicsView): self.mPlotItem.close() self.mPlotItem = None self.setParent(None) - GraphicsView.close(self) \ No newline at end of file + GraphicsView.close(self) diff --git a/widgets/PathButton.py b/widgets/PathButton.py index 7950a53d..0c62bb1b 100644 --- a/widgets/PathButton.py +++ b/widgets/PathButton.py @@ -1,5 +1,6 @@ -from pyqtgraph.Qt import QtGui, QtCore -import pyqtgraph as pg +from ..Qt import QtGui, QtCore +from .. import functions as fn + __all__ = ['PathButton'] @@ -20,10 +21,10 @@ class PathButton(QtGui.QPushButton): def setBrush(self, brush): - self.brush = pg.mkBrush(brush) + self.brush = fn.mkBrush(brush) def setPen(self, pen): - self.pen = pg.mkPen(pen) + self.pen = fn.mkPen(pen) def setPath(self, path): self.path = path diff --git a/widgets/PlotWidget.py b/widgets/PlotWidget.py index 7b3c685c..f9b544f5 100644 --- a/widgets/PlotWidget.py +++ b/widgets/PlotWidget.py @@ -5,9 +5,9 @@ Copyright 2010 Luke Campagnola Distributed under MIT/X11 license. See license.txt for more infomation. """ -from pyqtgraph.Qt import QtCore, QtGui +from ..Qt import QtCore, QtGui from .GraphicsView import * -from pyqtgraph.graphicsItems.PlotItem import * +from ..graphicsItems.PlotItem import * __all__ = ['PlotWidget'] class PlotWidget(GraphicsView): diff --git a/widgets/ProgressDialog.py b/widgets/ProgressDialog.py index 0f55e227..8c669be4 100644 --- a/widgets/ProgressDialog.py +++ b/widgets/ProgressDialog.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -from pyqtgraph.Qt import QtGui, QtCore +from ..Qt import QtGui, QtCore __all__ = ['ProgressDialog'] class ProgressDialog(QtGui.QProgressDialog): diff --git a/widgets/RawImageWidget.py b/widgets/RawImageWidget.py index 517f4f99..970b570b 100644 --- a/widgets/RawImageWidget.py +++ b/widgets/RawImageWidget.py @@ -1,12 +1,12 @@ -from pyqtgraph.Qt import QtCore, QtGui +from ..Qt import QtCore, QtGui try: - from pyqtgraph.Qt import QtOpenGL + from ..Qt import QtOpenGL from OpenGL.GL import * HAVE_OPENGL = True except ImportError: HAVE_OPENGL = False -import pyqtgraph.functions as fn +from .. import functions as fn import numpy as np class RawImageWidget(QtGui.QWidget): diff --git a/widgets/RemoteGraphicsView.py b/widgets/RemoteGraphicsView.py index d44fd1c3..54712f43 100644 --- a/widgets/RemoteGraphicsView.py +++ b/widgets/RemoteGraphicsView.py @@ -1,8 +1,7 @@ -from pyqtgraph.Qt import QtGui, QtCore, USE_PYSIDE +from ..Qt import QtGui, QtCore, USE_PYSIDE if not USE_PYSIDE: import sip -import pyqtgraph.multiprocess as mp -import pyqtgraph as pg +from .. import multiprocess as mp from .GraphicsView import GraphicsView import numpy as np import mmap, tempfile, ctypes, atexit, sys, random diff --git a/widgets/ScatterPlotWidget.py b/widgets/ScatterPlotWidget.py index e9e24dd7..02f260ca 100644 --- a/widgets/ScatterPlotWidget.py +++ b/widgets/ScatterPlotWidget.py @@ -1,12 +1,13 @@ -from pyqtgraph.Qt import QtGui, QtCore +from ..Qt import QtGui, QtCore from .PlotWidget import PlotWidget from .DataFilterWidget import DataFilterParameter from .ColorMapWidget import ColorMapParameter -import pyqtgraph.parametertree as ptree -import pyqtgraph.functions as fn +from .. import parametertree as ptree +from .. import functions as fn +from .. import getConfigOption +from ..graphicsItems.TextItem import TextItem import numpy as np -from pyqtgraph.pgcollections import OrderedDict -import pyqtgraph as pg +from ..pgcollections import OrderedDict __all__ = ['ScatterPlotWidget'] @@ -48,9 +49,9 @@ class ScatterPlotWidget(QtGui.QSplitter): self.ctrlPanel.addWidget(self.ptree) self.addWidget(self.plot) - bg = pg.mkColor(pg.getConfigOption('background')) + bg = fn.mkColor(getConfigOption('background')) bg.setAlpha(150) - self.filterText = pg.TextItem(border=pg.getConfigOption('foreground'), color=bg) + self.filterText = TextItem(border=getConfigOption('foreground'), color=bg) self.filterText.setPos(60,20) self.filterText.setParentItem(self.plot.plotItem) @@ -193,7 +194,7 @@ class ScatterPlotWidget(QtGui.QSplitter): imax = int(xy[ax].max()) if len(xy[ax]) > 0 else 0 for i in range(imax+1): keymask = xy[ax] == i - scatter = pg.pseudoScatter(xy[1-ax][keymask], bidir=True) + scatter = fn.pseudoScatter(xy[1-ax][keymask], bidir=True) if len(scatter) == 0: continue smax = np.abs(scatter).max() diff --git a/widgets/SpinBox.py b/widgets/SpinBox.py index 57e4f1ed..422522de 100644 --- a/widgets/SpinBox.py +++ b/widgets/SpinBox.py @@ -1,9 +1,9 @@ # -*- coding: utf-8 -*- -from pyqtgraph.Qt import QtGui, QtCore -from pyqtgraph.python2_3 import asUnicode -from pyqtgraph.SignalProxy import SignalProxy +from ..Qt import QtGui, QtCore +from ..python2_3 import asUnicode +from ..SignalProxy import SignalProxy -import pyqtgraph.functions as fn +from .. import functions as fn from math import log from decimal import Decimal as D ## Use decimal to avoid accumulating floating-point errors from decimal import * diff --git a/widgets/TableWidget.py b/widgets/TableWidget.py index 8ffe7291..03392648 100644 --- a/widgets/TableWidget.py +++ b/widgets/TableWidget.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- -from pyqtgraph.Qt import QtGui, QtCore -from pyqtgraph.python2_3 import asUnicode +from ..Qt import QtGui, QtCore +from ..python2_3 import asUnicode import numpy as np try: diff --git a/widgets/TreeWidget.py b/widgets/TreeWidget.py index 97fbe953..ec2c35cf 100644 --- a/widgets/TreeWidget.py +++ b/widgets/TreeWidget.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -from pyqtgraph.Qt import QtGui, QtCore +from ..Qt import QtGui, QtCore from weakref import * __all__ = ['TreeWidget', 'TreeWidgetItem'] diff --git a/widgets/ValueLabel.py b/widgets/ValueLabel.py index 7f6fa84b..d395cd43 100644 --- a/widgets/ValueLabel.py +++ b/widgets/ValueLabel.py @@ -1,6 +1,6 @@ -from pyqtgraph.Qt import QtCore, QtGui -from pyqtgraph.ptime import time -import pyqtgraph as pg +from ..Qt import QtCore, QtGui +from ..ptime import time +from .. import functions as fn from functools import reduce __all__ = ['ValueLabel'] @@ -67,7 +67,7 @@ class ValueLabel(QtGui.QLabel): avg = self.averageValue() val = self.values[-1][1] if self.siPrefix: - return pg.siFormat(avg, suffix=self.suffix) + return fn.siFormat(avg, suffix=self.suffix) else: return self.formatStr.format(value=val, avgValue=avg, suffix=self.suffix) diff --git a/widgets/VerticalLabel.py b/widgets/VerticalLabel.py index fa45ae5d..c8cc80bd 100644 --- a/widgets/VerticalLabel.py +++ b/widgets/VerticalLabel.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -from pyqtgraph.Qt import QtGui, QtCore +from ..Qt import QtGui, QtCore __all__ = ['VerticalLabel'] #class VerticalLabel(QtGui.QLabel):