在 GUI 中读取文件而不阻塞主线程
Reading a File without block main thead in GUI
在我的 中,我尝试过、失败过、学习过,并通过以下尝试回来了。
我有一个文本文件,其中的名称用逗号解析,如下所示:
Ann Marie,Smith,ams@companyname.com
列表中可能有 100 多个名字。我省略了生成所有其他 GUI 组件的代码,以专注于加载组合框和项目。
我试图在不阻塞主线程的情况下读取文本并将数据加载到组合框中。我查阅了一本教科书和Pythons文档,这是我想出的。
问题:
在我的 def read_employees(self,read_file):
中,我 return 我读取了 list
的数据。我知道 list
不是线程安全的,我在这里使用它的方式可以吗?
def textfilemanage(self):
中组合框的设置也是如此,我通过 self.combo = wx.ComboBox(self.panel, choices=data)
在该方法中设置了组合框。可以吗?
import wx
import concurrent.futures
class Mywin(wx.Frame):
def __init__(self, parent, title):
super(Mywin, self).__init__(parent, title=title, size=(300, 200))
self.panel = wx.Panel(self)
box = wx.BoxSizer(wx.VERTICAL)
self.textfilemanage()
self.label = wx.StaticText(self.panel, label="Your choice:", style=wx.ALIGN_CENTRE)
box.Add(self.label, 0, wx.EXPAND | wx.ALIGN_CENTER_HORIZONTAL | wx.ALL, 20)
cblbl = wx.StaticText(self.panel, label="Combo box", style=wx.ALIGN_CENTRE)
box.Add(cblbl, 0, wx.EXPAND | wx.ALIGN_CENTER_HORIZONTAL | wx.ALL, 5)
box.Add(self.combo, 1, wx.EXPAND | wx.ALIGN_CENTER_HORIZONTAL | wx.ALL, 5)
chlbl = wx.StaticText(self.panel, label="Choice control", style=wx.ALIGN_CENTRE)
box.AddStretchSpacer()
self.combo.Bind(wx.EVT_COMBOBOX, self.OnCombo)
self.panel.SetSizer(box)
self.Centre()
self.Show()
def read_employees(self,read_file):
emp_list = []
with open(read_file) as f_obj:
for line in f_obj:
emp_list.append(line)
return emp_list
def textfilemanage(self):
filename = 'employees.txt'
with concurrent.futures.ThreadPoolExecutor(max_workers=2) as executor:
future_to_read = {executor.submit(self.read_employees, filename)}
for future in concurrent.futures.as_completed(future_to_read):
data = future.result()
self.combo = wx.ComboBox(self.panel, choices=data)
def OnCombo(self, event):
self.label.SetLabel("You selected" + self.combo.GetValue() + " from Combobox")
app = wx.App()
Mywin(None, 'ComboBox and Choice demo')
app.MainLoop()
textfilemanage()
中的 for
循环会一直等到线程完成,因此不同的线程在代码中是无用的。
改为:
在 __init__
中创建空组合框(布局需要)并将其分配给 self.combo
在 textfilemanage()
中启动线程但不要等待它。
在 read_employees()
中将最后的 return
语句替换为
wx.CallAfter(self.combo.Append, emp_list)
或
wx.CallAfter(self.combo.AppendItems, emp_list)
(这取决于接受哪个变体的wxPython版本)
在我的
我有一个文本文件,其中的名称用逗号解析,如下所示:
Ann Marie,Smith,ams@companyname.com
列表中可能有 100 多个名字。我省略了生成所有其他 GUI 组件的代码,以专注于加载组合框和项目。
我试图在不阻塞主线程的情况下读取文本并将数据加载到组合框中。我查阅了一本教科书和Pythons文档,这是我想出的。
问题:
在我的 def read_employees(self,read_file):
中,我 return 我读取了 list
的数据。我知道 list
不是线程安全的,我在这里使用它的方式可以吗?
def textfilemanage(self):
中组合框的设置也是如此,我通过 self.combo = wx.ComboBox(self.panel, choices=data)
在该方法中设置了组合框。可以吗?
import wx
import concurrent.futures
class Mywin(wx.Frame):
def __init__(self, parent, title):
super(Mywin, self).__init__(parent, title=title, size=(300, 200))
self.panel = wx.Panel(self)
box = wx.BoxSizer(wx.VERTICAL)
self.textfilemanage()
self.label = wx.StaticText(self.panel, label="Your choice:", style=wx.ALIGN_CENTRE)
box.Add(self.label, 0, wx.EXPAND | wx.ALIGN_CENTER_HORIZONTAL | wx.ALL, 20)
cblbl = wx.StaticText(self.panel, label="Combo box", style=wx.ALIGN_CENTRE)
box.Add(cblbl, 0, wx.EXPAND | wx.ALIGN_CENTER_HORIZONTAL | wx.ALL, 5)
box.Add(self.combo, 1, wx.EXPAND | wx.ALIGN_CENTER_HORIZONTAL | wx.ALL, 5)
chlbl = wx.StaticText(self.panel, label="Choice control", style=wx.ALIGN_CENTRE)
box.AddStretchSpacer()
self.combo.Bind(wx.EVT_COMBOBOX, self.OnCombo)
self.panel.SetSizer(box)
self.Centre()
self.Show()
def read_employees(self,read_file):
emp_list = []
with open(read_file) as f_obj:
for line in f_obj:
emp_list.append(line)
return emp_list
def textfilemanage(self):
filename = 'employees.txt'
with concurrent.futures.ThreadPoolExecutor(max_workers=2) as executor:
future_to_read = {executor.submit(self.read_employees, filename)}
for future in concurrent.futures.as_completed(future_to_read):
data = future.result()
self.combo = wx.ComboBox(self.panel, choices=data)
def OnCombo(self, event):
self.label.SetLabel("You selected" + self.combo.GetValue() + " from Combobox")
app = wx.App()
Mywin(None, 'ComboBox and Choice demo')
app.MainLoop()
textfilemanage()
中的 for
循环会一直等到线程完成,因此不同的线程在代码中是无用的。
改为:
在 __init__
中创建空组合框(布局需要)并将其分配给 self.combo
在 textfilemanage()
中启动线程但不要等待它。
在 read_employees()
中将最后的 return
语句替换为
wx.CallAfter(self.combo.Append, emp_list)
或
wx.CallAfter(self.combo.AppendItems, emp_list)
(这取决于接受哪个变体的wxPython版本)