Merge branch 'static_imports' into develop

No more dynamic imports; pg uses static imports throughout.
Flowcharts and exporters use plugin systems
This commit is contained in:
Luke Campagnola 2013-12-21 23:53:30 -05:00
commit 3488910810
14 changed files with 394 additions and 234 deletions

View File

@ -1,3 +1,35 @@
pyqtgraph-0.9.9 [unreleased]
API / behavior changes:
- Dynamic import system abandoned; pg now uses static imports throughout.
- Flowcharts and exporters have new pluggin systems
- Version strings:
- __init__.py in git repo now contains latest release version string
(previously, only packaged releases had version strings).
- installing from git checkout that does not correspond to a release
commit will result in a more descriptive version string.
- Speed improvements in functions.makeARGB
- ImageItem is faster by avoiding makeQImage(transpose=True)
New Features:
- New HDF5 example for working with very large datasets
- Added Qt.loadUiType function for PySide
- Simplified Profilers; can be activated with environmental variables
- Added Dock.raiseDock() method
Bugfixes:
- PlotCurveItem now has correct clicking behavior--clicks within a few px
of the line will trigger a signal.
- Fixes related to CSV exporter:
- CSV headers include data names, if available
- Exporter correctly handles items with no data
- pg.plot() avoids creating empty data item
- removed call to reduce() from exporter; not available in python 3
- Gave .name() methods to PlotDataItem, PlotCurveItem, and ScatterPlotItem
- fixed ImageItem handling of rgb images
- fixed makeARGB re-ordering of color channels
pyqtgraph-0.9.8 2013-11-24 pyqtgraph-0.9.8 2013-11-24
API / behavior changes: API / behavior changes:

View File

@ -83,9 +83,8 @@ class ImageViewNode(Node):
else: else:
self.view.setImage(data) self.view.setImage(data)
## register the class so it will appear in the menu of node types.
## It will appear in the 'display' sub-menu.
fclib.registerNodeType(ImageViewNode, [('Display',)])
## We will define an unsharp masking filter node as a subclass of CtrlNode. ## We will define an unsharp masking filter node as a subclass of CtrlNode.
## CtrlNode is just a convenience class that automatically creates its ## CtrlNode is just a convenience class that automatically creates its
@ -114,10 +113,23 @@ class UnsharpMaskNode(CtrlNode):
output = dataIn - (strength * scipy.ndimage.gaussian_filter(dataIn, (sigma,sigma))) output = dataIn - (strength * scipy.ndimage.gaussian_filter(dataIn, (sigma,sigma)))
return {'dataOut': output} return {'dataOut': output}
## register the class so it will appear in the menu of node types.
## It will appear in a new 'image' sub-menu.
fclib.registerNodeType(UnsharpMaskNode, [('Image',)])
## To make our custom node classes available in the flowchart context menu,
## we can either register them with the default node library or make a
## new library.
## Method 1: Register to global default library:
#fclib.registerNodeType(ImageViewNode, [('Display',)])
#fclib.registerNodeType(UnsharpMaskNode, [('Image',)])
## Method 2: If we want to make our custom node available only to this flowchart,
## then instead of registering the node type globally, we can create a new
## NodeLibrary:
library = fclib.LIBRARY.copy() # start with the default node set
library.addNodeType(ImageViewNode, [('Display',)])
library.addNodeType(UnsharpMaskNode, [('Image',)])
fc.setLibrary(library)
## Now we will programmatically add nodes to define the function of the flowchart. ## Now we will programmatically add nodes to define the function of the flowchart.

View File

