wxPython:使用 GridBagSizer 和 Timer 更新面板上的标签
wxPython : Update the label on Panel with GridBagSizer and Timer
我想更新面板“标签”,但我认为我的 Refresh/Update/Remove 方法不对。
我写了2个python文件,“WriteData.py”会自动更新一个txt文件,而“Main.py”想在[=43上显示txt值=].
我运行同时处理2个python文件,使用Timer每3秒自动更新一次数据。
而我用的是GridBagSizer希望能安排好这些panel的位置。
但我不知道如何安排新的更新面板位置,也不知道如何删除以前的面板 .
希望大家多多指教,甚至指出我的错误。
我也很欣赏有关此的一些示例代码!
这里是“Main.py”
import wx
import time
def ReadData():
with open('RealTime.txt') as f:
for line in f:
data = line.split()
results = map(float, data)
return results
class BlockWindow(wx.Panel):
# code on book "wxPython in action" Listing 11.1
def __init__(self, parent, ID=-1, label="",
pos = wx.DefaultPosition, size = (100, 25)):
wx.Panel.__init__(self, parent, ID, pos, size,
wx.RAISED_BORDER, label)
self.label = label
self.SetMinSize(size)
self.Bind(wx.EVT_PAINT, self.OnPaint)
def OnPaint(self, evt):
sz = self.GetClientSize()
dc = wx.PaintDC(self)
w,h = dc.GetTextExtent(self.label)
dc.SetFont(self.GetFont())
dc.DrawText(self.label, (sz.width-w)/2, (sz.height-h)/2)
class MyPanel(wx.Panel):
def __init__(self, parent):
wx.Panel.__init__(self, parent, size=(0,0))
self.timer = wx.Timer(self)
self.Bind(wx.EVT_TIMER, self.OnTimer, self.timer)
self.timer.Start(3000)
def OnTimer(self, evt):
Data = ReadData()
sizer = wx.GridBagSizer(hgap=5, vgap=-1)
bw = BlockWindow(self, label="Item 1" )
sizer.Add(bw, pos=(4, 2))
#bw.Refresh()
bw = BlockWindow(self, label="Updated : %.3f" % Data[0])
sizer.Add(bw, pos=(5, 2))
bw.Refresh()
#bw.Update(self, label ="Updated : %.3f" % Data[0] )
mainSizer = wx.BoxSizer(wx.VERTICAL)
mainSizer.Add(sizer, 0, wx.EXPAND|wx.ALL, 10)
self.SetSizer(mainSizer)
self.Fit()
class MyFrame(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, title=' Frame Title')
mypanel = MyPanel(self)
self.SetSize(wx.Size(800,600))
self.Centre()
app = wx.App(False)
MyFrame().Show()
app.MainLoop()
这里是'WriteData.py',
import sched, time
from datetime import datetime as dt
data = ['5.564', '3.4', '2.176', '7.3', '4.4', '5.5', '2.3', '4.4', '5.1']
index = 0
while True:
start = dt.now().hour
stop = dt.now().hour + 1
if index >7 : index=1
if dt.now().hour in range(start, stop): # start, stop are integers (eg: 6, 9)
# call to your scheduled task goes here
f2 = open('RealTime.txt', 'w')
f2.write("%s " % data[index])
index = index + 1
f2.close()
time.sleep(3)
else:
time.sleep(3)
当我 运行 2.py 文件时,我遇到了这种情况 运行 例子
希望你帮我解决这个问题。
我在 win10 上使用 python2.7。
此致,唐国廷
您无需在每次需要更新时从头开始重新创建所有内容。只需将初始化代码(您在其中创建 BlockWindow
s 和 sizer 的地方移动到 MyPanel
的构造函数。似乎您想要做的就是更新第二个面板的标签,为此您可以编写BlockWindow
中的一个方法将更新标签并调用 Refresh
以便触发 OnPaint
并处理其余部分。
class BlockWindow(wx.Panel):
# code on book "wxPython in action" Listing 11.1
def __init__(self, parent, ID=-1, label="",
pos = wx.DefaultPosition, size = (100, 25)):
wx.Panel.__init__(self, parent, ID, pos, size,
wx.RAISED_BORDER, label)
self.label = label
self.SetMinSize(size)
self.Bind(wx.EVT_PAINT, self.OnPaint)
def OnPaint(self, evt):
sz = self.GetClientSize()
dc = wx.PaintDC(self)
w,h = dc.GetTextExtent(self.label)
dc.SetFont(self.GetFont())
dc.DrawText(self.label, (sz.width-w)/2, (sz.height-h)/2)
def UpdateLabel(self, label):
self.label = label
self.Refresh()
class MyPanel(wx.Panel):
def __init__(self, parent):
wx.Panel.__init__(self, parent, size=(0,0))
sizer = wx.GridBagSizer(hgap=5, vgap=-1)
bw = BlockWindow(self, label="Item 1" )
sizer.Add(bw, pos=(4, 2))
self.block = BlockWindow(self, label="")
sizer.Add(self.block, pos=(5, 2))
mainSizer = wx.BoxSizer(wx.VERTICAL)
mainSizer.Add(sizer, 0, wx.EXPAND|wx.ALL, 10)
self.SetSizer(mainSizer)
self.Fit()
self.timer = wx.Timer(self)
self.Bind(wx.EVT_TIMER, self.OnTimer, self.timer)
self.timer.Start(3000)
def OnTimer(self, evt):
Data = ReadData()
self.block.UpdateLabel("Updated : %.3f" % Data[0])
我想更新面板“标签”,但我认为我的 Refresh/Update/Remove 方法不对。
我写了2个python文件,“WriteData.py”会自动更新一个txt文件,而“Main.py”想在[=43上显示txt值=].
我运行同时处理2个python文件,使用Timer每3秒自动更新一次数据。
而我用的是GridBagSizer希望能安排好这些panel的位置。
但我不知道如何安排新的更新面板位置,也不知道如何删除以前的面板 .
希望大家多多指教,甚至指出我的错误。 我也很欣赏有关此的一些示例代码!
这里是“Main.py”
import wx
import time
def ReadData():
with open('RealTime.txt') as f:
for line in f:
data = line.split()
results = map(float, data)
return results
class BlockWindow(wx.Panel):
# code on book "wxPython in action" Listing 11.1
def __init__(self, parent, ID=-1, label="",
pos = wx.DefaultPosition, size = (100, 25)):
wx.Panel.__init__(self, parent, ID, pos, size,
wx.RAISED_BORDER, label)
self.label = label
self.SetMinSize(size)
self.Bind(wx.EVT_PAINT, self.OnPaint)
def OnPaint(self, evt):
sz = self.GetClientSize()
dc = wx.PaintDC(self)
w,h = dc.GetTextExtent(self.label)
dc.SetFont(self.GetFont())
dc.DrawText(self.label, (sz.width-w)/2, (sz.height-h)/2)
class MyPanel(wx.Panel):
def __init__(self, parent):
wx.Panel.__init__(self, parent, size=(0,0))
self.timer = wx.Timer(self)
self.Bind(wx.EVT_TIMER, self.OnTimer, self.timer)
self.timer.Start(3000)
def OnTimer(self, evt):
Data = ReadData()
sizer = wx.GridBagSizer(hgap=5, vgap=-1)
bw = BlockWindow(self, label="Item 1" )
sizer.Add(bw, pos=(4, 2))
#bw.Refresh()
bw = BlockWindow(self, label="Updated : %.3f" % Data[0])
sizer.Add(bw, pos=(5, 2))
bw.Refresh()
#bw.Update(self, label ="Updated : %.3f" % Data[0] )
mainSizer = wx.BoxSizer(wx.VERTICAL)
mainSizer.Add(sizer, 0, wx.EXPAND|wx.ALL, 10)
self.SetSizer(mainSizer)
self.Fit()
class MyFrame(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, title=' Frame Title')
mypanel = MyPanel(self)
self.SetSize(wx.Size(800,600))
self.Centre()
app = wx.App(False)
MyFrame().Show()
app.MainLoop()
这里是'WriteData.py',
import sched, time
from datetime import datetime as dt
data = ['5.564', '3.4', '2.176', '7.3', '4.4', '5.5', '2.3', '4.4', '5.1']
index = 0
while True:
start = dt.now().hour
stop = dt.now().hour + 1
if index >7 : index=1
if dt.now().hour in range(start, stop): # start, stop are integers (eg: 6, 9)
# call to your scheduled task goes here
f2 = open('RealTime.txt', 'w')
f2.write("%s " % data[index])
index = index + 1
f2.close()
time.sleep(3)
else:
time.sleep(3)
当我 运行 2.py 文件时,我遇到了这种情况 运行 例子
希望你帮我解决这个问题。 我在 win10 上使用 python2.7。 此致,唐国廷
您无需在每次需要更新时从头开始重新创建所有内容。只需将初始化代码(您在其中创建 BlockWindow
s 和 sizer 的地方移动到 MyPanel
的构造函数。似乎您想要做的就是更新第二个面板的标签,为此您可以编写BlockWindow
中的一个方法将更新标签并调用 Refresh
以便触发 OnPaint
并处理其余部分。
class BlockWindow(wx.Panel):
# code on book "wxPython in action" Listing 11.1
def __init__(self, parent, ID=-1, label="",
pos = wx.DefaultPosition, size = (100, 25)):
wx.Panel.__init__(self, parent, ID, pos, size,
wx.RAISED_BORDER, label)
self.label = label
self.SetMinSize(size)
self.Bind(wx.EVT_PAINT, self.OnPaint)
def OnPaint(self, evt):
sz = self.GetClientSize()
dc = wx.PaintDC(self)
w,h = dc.GetTextExtent(self.label)
dc.SetFont(self.GetFont())
dc.DrawText(self.label, (sz.width-w)/2, (sz.height-h)/2)
def UpdateLabel(self, label):
self.label = label
self.Refresh()
class MyPanel(wx.Panel):
def __init__(self, parent):
wx.Panel.__init__(self, parent, size=(0,0))
sizer = wx.GridBagSizer(hgap=5, vgap=-1)
bw = BlockWindow(self, label="Item 1" )
sizer.Add(bw, pos=(4, 2))
self.block = BlockWindow(self, label="")
sizer.Add(self.block, pos=(5, 2))
mainSizer = wx.BoxSizer(wx.VERTICAL)
mainSizer.Add(sizer, 0, wx.EXPAND|wx.ALL, 10)
self.SetSizer(mainSizer)
self.Fit()
self.timer = wx.Timer(self)
self.Bind(wx.EVT_TIMER, self.OnTimer, self.timer)
self.timer.Start(3000)
def OnTimer(self, evt):
Data = ReadData()
self.block.UpdateLabel("Updated : %.3f" % Data[0])