等级:初学者
我使用的是python v2.7和wxPython v3.0,操作系统是Windows 7。
我的GUI应用程序:在我的GUI应用程序中,我正在从服务器读取一些值,然后根据这些值的数量,我在GUI中创建面板。然后,这些面板中的每一个都将以staticText
的形式表示值。例如:如果我从服务器收到 1,2,3 值,那么我创建 3 面板,每个面板显示 1 , 2 和 3 。这个工作正常,直到这里。
问题:我想每隔5秒检查一次服务器以获取值并相应地更新我的GUI即。我必须更新面板上的staticText
以显示更新的值。我不想添加新面板,我只想更新旧面板中的值。
例如:如果我检查服务器以及服务器是否返回 1 , 2 , 3 为然后我想创建 3 面板,分别显示 1 , 2 , 3 值。然后在我再次检查服务器5秒后,如果服务器提供 4 , 5 , 6 作为值,那么我只想更新这些值在旧面板上。这意味着现在面板将显示 4 , 5 , 6 而不是 1 , 2 , 3 。我读了一些教程& SC关于使用线程的帖子,我也理解了一些基本事实。不幸的是,我不明白如何将这个概念应用于我的问题。 如果我可以为我的这个特定问题找到一个有效的例子,那将是非常好的,这样我就可以将它应用到我的应用程序的其余部分。
代码:我为此特定问题创建了一个简短的示例代码。 getLabels()
中的class labelsA
和类getLabels()
中的labelsB
通过生成一些随机值并将其返回到列表中来模仿服务器。然后getLabels()
的{{1}}返回的值列表以及class labelA
的{{1}}返回的值列表由getLabels()
和{{1}使用分别创建面板并显示这些值。白色背景中的面板为class labelsB
,黄色背景的面板为createPanels()A
。如果有人可以教我如何使用线程来更新这两个面板的值而不冻结/阻止我的GUI,那将是非常好的。
下载:示例代码如下所示,也可以是downloaded from here,以避免出现身份问题。
createPanelsB()
非常感谢你的时间。任何帮助将不胜感激。
答案 0 :(得分:1)
以下是创建一个每5秒从某个地方获取信息的线程的演示,还展示了如何根据需要创建StaticTexts,以及如何更新它们。
#!/usr/bin/env python
from random import randrange
import wx
import wx.lib.scrolledpanel
import time
import threading
from wx.lib.pubsub import setupkwargs
from wx.lib.pubsub import pub
class GUI(wx.Frame):
def __init__(self, parent, id, title):
screenWidth = 800
screenHeight = 450
screenSize = (screenWidth, screenHeight)
wx.Frame.__init__(self, None, id, title, size=screenSize)
self.locationFont = locationFont = wx.Font(15, wx.MODERN, wx.NORMAL, wx.BOLD)
mainSizer = wx.BoxSizer(wx.VERTICAL)
self.sizer = sizer = wx.BoxSizer(wx.VERTICAL)
self.panel = panel = wx.lib.scrolledpanel.ScrolledPanel(self, -1, style=wx.SIMPLE_BORDER)
panel.SetupScrolling()
panel.SetBackgroundColour('#FFFFFF')
panel.SetSizer(sizer)
mainSizer.Add(panel, 15, wx.EXPAND|wx.ALL)
self.SetSizer(mainSizer)
self.text_labels = [] # Stores the labels where server data is displayed
pub.subscribe(self.OnNewLabels, "NEW_LABELS")
def OnNewLabels(self, labels):
locations = labels
print locations
if len(self.text_labels) < len(labels):
new_labels_needed = len(labels) - len(self.text_labels)
label = "(no data)"
for i in range(new_labels_needed):
sPanels = wx.Panel(self.panel)
text = wx.StaticText(sPanels, -1, label)
text.SetFont(self.locationFont)
text.SetForegroundColour('#0101DF')
self.sizer.Add(sPanels, 0, wx.ALL, 5)
self.sizer.Add(wx.StaticLine(self.panel), 0, wx.ALL|wx.EXPAND, 0)
self.text_labels.append(text)
self.sizer.Layout()
k = 0
for label in locations:
self.text_labels[k].SetLabel(str(label))
k=k+1
###############################
#
#
def InterfaceThread():
while True:
# get the info from the server
mylist =[]
i = randrange(10)
for k in range(1,i+1):
mylist.append(randrange(10))
# Tell the GUI about them
wx.CallAfter(pub.sendMessage, "NEW_LABELS", labels = mylist)
time.sleep(5)
class ServerInterface():
def __init__(self):
interface_thread = threading.Thread(target = InterfaceThread, args = ())
interface_thread.start()
#############
#
if __name__=='__main__':
app = wx.App()
frame = GUI(parent=None, id=-1, title="Test")
frame.Show()
server_interface = ServerInterface()
app.MainLoop()
答案 1 :(得分:1)
为了记录,我知道很久以前这个问题得到了解答,用简单的wx.Timer可以达到同样的效果。
使用上面提供的代码:
3