@ -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 ## Import almost everything to make it available from a single namespace
## don't import the more complex systems--canvas, parametertree, flowchart, dockarea ## don't import the more complex systems--canvas, parametertree, flowchart, dockarea
## these must be imported separately. ## these must be imported separately.
from . import frozenSupport #from . import frozenSupport
def importModules(path, globals, locals, excludes=()): #def importModules(path, globals, locals, excludes=()):
"""Import all modules residing within *path*, return a dict of name: module pairs. #"""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. #Note that *path* MUST be relative to the module doing the import.
""" #"""
d = os.path.join(os.path.split(globals['__file__'])[0], path) #d = os.path.join(os.path.split(globals['__file__'])[0], path)
files = set() #files = set()
for f in frozenSupport.listdir(d): #for f in frozenSupport.listdir(d):
if frozenSupport.isdir(os.path.join(d, f)) and f not in ['__pycache__', 'tests']: #if frozenSupport.isdir(os.path.join(d, f)) and f not in ['__pycache__', 'tests']:
files.add(f) #files.add(f)
elif f[-3:] == '.py' and f != '__init__.py': #elif f[-3:] == '.py' and f != '__init__.py':
files.add(f[:-3]) #files.add(f[:-3])
elif f[-4:] == '.pyc' and f != '__init__.pyc': #elif f[-4:] == '.pyc' and f != '__init__.pyc':
files.add(f[:-4]) #files.add(f[:-4])
mods = {} #mods = {}
path = path.replace(os.sep, '.') #path = path.replace(os.sep, '.')
for modName in files: #for modName in files:
if modName in excludes: #if modName in excludes:
continue #continue
try: #try:
if len(path) > 0: #if len(path) > 0:
modName = path + '.' + modName #modName = path + '.' + modName
#mod = __import__(modName, globals, locals, fromlist=['*']) #print( "from .%s import * " % modName)
mod = __import__(modName, globals, locals, ['*'], 1) #mod = __import__(modName, globals, locals, ['*'], 1)
mods[modName] = mod #mods[modName] = mod
except: #except:
import traceback #import traceback
traceback.print_stack() #traceback.print_stack()
sys.excepthook(*sys.exc_info()) #sys.excepthook(*sys.exc_info())
print("[Error importing module: %s]" % modName) #print("[Error importing module: %s]" % modName)
return mods #return mods
def importAll(path, globals, locals, excludes=()): #def importAll(path, globals, locals, excludes=()):
"""Given a list of modules, import all names from each module into the global namespace.""" #"""Given a list of modules, import all names from each module into the global namespace."""
mods = importModules(path, globals, locals, excludes) #mods = importModules(path, globals, locals, excludes)
for mod in mods.values(): #for mod in mods.values():
if hasattr(mod, '__all__'): #if hasattr(mod, '__all__'):
names = mod.__all__ #names = mod.__all__
else: #else:
names = [n for n in dir(mod) if n[0] != '_'] #names = [n for n in dir(mod) if n[0] != '_']
for k in names: #for k in names:
if hasattr(mod, k): #if hasattr(mod, k):
globals[k] = getattr(mod, k) #globals[k] = getattr(mod, k)
importAll('graphicsItems', globals(), locals()) # Dynamic imports are disabled. This causes too many problems.
importAll('widgets', globals(), locals(), #importAll('graphicsItems', globals(), locals())
excludes=['MatplotlibWidget', 'RawImageWidget', 'RemoteGraphicsView']) #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 .imageview import *
from .WidgetGroup import * from .WidgetGroup import *
@ -194,6 +257,7 @@ from .SignalProxy import *
from .colormap import * from .colormap import *
from .ptime import time from .ptime import time
############################################################## ##############################################################
## PyQt and PySide both are prone to crashing on exit. ## PyQt and PySide both are prone to crashing on exit.
## There are two general approaches to dealing with this: ## There are two general approaches to dealing with this:

View File

@ -60,6 +60,6 @@ class CSVExporter(Exporter):
fd.write('\n') fd.write('\n')
fd.close() fd.close()
CSVExporter.register()

View File

