【问题标题】:wxPython : Update the label on Panel with GridBagSizer and TimerwxPython : 使用 GridBagSizer 和 Timer 更新 Panel 上的标签
【发布时间】:2017-07-21 00:24:37
【问题描述】:

我想更新面板“标签”,但我认为我的 Refresh/Update/Remove 方法有误。

我写了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。 最好的问候, 唐国廷

【问题讨论】:

    标签: python user-interface wxpython panel


    【解决方案1】:

    您无需在每次需要更新时从头开始重新创建所有内容。只需将初始化代码(您在其中创建BlockWindows 和sizers 到MyPanel 的构造函数中)移动。看来您要做的就是更新第二个面板的标签,为此您可以在@ 中编写一个方法987654323@ 将更新标签并调用 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() 和 Timer,甚至教我改进 BlockWindow 的方法。你的代码非常干净而且很有帮助!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-12-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-23
    相关资源
    最近更新 更多