Flowchart fixes: better job managing / saving / restoring 'muli' state of terminals
This commit is contained in:
parent
d1fdbadd19
commit
5b6f77be58
@ -71,7 +71,8 @@ class Flowchart(Node):
|
||||
if terminals is None:
|
||||
terminals = {}
|
||||
self.filePath = filePath
|
||||
Node.__init__(self, name) ## create node without terminals; we'll add these later
|
||||
Node.__init__(self, name, allowAddInput=True, allowAddOutput=True) ## create node without terminals; we'll add these later
|
||||
|
||||
|
||||
self.inputWasSet = False ## flag allows detection of changes in the absence of input change.
|
||||
self._nodes = {}
|
||||
@ -457,7 +458,7 @@ class Flowchart(Node):
|
||||
state = Node.saveState(self)
|
||||
state['nodes'] = []
|
||||
state['connects'] = []
|
||||
state['terminals'] = self.saveTerminals()
|
||||
#state['terminals'] = self.saveTerminals()
|
||||
|
||||
for name, node in self._nodes.items():
|
||||
cls = type(node)
|
||||
@ -470,7 +471,7 @@ class Flowchart(Node):
|
||||
conn = self.listConnections()
|
||||
for a, b in conn:
|
||||
state['connects'].append((a.node().name(), a.name(), b.node().name(), b.name()))
|
||||
|
||||
|
||||
state['inputNode'] = self.inputNode.saveState()
|
||||
state['outputNode'] = self.outputNode.saveState()
|
||||
|
||||
@ -486,7 +487,8 @@ class Flowchart(Node):
|
||||
nodes.sort(lambda a, b: cmp(a['pos'][0], b['pos'][0]))
|
||||
for n in nodes:
|
||||
if n['name'] in self._nodes:
|
||||
self._nodes[n['name']].moveBy(*n['pos'])
|
||||
#self._nodes[n['name']].graphicsItem().moveBy(*n['pos'])
|
||||
self._nodes[n['name']].restoreState(n['state'])
|
||||
continue
|
||||
try:
|
||||
node = self.createNode(n['class'], name=n['name'])
|
||||
@ -498,7 +500,7 @@ class Flowchart(Node):
|
||||
self.inputNode.restoreState(state.get('inputNode', {}))
|
||||
self.outputNode.restoreState(state.get('outputNode', {}))
|
||||
|
||||
self.restoreTerminals(state['terminals'])
|
||||
#self.restoreTerminals(state['terminals'])
|
||||
for n1, t1, n2, t2 in state['connects']:
|
||||
try:
|
||||
self.connectTerminals(self._nodes[n1][t1], self._nodes[n2][t2])
|
||||
|
@ -1,16 +1,13 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from pyqtgraph.Qt import QtCore, QtGui
|
||||
#from PySide import QtCore, QtGui
|
||||
from pyqtgraph.graphicsItems.GraphicsObject import GraphicsObject
|
||||
import pyqtgraph.functions as fn
|
||||
from .Terminal import *
|
||||
from collections import OrderedDict
|
||||
from pyqtgraph.debug import *
|
||||
import numpy as np
|
||||
#from pyqtgraph.ObjectWorkaround import QObjectWorkaround
|
||||
from .eq import *
|
||||
|
||||
#TETRACYCLINE = True
|
||||
|
||||
def strDict(d):
|
||||
return dict([(str(k), v) for k, v in d.items()])
|
||||
@ -32,8 +29,8 @@ class Node(QtCore.QObject):
|
||||
self.bypassButton = None ## this will be set by the flowchart ctrl widget..
|
||||
self._graphicsItem = None
|
||||
self.terminals = OrderedDict()
|
||||
self._inputs = {}
|
||||
self._outputs = {}
|
||||
self._inputs = OrderedDict()
|
||||
self._outputs = OrderedDict()
|
||||
self._allowAddInput = allowAddInput ## flags to allow the user to add/remove terminals
|
||||
self._allowAddOutput = allowAddOutput
|
||||
self._allowRemove = allowRemove
|
||||
@ -85,24 +82,16 @@ class Node(QtCore.QObject):
|
||||
def terminalRenamed(self, term, oldName):
|
||||
"""Called after a terminal has been renamed"""
|
||||
newName = term.name()
|
||||
#print "node", self, "handling rename..", newName, oldName
|
||||
for d in [self.terminals, self._inputs, self._outputs]:
|
||||
if oldName not in d:
|
||||
continue
|
||||
#print " got one"
|
||||
d[newName] = d[oldName]
|
||||
del d[oldName]
|
||||
|
||||
self.graphicsItem().updateTerminals()
|
||||
#self.emit(QtCore.SIGNAL('terminalRenamed'), term, oldName)
|
||||
self.sigTerminalRenamed.emit(term, oldName)
|
||||
|
||||
def addTerminal(self, name, **opts):
|
||||
#print "Node.addTerminal called. name:", name, "opts:", opts
|
||||
#global TETRACYCLINE
|
||||
#print "TETRACYCLINE: ", TETRACYCLINE
|
||||
#if TETRACYCLINE:
|
||||
#print "Creating Terminal..."
|
||||
name = self.nextTerminalName(name)
|
||||
term = Terminal(self, name, **opts)
|
||||
self.terminals[name] = term
|
||||
@ -278,12 +267,20 @@ class Node(QtCore.QObject):
|
||||
|
||||
def saveState(self):
|
||||
pos = self.graphicsItem().pos()
|
||||
return {'pos': (pos.x(), pos.y()), 'bypass': self.isBypassed()}
|
||||
state = {'pos': (pos.x(), pos.y()), 'bypass': self.isBypassed()}
|
||||
termsEditable = self._allowAddInput | self._allowAddOutput
|
||||
for term in self._inputs.values() + self._outputs.values():
|
||||
termsEditable |= term._renamable | term._removable | term._multiable
|
||||
if termsEditable:
|
||||
state['terminals'] = self.saveTerminals()
|
||||
return state
|
||||
|
||||
def restoreState(self, state):
|
||||
pos = state.get('pos', (0,0))
|
||||
self.graphicsItem().setPos(*pos)
|
||||
self.bypass(state.get('bypass', False))
|
||||
if 'terminals' in state:
|
||||
self.restoreTerminals(state['terminals'])
|
||||
|
||||
def saveTerminals(self):
|
||||
terms = OrderedDict()
|
||||
@ -309,8 +306,8 @@ class Node(QtCore.QObject):
|
||||
for t in self.terminals.values():
|
||||
t.close()
|
||||
self.terminals = OrderedDict()
|
||||
self._inputs = {}
|
||||
self._outputs = {}
|
||||
self._inputs = OrderedDict()
|
||||
self._outputs = OrderedDict()
|
||||
|
||||
def close(self):
|
||||
"""Cleans up after the node--removes terminals, graphicsItem, widget"""
|
||||
@ -493,10 +490,6 @@ class NodeGraphicsItem(GraphicsObject):
|
||||
self.hovered = False
|
||||
self.update()
|
||||
|
||||
#def mouseReleaseEvent(self, ev):
|
||||
#ret = QtGui.QGraphicsItem.mouseReleaseEvent(self, ev)
|
||||
#return ret
|
||||
|
||||
def keyPressEvent(self, ev):
|
||||
if ev.key() == QtCore.Qt.Key_Delete or ev.key() == QtCore.Qt.Key_Backspace:
|
||||
ev.accept()
|
||||
@ -513,13 +506,8 @@ class NodeGraphicsItem(GraphicsObject):
|
||||
return GraphicsObject.itemChange(self, change, val)
|
||||
|
||||
|
||||
#def contextMenuEvent(self, ev):
|
||||
#ev.accept()
|
||||
#self.menu.popup(ev.screenPos())
|
||||
|
||||
def getMenu(self):
|
||||
return self.menu
|
||||
|
||||
|
||||
def getContextMenus(self, event):
|
||||
return [self.menu]
|
||||
@ -548,25 +536,3 @@ class NodeGraphicsItem(GraphicsObject):
|
||||
def addOutputFromMenu(self): ## called when add output is clicked in context menu
|
||||
self.node.addOutput(renamable=True, removable=True, multiable=False)
|
||||
|
||||
#def menuTriggered(self, action):
|
||||
##print "node.menuTriggered called. action:", action
|
||||
#act = str(action.text())
|
||||
#if act == "Add input":
|
||||
#self.node.addInput()
|
||||
#self.updateActionMenu()
|
||||
#elif act == "Add output":
|
||||
#self.node.addOutput()
|
||||
#self.updateActionMenu()
|
||||
#elif act == "Remove node":
|
||||
#self.node.close()
|
||||
#else: ## only other option is to remove a terminal
|
||||
#self.node.removeTerminal(act)
|
||||
#self.terminalMenu.removeAction(action)
|
||||
|
||||
#def updateActionMenu(self):
|
||||
#for t in self.node.terminals:
|
||||
#if t not in [str(a.text()) for a in self.terminalMenu.actions()]:
|
||||
#self.terminalMenu.addAction(t)
|
||||
#for a in self.terminalMenu.actions():
|
||||
#if str(a.text()) not in self.node.terminals:
|
||||
#self.terminalMenu.removeAction(a)
|
||||
|
@ -45,7 +45,7 @@ class Terminal:
|
||||
self._value = {} ## dictionary of terminal:value pairs.
|
||||
else:
|
||||
self._value = None
|
||||
|
||||
|
||||
self.valueOk = None
|
||||
self.recolor()
|
||||
|
||||
@ -70,6 +70,8 @@ class Terminal:
|
||||
return
|
||||
self._value = val
|
||||
else:
|
||||
if not isinstance(self._value, dict):
|
||||
self._value = {}
|
||||
if val is not None:
|
||||
self._value.update(val)
|
||||
|
||||
@ -132,9 +134,14 @@ class Terminal:
|
||||
def isMultiValue(self):
|
||||
return self._multi
|
||||
|
||||
def setMultiValue(self, b):
|
||||
def setMultiValue(self, multi):
|
||||
"""Set whether this is a multi-value terminal."""
|
||||
self._multi = b
|
||||
self._multi = multi
|
||||
if not multi and len(self.inputTerminals()) > 1:
|
||||
self.disconnectAll()
|
||||
|
||||
for term in self.inputTerminals():
|
||||
self.inputChanged(term)
|
||||
|
||||
def isOutput(self):
|
||||
return self._io == 'out'
|
||||
@ -407,6 +414,8 @@ class TerminalGraphicsItem(GraphicsObject):
|
||||
multiAct = QtGui.QAction("Multi-value", self.menu)
|
||||
multiAct.setCheckable(True)
|
||||
multiAct.setChecked(self.term.isMultiValue())
|
||||
multiAct.setEnabled(self.term.isMultiable())
|
||||
|
||||
multiAct.triggered.connect(self.toggleMulti)
|
||||
self.menu.addAction(multiAct)
|
||||
self.menu.multiAct = multiAct
|
||||
|
@ -240,7 +240,7 @@ class EvalNode(Node):
|
||||
def saveState(self):
|
||||
state = Node.saveState(self)
|
||||
state['text'] = str(self.text.toPlainText())
|
||||
state['terminals'] = self.saveTerminals()
|
||||
#state['terminals'] = self.saveTerminals()
|
||||
return state
|
||||
|
||||
def restoreState(self, state):
|
||||
@ -282,7 +282,7 @@ class ColumnJoinNode(Node):
|
||||
|
||||
def addInput(self):
|
||||
#print "ColumnJoinNode.addInput called."
|
||||
term = Node.addInput(self, 'input', renamable=True)
|
||||
term = Node.addInput(self, 'input', renamable=True, removable=True)
|
||||
#print "Node.addInput returned. term:", term
|
||||
item = QtGui.QTreeWidgetItem([term.name()])
|
||||
item.term = term
|
||||
@ -322,16 +322,14 @@ class ColumnJoinNode(Node):
|
||||
|
||||
def restoreState(self, state):
|
||||
Node.restoreState(self, state)
|
||||
inputs = [inp.name() for inp in self.inputs()]
|
||||
inputs = self.inputs()
|
||||
order = [name for name in state['order'] if name in inputs]
|
||||
for name in inputs:
|
||||
if name not in state['order']:
|
||||
self.removeTerminal(name)
|
||||
for name in state['order']:
|
||||
if name not in inputs:
|
||||
Node.addInput(self, name, renamable=True)
|
||||
if name not in order:
|
||||
order.append(name)
|
||||
|
||||
self.tree.clear()
|
||||
for name in state['order']:
|
||||
for name in order:
|
||||
term = self[name]
|
||||
item = QtGui.QTreeWidgetItem([name])
|
||||
item.term = term
|
||||
|
@ -153,7 +153,7 @@ def denoise(data, radius=2, threshold=4):
|
||||
|
||||
r2 = radius * 2
|
||||
d1 = data.view(np.ndarray)
|
||||
d2 = data[radius:] - data[:-radius] #a derivative
|
||||
d2 = d1[radius:] - d1[:-radius] #a derivative
|
||||
#d3 = data[r2:] - data[:-r2]
|
||||
#d4 = d2 - d3
|
||||
stdev = d2.std()
|
||||
|
Loading…
Reference in New Issue
Block a user