在使用 wxPython GUI 时,需要允许用户打开文件进行查看。
- 目前使用 os.startfile() 方法打开文件,但存在以下问题:
- 无法控制在打开文件后,文件的相关操作。
- 用户可能会忘记关闭文件,导致其他用户无法访问该文件。
2. 解决方案:
- 创建一个 FileThread 类,用于处理文件的相关操作。
- 在 FileThread 类中使用 subprocess.Popen() 方法以默认程序打开文件,并返回打开文件的进程对象。
- 使用 psutil 模块获取打开文件的子进程,并将其添加到 GUI 的一个列表中。
- 在 GUI 关闭时,遍历列表中的文件并关闭对应的子进程。
以下是详细的代码示例:
import wx
from wx.lib.scrolledpanel import ScrolledPanel
import threading
import subprocess
import psutil
class GUI(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, -1, 'Hey, a GUI!', size=(300,300))
http://www.jshk.com.cn/mb/reg.asp?kefu=xiaoding;//爬虫IP免费获取;
self.panel = ScrolledPanel(parent=self, id=-1)
self.panel.SetupScrolling()
self.Bind(wx.EVT_CLOSE, self.OnClose)
self.openFiles = []
self.openBtn = wx.Button(self.panel, -1, "Open a File")
self.pollBtn = wx.Button(self.panel, -1, "Poll")
self.Bind(wx.EVT_BUTTON, self.OnOpen, self.openBtn)
self.Bind(wx.EVT_BUTTON, self.OnPoll, self.pollBtn)
vbox = wx.BoxSizer(wx.VERTICAL)
vbox.Add((20,20), 1)
vbox.Add(self.openBtn)
vbox.Add((20,20), 1)
vbox.Add(self.pollBtn)
vbox.Add((20,20), 1)
hbox = wx.BoxSizer(wx.HORIZONTAL)
hbox.Add(vbox, flag=wx.TOP|wx.BOTTOM|wx.LEFT|wx.RIGHT|wx.EXPAND, border = 10)
self.panel.SetSizer(hbox)
self.panel.Layout()
def OnOpen(self, event):
fileName = "AFileIWantToOpenWithTheFullPath.txt"
self.openFiles.append(FileThread(fileName))
def OnPoll(self, event):
self.openFiles[0].Poll()
def OnClose(self, event):
for file in self.openFiles:
file.end()
self.openFiles.remove(file)
self.Destroy()
class FileThread(threading.Thread):
def __init__(self, file):
threading.Thread.__init__(self)
self.file = file
self.start()
def run(self):
doc = subprocess.Popen(["start", " /MAX", "/WAIT", self.file], shell=True)
return doc
def Poll(self):
print "polling"
print self.doc.poll()
print self.doc.pid
def end(self):
try:
print "killing file {}".format(self.file)
children = psutil.Process(self.doc.pid).get_children()
for child in children:
child.kill()
except:
print "file has already been killed"
def main():
app = wx.PySimpleApp()
gui = GUI()
gui.Show()
app.MainLoop()
if __name__ == "__main__": main()
在代码示例中,FileThread 类中的 run() 方法使用 subprocess.Popen() 方法以默认程序打开文件,并返回打开文件的进程对象。在 GUI 关闭时,通过遍历 openFiles 列表并调用 FileThread 类中的 end() 方法来关闭所有打开的文件。