@ -11,6 +11,14 @@ class Exporter(object):
Abstract class used for exporting graphics to file / printer / whatever. Abstract class used for exporting graphics to file / printer / whatever.
""" """
allowCopy = False # subclasses set this to True if they can use the copy buffer 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): def __init__(self, item):
""" """
@ -20,9 +28,6 @@ class Exporter(object):
object.__init__(self) object.__init__(self)
self.item = item self.item = item
#def item(self):
#return self.item
def parameters(self): def parameters(self):
"""Return the parameters used to configure this exporter.""" """Return the parameters used to configure this exporter."""
raise Exception("Abstract method must be overridden in subclass.") raise Exception("Abstract method must be overridden in subclass.")
@ -131,45 +136,4 @@ class Exporter(object):
return preItems + rootItem + postItems return preItems + rootItem + postItems
def render(self, painter, targetRect, sourceRect, item=None): 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)) 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

View File

@ -98,4 +98,5 @@ class ImageExporter(Exporter):
else: else:
self.png.save(fileName) self.png.save(fileName)
ImageExporter.register()

View File

@ -57,6 +57,7 @@ class MatplotlibExporter(Exporter):
else: else:
raise Exception("Matplotlib export currently only works with plot items") raise Exception("Matplotlib export currently only works with plot items")
MatplotlibExporter.register()
class MatplotlibWindow(QtGui.QMainWindow): class MatplotlibWindow(QtGui.QMainWindow):
@ -72,3 +73,5 @@ class MatplotlibWindow(QtGui.QMainWindow):
def closeEvent(self, ev): def closeEvent(self, ev):
MatplotlibExporter.windows.remove(self) MatplotlibExporter.windows.remove(self)

View File

@ -63,3 +63,6 @@ class PrintExporter(Exporter):
finally: finally:
self.setExportMode(False) self.setExportMode(False)
painter.end() painter.end()
#PrintExporter.register()

View File

@ -404,6 +404,10 @@ def correctCoordinates(node, item):
if removeTransform: if removeTransform:
grp.removeAttribute('transform') grp.removeAttribute('transform')
SVGExporter.register()
def itemTransform(item, root): def itemTransform(item, root):
## Return the transformation mapping item to root ## Return the transformation mapping item to root
## (actually to parent coordinate system of root) ## (actually to parent coordinate system of root)

View File

@ -1,27 +1,24 @@
Exporters = [] #Exporters = []
from pyqtgraph import importModules #from pyqtgraph import importModules
#from .. import frozenSupport #import os
import os #d = os.path.split(__file__)[0]
d = os.path.split(__file__)[0] #for mod in importModules('', globals(), locals(), excludes=['Exporter']).values():
#files = [] #if hasattr(mod, '__all__'):
#for f in frozenSupport.listdir(d): #names = mod.__all__
#if frozenSupport.isdir(os.path.join(d, f)) and f != '__pycache__': #else:
#files.append(f) #names = [n for n in dir(mod) if n[0] != '_']
#elif f[-3:] == '.py' and f not in ['__init__.py', 'Exporter.py']: #for k in names:
#files.append(f[:-3]) #if hasattr(mod, k):
#Exporters.append(getattr(mod, k))
#for modName in files: from .Exporter import Exporter
#mod = __import__(modName, globals(), locals(), fromlist=['*']) from .ImageExporter import *
for mod in importModules('', globals(), locals(), excludes=['Exporter']).values(): from .SVGExporter import *
if hasattr(mod, '__all__'): from .Matplotlib import *
names = mod.__all__ from .CSVExporter import *
else: from .PrintExporter import *
names = [n for n in dir(mod) if n[0] != '_']
for k in names:
if hasattr(mod, k):
Exporters.append(getattr(mod, k))
def listExporters(): def listExporters():
return Exporters[:] return Exporter.Exporters[:]

View File

