我有一个开始'采样'的计时器(现在只是一个随机编号)并绘制成图表 - 按下'开始'时启动计时器。这样工作正常(绘图效果不是很好,但它有效),虽然我的问题是引入一个'目标'值,使得样本值被 - 改变,但只有在输入键输入目标之后甚至更新按钮。
目前,对目标SpinCtrl小部件所做的任何更改都是如此直播,我不希望如此,我只想在Enter后更新
所以我理解我的问题涉及计时器,绑定事件和* wx.EVT_TEXT_ENTER *;在计时器已经运行时我捕获了多少文本条目?
原谅我缺乏蟒蛇知识。
我的代码:
print( "\n- Please Wait -- Importing Matplotlib and Related Modules...\n" )
import matplotlib
import numpy
import wx
import numpy as np
matplotlib.use('WXAgg')
from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as FigureCanvas
from matplotlib.backends.backend_wx import NavigationToolbar2Wx
from matplotlib.figure import Figure
import random
SamplingTime = 1# in ms
class GraphPanel( wx.Panel ) :
def __init__( self, parent, position ) :
wx.Panel.__init__( self, parent, pos=position, size=(800,320) )
# initialize matplotlib
self.figure = matplotlib.figure.Figure( None, facecolor="white" )
self.canvas = matplotlib.backends.backend_wxagg.FigureCanvasWxAgg( self, -1, self.figure )
self.axes = self.figure.add_subplot(111)
self.axes.grid(True, color="gray")
self.axes.set_xbound( (0,100) )
self.axes.set_ybound( (0,10) )
self.axes.set_xlabel( "Sample" )
self.axes.set_ylabel( "Data" )
self._SetSize()
self.Bind( wx.EVT_SIZE, self._SetSize )
self.Data = []
def updateData(self, value):
self.Data.append( value )
x = np.arange( len(self.Data) )
y = np.array(self.Data)
yMin = round(min(y)) + 2
yMax = round(max(y)) + 2
self.axes = self.figure.add_subplot(111)
self.axes.grid(True, color="gray")
self.axes.plot(x,y, "-k")
self.axes.set_ybound( (yMin,yMax) )
self.axes.set_xlabel( "Sample" )
self.axes.set_ylabel( "Data" )
self._SetSize()
self.Bind( wx.EVT_SIZE, self._SetSize )
self.canvas = FigureCanvas(self, -1, self.figure)
#-----------------------------------------------------------------------------------
def _SetSize( self, event=None ):
pixels = self.GetSize()
self.SetSize( pixels )
self.canvas.SetSize( pixels )
dpi = self.figure.get_dpi()
self.figure.set_size_inches( float( pixels[0] ) / dpi,float( pixels[1] ) / dpi )
#------------------------------------------------------------------------------------
############################################ Basic Frame ###################################################
class BasicFrame(wx.Frame):
def __init__(self, parent, title):
self.Data = 0
self.DataPrevious = 1
# split the screen
wx.Frame.__init__(self, parent, title="Data Collection", size=(1100,750))
self.sp = wx.SplitterWindow(self)
self.p1 = wx.Panel(self.sp, style = wx.SUNKEN_BORDER)
self.p2 = wx.Panel(self.sp, style = wx.SUNKEN_BORDER)
self.sp.SplitVertically(self.p1, self.p2, 940)
# graph
self.Graph = GraphPanel( self.p1, position=(20, 20) )
# define control input
wx.StaticBox(self.p2, -1, "System Control", pos=(5, 5), size=(120, 210))
wx.StaticText(self.p2, -1,"Target:", pos=(15, 100))
self.Target = wx.SpinCtrl(self.p2,-1,pos=(15,120), size=(80, 20), min=5, max=10)
self.Target.Bind(wx.EVT_BUTTON, self.StartSystem)
self.StartButton = wx.Button(self.p2, -1, "Start", pos=(20,230))
self.StartButton.Bind(wx.EVT_BUTTON, self.StartSystem)
self.PauseButton = wx.Button(self.p2, -1, "Pause", pos=(20,270))
self.PauseButton.Bind(wx.EVT_BUTTON, self.PauseSystem)
self.StopButton = wx.Button(self.p2, -1, "Stop", pos=(20,500))
self.StopButton.Bind(wx.EVT_BUTTON, self.StopSystem)
# set the timers
self.SampleTimer = wx.Timer(self)
self.Bind(wx.EVT_TIMER, self.updateData, self.SampleTimer)
print( "Ready!\n" )
def sampleData(self):
Error = random.uniform(0, 0.2)
Target = self.Target.GetValue()
if( self.Data <= Target):
self.Data += self.DataPrevious*Error
elif( self.Data >= Target):
self.Data -= self.DataPrevious*Error
self.DataPrevious = self.Data
print( "Target Aim: "+str(self.Data) )
return self.Data
def updateData(self, event):
CurrentData = round(self.sampleData(),2) # obtain currnt data
self.Graph.updateData(CurrentData) # add data to graph
def StartSystem(self, event):
self.SampleTimer.Start(SamplingTime)
def PauseSystem(self, event):
self.SampleTimer.Stop()
def StopSystem(self, event):
self.SampleTimer.Stop()
self.Destroy()
app = wx.App(redirect=False)
frame = BasicFrame(None, -1)
frame.Show()
app.MainLoop()
答案 0 :(得分:1)
如果我理解正确,您只想使用SpinCtrl值更新应用程序中的内部值1)按下SpinCtrl内部输入或2)按下更新按钮。以下示例就是这样做的:
import wx
class MainWindow(wx.Frame):
def __init__(self, *args, **kwargs):
wx.Frame.__init__(self, *args, **kwargs)
self.panel = wx.Panel(self)
self.spin = wx.SpinCtrl(self.panel)
self.button = wx.Button(self.panel, label="Update")
self.sizer = wx.BoxSizer()
self.sizer.Add(self.spin)
self.sizer.Add(self.button)
self.panel.SetSizerAndFit(self.sizer)
self.Show()
# Use EVT_CHAR_HOOK on Frame insted of wx.EVT_KEY_UP on SpinCtrl
# to disable "on Enter go to next widget" functionality
self.Bind(wx.EVT_CHAR_HOOK, self.OnKey)
self.button.Bind(wx.EVT_BUTTON, self.OnUpdate)
self.timer = wx.Timer(self)
self.Bind(wx.EVT_TIMER, self.OnTimer, self.timer)
self.timer.Start(500)
self.value = 0
def OnKey(self, e):
if e.GetKeyCode() == wx.WXK_RETURN: # Is the key ENTER?
self.value = self.spin.GetValue() # Read SpinCtrl and set internal value
else: # Else let the event out of the handler
e.Skip()
def OnUpdate(self, e):
self.value = self.spin.GetValue() # Read SpinCtrl and set internal value
def OnTimer(self, e):
# Show internal value
print(self.value)
app = wx.App(False)
win = MainWindow(None)
app.MainLoop()
答案 1 :(得分:0)
如果您不想对旋转控件的每个操作做出反应,那么请不要绑定它。而是在StartTimer()函数中查询其值。