Hello,
perhaps somebody run already into a similar problem. You need a SpinCtrl for a somewhat scientific application, e.g. the gain in an oscilloscope, and you would like that the values can only be [1,2,5]*10^n with n[-N,..,N]. I tried to do this with the following code. But I am not happy with it, since the event handler needs to call the GetNextValue() method, which then calls the SetValue() method, which triggers another event ...
Any hints to make it better?
peter
···
--
class wxSpinSteps(wxSpinCtrl):
def __init__(self,parent,ID,minval,maxval,initial,sequence=None):
wxSpinCtrl.__init__(self,parent,ID)
self.SetRange(minval,maxval)
self.SetValue(initial)
self.valcopy = initial
if sequence == None:
self.sequence = [1,2,3,4,5,6,7,8,9]
else:
self.sequence = sequence
def GetNextValue(self):
x = self.GetValue()
z = self.valcopy
if x == z:
return 0, x # unchanged
n = floor(log10(z)) # power of old value
r = int(floor(z*pow(10,-n))) # first digit of old value
N = len(self.sequence)
for i in range(0,N):
if r <= self.sequence[i]: # first digit closest
break # or equal to value in sequence
if x > z:
i+=1 # next in sequence UP
if i > N-1: # wrap around highest
i = 0 # and take lowest
n += 1 # but increase power
else: # x < z
i-=1 # next in sequence DOWN
if i < 0: # wrap around lowest
i = N-1 # and take highest
n -= 1 # but decrease power
z = int(self.sequence[i]*pow(10,n)) # sequence[i] * 10^n
maxt = self.GetMax()
mint = self.GetMin()
if z > maxt: z = maxt # clamp above
if z < mint: z = mint # clamp below
self.valcopy = z # keep copy
self.SetValue(z) # and set value (triggers and event)
return 1, z # changed
class COscilloscope:
def __init__ (self,frame):
# other stuff
gainID = wxNewId()
gainSC = wxSpinSteps(self,gainID,1,1000,10,[1,2,5])
EVT_SPINCTRL(self,gainID,self.OnGain)
def OnGain(self,event):
sc = event.GetEventObject()
changed, value = sc.GetNextValue()
print "gain = ", value