gpt4 book ai didi

wxPython listctrl 快速更新闪烁

转载 作者:行者123 更新时间:2023-12-05 01:18:40 26 4
gpt4 key购买 nike

我在列表控件中放置了一些行,然后相当快地更新它们——通常数据来自总线——整个列表闪烁得非常多。阻止它这样做真的很好。

我已经尽可能地减少了代码,同时仍然保持下面示例中我正在做的事情的一般外观。

lisctrl 是在 wx.Notebook 中还是只是一个普通的 wx.Panel 似乎并不重要,所以我将笔记本留在了那里。

我已经开始研究双缓冲,但想看看是否还有其他东西可以先尝试。

在 Windows 7 上使用 wxPython 2.8.12.1 执行此操作。也发生在 XP 上。

import sys
import time
import logging
import wx
from random import randint

UPDATE_MS=10

class CanMsg(object):
def __init__(self, ID, type, len, data=None):
"""Represents a CAN message"""
self.ID=ID # 11/29-bit message identifier
self.MSGTYPE=type # Type of the message
self.LEN=len # Data Length Code of the message (0..8)
if data:
self.DATA=data
else:
self.DATA=[0,]*len

class EmulatorFrame(wx.Frame):
def __init__(self, parent, id, title, pos=wx.DefaultPosition, size=wx.DefaultSize,
style=wx.DEFAULT_FRAME_STYLE):
wx.Frame.__init__(self, parent, id, title, pos, size, style)
# create frame menu and status bar
self.status = self.CreateStatusBar()
# create tab panels
panel = wx.Panel(self)
nb = wx.Notebook(panel)
self.messages_tab = MessagesTab(nb)
# self.messages_tab = MessagesTab(panel)
# add tab pages to notebook
nb.AddPage(self.messages_tab, 'CAN data')
self._nb = nb

sizer = wx.BoxSizer()
sizer.Add(nb, 1, wx.EXPAND)
# sizer.Add(self.messages_tab, 1, wx.EXPAND)
minSize=self.ClientToWindowSize(sizer.GetMinSize()) # get this as Info tab's min size is too small
panel.SetSizerAndFit(sizer)
self.SetInitialSize(minSize)

self.InitialiseTimers()

def InitialiseTimers(self):
# tab updates and test comparison timer
self.displayTimer=wx.Timer(self)
self.Bind(wx.EVT_TIMER, self.OnRefresh, self.displayTimer)
self.displayTimer.Start(UPDATE_MS)
# self.Bind(wx.EVT_IDLE, self.OnRefresh)

def OnRefresh(self, event):
self.messages_tab.Update(can_send, can_recv)

class MessagesTab(wx.Panel):
def __init__(self, parent):
msg_size=450 # width of messge windows
wx.Panel.__init__(self, parent, wx.ID_ANY)

receivedLabel=wx.StaticText(self, wx.ID_ANY, 'Messages Received')
receivedLabel.SetForegroundColour('blue')
sentLabel=wx.StaticText(self, wx.ID_ANY, 'Messages Sent')
sentLabel.SetForegroundColour('dark slate blue')
SentMsgList = MessageList(self, size=wx.Size(msg_size,150))
ReceivedMsgList = MessageList(self, size=wx.Size(msg_size,150))

sizer=wx.BoxSizer(wx.VERTICAL)
sizer.Add(sentLabel, 0, wx.EXPAND|wx.ALL, 2)
sizer.Add(SentMsgList, 1, wx.EXPAND|wx.ALL, 2)
sizer.Add(receivedLabel, 0, wx.EXPAND|wx.ALL, 2)
sizer.Add(ReceivedMsgList, 1, wx.EXPAND|wx.ALL, 2)

b = wx.Button(self, wx.ID_ANY, 'Clear messages', name='clear_stale')
self.Bind(wx.EVT_BUTTON, self.OnClearMessages, b)
sizer.Add(b, proportion=0, flag=wx.ALL, border=4)

self.SetSizer(sizer)
self.SentMsgList = SentMsgList
self.ReceivedMsgList = ReceivedMsgList

def Update(self, can_send, can_recv):
self.SentMsgList.Populate(can_send)
self.ReceivedMsgList.Populate(can_recv)

def OnClearMessages(self, event):
self.SentMsgList.DeleteAllItems()
self.ReceivedMsgList.DeleteAllItems()

class MessageList(wx.ListCtrl):
def __init__(self, parent, ID=wx.ID_ANY, pos=wx.DefaultPosition,
size=wx.DefaultSize, style=wx.LC_REPORT|wx.LC_HRULES|wx.LC_VRULES|wx.LC_SORT_ASCENDING):
wx.ListCtrl.__init__(self, parent, ID, pos, size, style)
self.InsertColumn(0, "COB-ID")
self.InsertColumn(1, "Type")
self.InsertColumn(2, "Len")
self.InsertColumn(3, "Data")
self.InsertColumn(4, "Cycle [ms]")
self.SetColumnWidth(0, 60)
self.SetColumnWidth(1, 40)
self.SetColumnWidth(2, 40)
self.SetColumnWidth(3, 200)
self.SetColumnWidth(4, 75)

# either add messages to the listctrl or update the existing ones if
def Populate(self, msg_store):
item=-1
while 1:
item = self.GetNextItem(item, wx.LIST_NEXT_ALL, wx.LIST_STATE_DONTCARE)
if item == -1: break
if self.GetItemText(item) not in msg_store:
self.DeleteItem(item)

for msg_id in msg_store:
item = self.FindItem(-1, msg_id)
msg = msg_store.get(msg_id)
interval = randint(10,1000)
# insert new messages
if item == -1:
item = self.InsertStringItem(sys.maxint, msg_id)
self.SetStringItem(item, 1, 'std')
# fill in other columns
self.SetStringItem(item, 2, '%1d'%msg.LEN)
self.SetStringItem(item, 3, ' '.join(['%02x'%d for d in msg.DATA[:msg.LEN]]))
self.SetStringItem(item, 4, '%d'%interval)
#====================================================================
#====================================================================
if __name__=='__main__':
msg=(0x180, 0, 8, range(1,9))
can_send={}
can_recv={}
# just make up some simple messages for listctrl to display
# send msgs
for a in range(1,7):
this_msg=list(msg)
this_msg[0] += a
can_send[hex(this_msg[0])] = CanMsg(*msg)
# receive msgs
for a in range(1,10):
this_msg=list(msg)
this_msg[0] += 0x100+a
can_recv[hex(this_msg[0])] = CanMsg(*msg)

app=wx.App(0) # 0 arg stops stdout/stderr text box pop-up, messages go to console
frame = EmulatorFrame(None, wx.ID_ANY, 'Listctrl flicker test')
frame.Show(True)
app.MainLoop()

最佳答案

我建议使用 wxPython 的 Freeze 和 Thaw 方法。基本上你卡住小部件,更新它,然后你解冻它。

关于wxPython listctrl 快速更新闪烁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12967703/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com