commit
dce9a5bf0c
@ -3,6 +3,7 @@ from .Qt import QtCore
|
||||
from .ptime import time
|
||||
from . import ThreadsafeTimer
|
||||
import weakref
|
||||
from .functions import SignalBlock
|
||||
|
||||
__all__ = ['SignalProxy']
|
||||
|
||||
@ -34,7 +35,7 @@ class SignalProxy(QtCore.QObject):
|
||||
self.args = None
|
||||
self.timer = ThreadsafeTimer.ThreadsafeTimer()
|
||||
self.timer.timeout.connect(self.flush)
|
||||
self.block = False
|
||||
self.blockSignal = False
|
||||
self.slot = weakref.ref(slot)
|
||||
self.lastFlushTime = None
|
||||
if slot is not None:
|
||||
@ -45,7 +46,7 @@ class SignalProxy(QtCore.QObject):
|
||||
|
||||
def signalReceived(self, *args):
|
||||
"""Received signal. Cancel previous timer and store args to be forwarded later."""
|
||||
if self.block:
|
||||
if self.blockSignal:
|
||||
return
|
||||
self.args = args
|
||||
if self.rateLimit == 0:
|
||||
@ -61,11 +62,10 @@ class SignalProxy(QtCore.QObject):
|
||||
|
||||
self.timer.stop()
|
||||
self.timer.start((min(leakTime, self.delay)*1000)+1)
|
||||
|
||||
|
||||
def flush(self):
|
||||
"""If there is a signal queued up, send it now."""
|
||||
if self.args is None or self.block:
|
||||
if self.args is None or self.blockSignal:
|
||||
return False
|
||||
args, self.args = self.args, None
|
||||
self.timer.stop()
|
||||
@ -75,7 +75,7 @@ class SignalProxy(QtCore.QObject):
|
||||
return True
|
||||
|
||||
def disconnect(self):
|
||||
self.block = True
|
||||
self.blockSignal = True
|
||||
try:
|
||||
self.signal.disconnect(self.signalReceived)
|
||||
except:
|
||||
@ -85,18 +85,10 @@ class SignalProxy(QtCore.QObject):
|
||||
except:
|
||||
pass
|
||||
|
||||
|
||||
|
||||
#def proxyConnect(source, signal, slot, delay=0.3):
|
||||
#"""Connect a signal to a slot with delay. Returns the SignalProxy
|
||||
#object that was created. Be sure to store this object so it is not
|
||||
#garbage-collected immediately."""
|
||||
#sp = SignalProxy(source, signal, delay)
|
||||
#if source is None:
|
||||
#sp.connect(sp, QtCore.SIGNAL('signal'), slot)
|
||||
#else:
|
||||
#sp.connect(sp, signal, slot)
|
||||
#return sp
|
||||
def block(self):
|
||||
"""Return a SignalBlocker that temporarily blocks input signals to this proxy.
|
||||
"""
|
||||
return SignalBlock(self.signal, self.signalReceived)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
@ -14,22 +14,33 @@ class Vector(QtGui.QVector3D):
|
||||
def __init__(self, *args):
|
||||
if len(args) == 1:
|
||||
if isinstance(args[0], QtCore.QSizeF):
|
||||
QtGui.QVector3D.__init__(self, float(args[0].width()), float(args[0].height()), 0)
|
||||
return
|
||||
x = float(args[0].width())
|
||||
y = float(args[0].height())
|
||||
z = 0
|
||||
elif isinstance(args[0], QtCore.QPoint) or isinstance(args[0], QtCore.QPointF):
|
||||
QtGui.QVector3D.__init__(self, float(args[0].x()), float(args[0].y()), 0)
|
||||
x = float(args[0].x())
|
||||
y = float(args[0].y())
|
||||
z = 0
|
||||
elif isinstance(args[0], QtGui.QVector3D):
|
||||
x = args[0].x()
|
||||
y = args[0].y()
|
||||
z = args[0].z()
|
||||
elif hasattr(args[0], '__getitem__'):
|
||||
vals = list(args[0])
|
||||
if len(vals) == 2:
|
||||
vals.append(0)
|
||||
if len(vals) != 3:
|
||||
raise Exception('Cannot init Vector with sequence of length %d' % len(args[0]))
|
||||
QtGui.QVector3D.__init__(self, *vals)
|
||||
return
|
||||
x, y = vals
|
||||
z = 0
|
||||
elif len(vals) == 3:
|
||||
x, y, z = vals
|
||||
else:
|
||||
raise ValueError('Cannot init Vector with sequence of length %d' % len(args[0]))
|
||||
elif len(args) == 2:
|
||||
QtGui.QVector3D.__init__(self, args[0], args[1], 0)
|
||||
return
|
||||
QtGui.QVector3D.__init__(self, *args)
|
||||
x, y = args
|
||||
z = 0
|
||||
else:
|
||||
x, y, z = args # Could raise ValueError
|
||||
|
||||
QtGui.QVector3D.__init__(self, x, y, z)
|
||||
|
||||
def __len__(self):
|
||||
return 3
|
||||
|
@ -447,7 +447,7 @@ class ConsoleWidget(QtGui.QWidget):
|
||||
filterStr = str(self.ui.filterText.text())
|
||||
if filterStr != '':
|
||||
if isinstance(exc, Exception):
|
||||
msg = exc.message
|
||||
msg = traceback.format_exception_only(type(exc), exc)
|
||||
elif isinstance(exc, basestring):
|
||||
msg = exc
|
||||
else:
|
||||
|
@ -1151,7 +1151,22 @@ class ThreadTrace(object):
|
||||
for id, frame in sys._current_frames().items():
|
||||
if id == threading.current_thread().ident:
|
||||
continue
|
||||
print("<< thread %d >>" % id)
|
||||
|
||||
# try to determine a thread name
|
||||
try:
|
||||
name = threading._active.get(id, None)
|
||||
except:
|
||||
name = None
|
||||
if name is None:
|
||||
try:
|
||||
# QThread._names must be manually set by thread creators.
|
||||
name = QtCore.QThread._names.get(id)
|
||||
except:
|
||||
name = None
|
||||
if name is None:
|
||||
name = "???"
|
||||
|
||||
print("<< thread %d \"%s\" >>" % (id, name))
|
||||
traceback.print_stack(frame)
|
||||
print("===============================================\n")
|
||||
|
||||
|
@ -222,8 +222,8 @@ class InfiniteLine(GraphicsObject):
|
||||
|
||||
def setPos(self, pos):
|
||||
|
||||
if type(pos) in [list, tuple]:
|
||||
newPos = pos
|
||||
if type(pos) in [list, tuple, np.ndarray]:
|
||||
newPos = list(pos)
|
||||
elif isinstance(pos, QtCore.QPointF):
|
||||
newPos = [pos.x(), pos.y()]
|
||||
else:
|
||||
|
@ -5,12 +5,12 @@ from .ParameterItem import ParameterItem
|
||||
from ..widgets.SpinBox import SpinBox
|
||||
from ..widgets.ColorButton import ColorButton
|
||||
from ..colormap import ColorMap
|
||||
#from ..widgets.GradientWidget import GradientWidget ## creates import loop
|
||||
from .. import pixmaps as pixmaps
|
||||
from .. import functions as fn
|
||||
import os, sys
|
||||
from ..pgcollections import OrderedDict
|
||||
|
||||
|
||||
class WidgetParameterItem(ParameterItem):
|
||||
"""
|
||||
ParameterTree item with:
|
||||
@ -38,7 +38,6 @@ class WidgetParameterItem(ParameterItem):
|
||||
self.hideWidget = True ## hide edit widget, replace with label when not selected
|
||||
## set this to False to keep the editor widget always visible
|
||||
|
||||
|
||||
## build widget into column 1 with a display label and default button.
|
||||
w = self.makeWidget()
|
||||
self.widget = w
|
||||
@ -162,8 +161,6 @@ class WidgetParameterItem(ParameterItem):
|
||||
self.focusNext(forward=False)
|
||||
return True ## don't let anyone else see this event
|
||||
|
||||
#elif ev.type() == ev.FocusOut:
|
||||
#self.hideEditor()
|
||||
return False
|
||||
|
||||
def setFocus(self):
|
||||
@ -272,7 +269,6 @@ class WidgetParameterItem(ParameterItem):
|
||||
def optsChanged(self, param, opts):
|
||||
"""Called when any options are changed that are not
|
||||
name, value, default, or limits"""
|
||||
#print "opts changed:", opts
|
||||
ParameterItem.optsChanged(self, param, opts)
|
||||
|
||||
if 'readonly' in opts:
|
||||
@ -317,6 +313,11 @@ class SimpleParameter(Parameter):
|
||||
self.value = self.colorValue
|
||||
self.saveState = self.saveColorState
|
||||
|
||||
def setValue(self, value, blockSignal=None):
|
||||
if self.opts['type'] == 'int':
|
||||
value = int(value)
|
||||
Parameter.setValue(self, value, blockSignal)
|
||||
|
||||
def colorValue(self):
|
||||
return fn.mkColor(Parameter.value(self))
|
||||
|
||||
@ -343,9 +344,8 @@ class SimpleParameter(Parameter):
|
||||
if not isinstance(v, ColorMap):
|
||||
raise TypeError("Cannot set colormap parameter from object %r" % v)
|
||||
return v
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
registerParameterType('int', SimpleParameter, override=True)
|
||||
registerParameterType('float', SimpleParameter, override=True)
|
||||
registerParameterType('bool', SimpleParameter, override=True)
|
||||
@ -354,8 +354,6 @@ registerParameterType('color', SimpleParameter, override=True)
|
||||
registerParameterType('colormap', SimpleParameter, override=True)
|
||||
|
||||
|
||||
|
||||
|
||||
class GroupParameterItem(ParameterItem):
|
||||
"""
|
||||
Group parameters are used mainly as a generic parent item that holds (and groups!) a set
|
||||
@ -383,7 +381,6 @@ class GroupParameterItem(ParameterItem):
|
||||
w.setLayout(l)
|
||||
l.addWidget(self.addWidget)
|
||||
l.addStretch()
|
||||
#l.addItem(QtGui.QSpacerItem(200, 10, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum))
|
||||
self.addWidgetBox = w
|
||||
self.addItem = QtGui.QTreeWidgetItem([])
|
||||
self.addItem.setFlags(QtCore.Qt.ItemIsEnabled)
|
||||
@ -458,7 +455,8 @@ class GroupParameterItem(ParameterItem):
|
||||
self.addWidget.addItem(t)
|
||||
finally:
|
||||
self.addWidget.blockSignals(False)
|
||||
|
||||
|
||||
|
||||
class GroupParameter(Parameter):
|
||||
"""
|
||||
Group parameters are used mainly as a generic parent item that holds (and groups!) a set
|
||||
@ -486,14 +484,10 @@ class GroupParameter(Parameter):
|
||||
"""Change the list of options available for the user to add to the group."""
|
||||
self.setOpts(addList=vals)
|
||||
|
||||
|
||||
|
||||
registerParameterType('group', GroupParameter, override=True)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class ListParameterItem(WidgetParameterItem):
|
||||
"""
|
||||
WidgetParameterItem subclass providing comboBox that lets the user select from a list of options.
|
||||
@ -503,7 +497,6 @@ class ListParameterItem(WidgetParameterItem):
|
||||
self.targetValue = None
|
||||
WidgetParameterItem.__init__(self, param, depth)
|
||||
|
||||
|
||||
def makeWidget(self):
|
||||
opts = self.param.opts
|
||||
t = opts['type']
|
||||
@ -551,7 +544,6 @@ class ListParameterItem(WidgetParameterItem):
|
||||
self.updateDisplayLabel()
|
||||
finally:
|
||||
self.widget.blockSignals(False)
|
||||
|
||||
|
||||
|
||||
class ListParameter(Parameter):
|
||||
@ -561,7 +553,7 @@ class ListParameter(Parameter):
|
||||
self.forward = OrderedDict() ## {name: value, ...}
|
||||
self.reverse = ([], []) ## ([value, ...], [name, ...])
|
||||
|
||||
## Parameter uses 'limits' option to define the set of allowed values
|
||||
# Parameter uses 'limits' option to define the set of allowed values
|
||||
if 'values' in opts:
|
||||
opts['limits'] = opts['values']
|
||||
if opts.get('limits', None) is None:
|
||||
@ -576,24 +568,9 @@ class ListParameter(Parameter):
|
||||
if len(self.reverse[0]) > 0 and self.value() not in self.reverse[0]:
|
||||
self.setValue(self.reverse[0][0])
|
||||
|
||||
#def addItem(self, name, value=None):
|
||||
#if name in self.forward:
|
||||
#raise Exception("Name '%s' is already in use for this parameter" % name)
|
||||
#limits = self.opts['limits']
|
||||
#if isinstance(limits, dict):
|
||||
#limits = limits.copy()
|
||||
#limits[name] = value
|
||||
#self.setLimits(limits)
|
||||
#else:
|
||||
#if value is not None:
|
||||
#raise Exception ## raise exception or convert to dict?
|
||||
#limits = limits[:]
|
||||
#limits.append(name)
|
||||
## what if limits == None?
|
||||
|
||||
@staticmethod
|
||||
def mapping(limits):
|
||||
## Return forward and reverse mapping objects given a limit specification
|
||||
# Return forward and reverse mapping objects given a limit specification
|
||||
forward = OrderedDict() ## {name: value, ...}
|
||||
reverse = ([], []) ## ([value, ...], [name, ...])
|
||||
if isinstance(limits, dict):
|
||||
@ -658,7 +635,6 @@ class ActionParameter(Parameter):
|
||||
registerParameterType('action', ActionParameter, override=True)
|
||||
|
||||
|
||||
|
||||
class TextParameterItem(WidgetParameterItem):
|
||||
def __init__(self, param, depth):
|
||||
WidgetParameterItem.__init__(self, param, depth)
|
||||
@ -693,7 +669,6 @@ class TextParameterItem(WidgetParameterItem):
|
||||
class TextParameter(Parameter):
|
||||
"""Editable string; displayed as large text box in the tree."""
|
||||
itemClass = TextParameterItem
|
||||
|
||||
|
||||
|
||||
registerParameterType('text', TextParameter, override=True)
|
||||
|
@ -98,6 +98,19 @@ def check_interpolateArray(order):
|
||||
|
||||
assert_array_almost_equal(r1, r2)
|
||||
|
||||
def test_subArray():
|
||||
a = np.array([0, 0, 111, 112, 113, 0, 121, 122, 123, 0, 0, 0, 211, 212, 213, 0, 221, 222, 223, 0, 0, 0, 0])
|
||||
b = pg.subArray(a, offset=2, shape=(2,2,3), stride=(10,4,1))
|
||||
c = np.array([[[111,112,113], [121,122,123]], [[211,212,213], [221,222,223]]])
|
||||
assert np.all(b == c)
|
||||
|
||||
# operate over first axis; broadcast over the rest
|
||||
aa = np.vstack([a, a/100.]).T
|
||||
cc = np.empty(c.shape + (2,))
|
||||
cc[..., 0] = c
|
||||
cc[..., 1] = c / 100.
|
||||
bb = pg.subArray(aa, offset=2, shape=(2,2,3), stride=(10,4,1))
|
||||
assert np.all(bb == cc)
|
||||
|
||||
def test_subArray():
|
||||
a = np.array([0, 0, 111, 112, 113, 0, 121, 122, 123, 0, 0, 0, 211, 212, 213, 0, 221, 222, 223, 0, 0, 0, 0])
|
||||
|
@ -10,7 +10,7 @@
|
||||
## No unicode variable names (μ,Ω) allowed until python 3
|
||||
|
||||
SI_PREFIXES = 'yzafpnum kMGTPEZY'
|
||||
UNITS = 'm,s,g,W,J,V,A,F,T,Hz,Ohm,S,N,C,px,b,B'.split(',')
|
||||
UNITS = 'm,s,g,W,J,V,A,F,T,Hz,Ohm,S,N,C,px,b,B,Pa'.split(',')
|
||||
allUnits = {}
|
||||
|
||||
def addUnit(p, n):
|
||||
|
@ -31,4 +31,5 @@ class BusyCursor(object):
|
||||
def __exit__(self, *args):
|
||||
if self._active:
|
||||
BusyCursor.active.pop(-1)
|
||||
QtGui.QApplication.restoreOverrideCursor()
|
||||
if len(BusyCursor.active) == 0:
|
||||
QtGui.QApplication.restoreOverrideCursor()
|
||||
|
@ -1,5 +1,6 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from ..Qt import QtGui, QtCore
|
||||
from .. import ptime
|
||||
|
||||
__all__ = ['ProgressDialog']
|
||||
|
||||
@ -40,7 +41,7 @@ class ProgressDialog(QtGui.QProgressDialog):
|
||||
nested (bool) If True, then this progress bar will be displayed inside
|
||||
any pre-existing progress dialogs that also allow nesting.
|
||||
============== ================================================================
|
||||
"""
|
||||
"""
|
||||
# attributes used for nesting dialogs
|
||||
self.nestedLayout = None
|
||||
self._nestableWidgets = None
|
||||
@ -48,6 +49,9 @@ class ProgressDialog(QtGui.QProgressDialog):
|
||||
self._topDialog = None
|
||||
self._subBars = []
|
||||
self.nested = nested
|
||||
|
||||
# for rate-limiting Qt event processing during progress bar update
|
||||
self._lastProcessEvents = None
|
||||
|
||||
isGuiThread = QtCore.QThread.currentThread() == QtCore.QCoreApplication.instance().thread()
|
||||
self.disabled = disable or (not isGuiThread)
|
||||
@ -203,7 +207,10 @@ class ProgressDialog(QtGui.QProgressDialog):
|
||||
# Qt docs say this should happen automatically, but that doesn't seem
|
||||
# to be the case.
|
||||
if self.windowModality() == QtCore.Qt.WindowModal:
|
||||
QtGui.QApplication.processEvents()
|
||||
now = ptime.time()
|
||||
if self._lastProcessEvents is None or (now - self._lastProcessEvents) > 0.2:
|
||||
QtGui.QApplication.processEvents()
|
||||
self._lastProcessEvents = now
|
||||
|
||||
def setLabelText(self, val):
|
||||
if self.disabled:
|
||||
|
Loading…
Reference in New Issue
Block a user