@ -14,7 +14,7 @@ else:
from .Terminal import Terminal from .Terminal import Terminal
from numpy import ndarray from numpy import ndarray
from . import library from .library import LIBRARY
from pyqtgraph.debug import printExc from pyqtgraph.debug import printExc
import pyqtgraph.configfile as configfile import pyqtgraph.configfile as configfile
import pyqtgraph.dockarea as dockarea import pyqtgraph.dockarea as dockarea
@ -67,7 +67,8 @@ class Flowchart(Node):
sigChartLoaded = QtCore.Signal() sigChartLoaded = QtCore.Signal()
sigStateChanged = 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: if name is None:
name = "Flowchart" name = "Flowchart"
if terminals is None: if terminals is None:
@ -105,6 +106,10 @@ class Flowchart(Node):
for name, opts in terminals.items(): for name, opts in terminals.items():
self.addTerminal(name, **opts) self.addTerminal(name, **opts)
def setLibrary(self, lib):
self.library = lib
self.widget().chartWidget.buildMenu()
def setInput(self, **args): def setInput(self, **args):
"""Set the input values of the flowchart. This will automatically propagate """Set the input values of the flowchart. This will automatically propagate
the new values throughout the flowchart, (possibly) causing the output to change. the new values throughout the flowchart, (possibly) causing the output to change.
@ -194,7 +199,7 @@ class Flowchart(Node):
break break
n += 1 n += 1
node = library.getNodeType(nodeType)(name) node = self.library.getNodeType(nodeType)(name)
self.addNode(node, name, pos) self.addNode(node, name, pos)
return node return node
@ -846,13 +851,13 @@ class FlowchartWidget(dockarea.DockArea):
self.nodeMenu.triggered.disconnect(self.nodeMenuTriggered) self.nodeMenu.triggered.disconnect(self.nodeMenuTriggered)
self.nodeMenu = None self.nodeMenu = None
self.subMenus = [] self.subMenus = []
library.loadLibrary(reloadLibs=True) self.chart.library.reload()
self.buildMenu() self.buildMenu()
def buildMenu(self, pos=None): def buildMenu(self, pos=None):
self.nodeMenu = QtGui.QMenu() self.nodeMenu = QtGui.QMenu()
self.subMenus = [] self.subMenus = []
for section, nodes in library.getNodeTree().items(): for section, nodes in self.chart.library.getNodeTree().items():
menu = QtGui.QMenu(section) menu = QtGui.QMenu(section)
self.nodeMenu.addMenu(menu) self.nodeMenu.addMenu(menu)
for name in nodes: for name in nodes:

View File

@ -0,0 +1,84 @@
from pyqtgraph.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()

View File

