Reading a File without block main thead in GUI

一世执手 提交于 2019-12-02 16:57:35

问题


In my first attempt, I tried, failed, learned, and came back with the following attempt.

I have a text file with the names parsed with commas that looks like this:

Ann Marie,Smith,ams@companyname.com

The list could have over 100+ names in it. I left out the code that generates all the other GUI components to focus on loading the combobox and the items.

I'm trying to read a text and load the data into a combobox without blocking the main thread. I consulted a textbook and Pythons documentation, and this is what I came up with.

Question:

In my def read_employees(self,read_file): I return a list of the data I read. I'm aware that list isn't thread-safe, is it okay in the way i used it here?

Same goes for the setting of the combobox in def textfilemanage(self): I set the combobox in that method by doing, self.combo = wx.ComboBox(self.panel, choices=data). Is that okay?

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()

回答1:


The for-loop in textfilemanage() waits until the thread finishes so the different thread is useless in the code.

Instead:

Create the empty combobox in __init__ (needed for layouting) and assign it to self.combo

In textfilemanage() start the thread but don't wait for it.

In read_employees() replace the final return statement by

wx.CallAfter(self.combo.Append, emp_list)

or

wx.CallAfter(self.combo.AppendItems, emp_list)

(it depends on the wxPython version which variant is accepted)



来源:https://stackoverflow.com/questions/47186213/reading-a-file-without-block-main-thead-in-gui

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!