wxPython:使用GridBagSizer和Timer

时间:2017-03-01 15:29:57

标签: python user-interface wxpython panel

我想更新面板"标签",但我认为刷新/更新/删除方法错了。

我写了2个python文件," WriteData.py"会自动更新一个txt文件,以及" Main.py"想在wx.panel上显示txt值。

我同时运行2个python文件,使用Timer每3秒自动更新一次数据。

我使用GridBagSizer希望安排这些面板位置。

但我不知道如何安排新的更新小组位置,也不知道如何删除以前的小组

希望你给我一些建议,甚至指出我的错误。 我也很感谢有关此的一些示例代码!

这是" 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。 最诚挚的问候,唐国庭

1 个答案:

答案 0 :(得分:0)

每次需要更新时,您无需从头开始重新创建所有内容。只需将初始化代码(您创建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])