@ -1,103 +1,102 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from pyqtgraph.pgcollections import OrderedDict from pyqtgraph.pgcollections import OrderedDict
from pyqtgraph import importModules #from pyqtgraph import importModules
import os, types import os, types
from pyqtgraph.debug import printExc from pyqtgraph.debug import printExc
from ..Node import Node #from ..Node import Node
from ..NodeLibrary import NodeLibrary, isNodeClass
import pyqtgraph.reload as reload import pyqtgraph.reload as reload
NODE_LIST = OrderedDict() ## maps name:class for all registered Node subclasses # Build default library
NODE_TREE = OrderedDict() ## categorized tree of Node subclasses LIBRARY = NodeLibrary()
def getNodeType(name): # For backward compatibility, expose the default library's properties here:
try: NODE_LIST = LIBRARY.nodeList
return NODE_LIST[name] NODE_TREE = LIBRARY.nodeTree
except KeyError: registerNodeType = LIBRARY.addNodeType
raise Exception("No node type called '%s'" % name) getNodeTree = LIBRARY.getNodeTree
getNodeType = LIBRARY.getNodeType
def getNodeTree(): # Add all nodes to the default library
return NODE_TREE from . import Data, Display, Filters, Operators
for mod in [Data, Display, Filters, Operators]:
#mod = getattr(__import__('', fromlist=[modName], level=1), modName)
#mod = __import__(modName, level=1)
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],)])
def registerNodeType(cls, paths, override=False): #NODE_LIST = OrderedDict() ## maps name:class for all registered Node subclasses
""" #NODE_TREE = OrderedDict() ## categorized tree of Node subclasses
Register a new node type. If the type's name is already in use,
an exception will be raised (unless override=True).
Arguments: #def getNodeType(name):
cls - a subclass of Node (must have typ.nodeName) #try:
paths - list of tuples specifying the location(s) this #return NODE_LIST[name]
type will appear in the library tree. #except KeyError:
override - if True, overwrite any class having the same name #raise Exception("No node type called '%s'" % name)
"""
if not isNodeClass(cls):
raise Exception("Object %s is not a Node subclass" % str(cls))
name = cls.nodeName #def getNodeTree():
if not override and name in NODE_LIST: #return NODE_TREE
raise Exception("Node type name '%s' is already registered." % name)
NODE_LIST[name] = cls #def registerNodeType(cls, paths, override=False):
for path in paths: #"""
root = NODE_TREE #Register a new node type. If the type's name is already in use,
for n in path: #an exception will be raised (unless override=True).
if n not in root:
root[n] = OrderedDict() #Arguments:
root = root[n] #cls - a subclass of Node (must have typ.nodeName)
root[name] = cls #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): #def isNodeClass(cls):
try: #try:
if not issubclass(cls, Node): #if not issubclass(cls, Node):
return False #return False
except: #except:
return False #return False
return hasattr(cls, 'nodeName') #return hasattr(cls, 'nodeName')
def loadLibrary(reloadLibs=False, libPath=None): #def loadLibrary(reloadLibs=False, libPath=None):
"""Import all Node subclasses found within files in the library module.""" #"""Import all Node subclasses found within files in the library module."""
global NODE_LIST, NODE_TREE #global NODE_LIST, NODE_TREE
#if libPath is None:
#libPath = os.path.dirname(os.path.abspath(__file__))
if reloadLibs: #if reloadLibs:
reload.reloadAll(libPath) #reload.reloadAll(libPath)
mods = importModules('', globals(), locals()) #mods = importModules('', globals(), locals())
#for f in frozenSupport.listdir(libPath):
#pathName, ext = os.path.splitext(f) #for name, mod in mods.items():
#if ext not in ('.py', '.pyc') or '__init__' in pathName or '__pycache__' in pathName: #nodes = []
#continue #for n in dir(mod):
#try: #o = getattr(mod, n)
##print "importing from", f #if isNodeClass(o):
#mod = __import__(pathName, globals(), locals()) #registerNodeType(o, [(name,)], override=reloadLibs)
#except:
#printExc("Error loading flowchart library %s:" % pathName) #def reloadLibrary():
#continue #loadLibrary(reloadLibs=True)
#loadLibrary()
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)

View File

@ -1,28 +1,20 @@
from .GLViewWidget import GLViewWidget from .GLViewWidget import GLViewWidget
from pyqtgraph import importAll ## dynamic imports cause too many problems.
#import os #from pyqtgraph import importAll
#def importAll(path): #importAll('items', globals(), locals())
#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: from .items.GLGridItem import *
#mod = __import__(path+"."+modName, globals(), locals(), fromlist=['*']) from .items.GLBarGraphItem import *
#if hasattr(mod, '__all__'): from .items.GLScatterPlotItem import *
#names = mod.__all__ from .items.GLMeshItem import *
#else: from .items.GLLinePlotItem import *
#names = [n for n in dir(mod) if n[0] != '_'] from .items.GLAxisItem import *
#for k in names: from .items.GLImageItem import *
#if hasattr(mod, k): from .items.GLSurfacePlotItem import *
#globals()[k] = getattr(mod, k) from .items.GLBoxItem import *
from .items.GLVolumeItem import *
importAll('items', globals(), locals())
\
from .MeshData import MeshData from .MeshData import MeshData
## for backward compatibility: ## for backward compatibility:
#MeshData.MeshData = MeshData ## breaks autodoc. #MeshData.MeshData = MeshData ## breaks autodoc.