如何从wxPython文件打开对话框中提取路径变量到函数外部
解决方案
核心原因:wx.EVT_BUTTON的回调函数是事件触发时异步执行的,函数内部的局部变量默认无法直接被外部作用域访问,你可以通过以下3种常见方案实现路径传递,适配你2个按钮取2个路径的需求:
方案1:使用全局变量(适合小型单文件脚本,实现最简单)
先在外部定义全局变量存储路径,回调函数内用global关键字声明后赋值即可:
import wx # 全局变量存储两个文件路径 emg_path = "" other_path = "" # 第二个按钮对应的路径变量 app = wx.App() root_frame = wx.Frame(None, title="文件选择示例") panel = wx.Panel(root_frame) # 按钮定义示例 e1 = wx.Button(panel, label="选择EMG文件", pos=(20,20)) e2 = wx.Button(panel, label="选择第二个文件", pos=(20,60)) root_frame.Show() def onclk1(event): global emg_path with wx.FileDialog(panel, "OPEN EMG FILE", wildcard="TXT Files(*.txt)|*.txt", style=wx.FD_OPEN | wx.FD_FILE_MUST_EXIST) as EmgFile: if EmgFile.ShowModal() == wx.ID_CANCEL: return emg_path = EmgFile.GetPath() # 赋值后可直接在外部逻辑中调用emg_path取值 def onclk2(event): global other_path with wx.FileDialog(panel, "OPEN OTHER FILE", wildcard="TXT Files(*.txt)|*.txt", style=wx.FD_OPEN | wx.FD_FILE_MUST_EXIST) as OtherFile: if OtherFile.ShowModal() == wx.ID_CANCEL: return other_path = OtherFile.GetPath() e1.Bind(wx.EVT_BUTTON, onclk1) e2.Bind(wx.EVT_BUTTON, onclk2) app.MainLoop()
注意:你原来代码中回调返回的"cancelled"没有实际作用,wx事件系统不会处理回调函数的返回值,不需要添加
方案2:使用类属性存储(更推荐,适合正规wxPython项目,无全局变量污染)
wxPython开发通常会把界面逻辑封装在类中,直接用类的实例属性存储路径即可:
import wx class MyFrame(wx.Frame): def __init__(self): super().__init__(None, title="文件选择示例") panel = wx.Panel(self) # 实例属性存储两个路径 self.emg_path = "" self.other_path = "" self.e1 = wx.Button(panel, label="选择EMG文件", pos=(20, 20)) self.e2 = wx.Button(panel, label="选择第二个文件", pos=(20, 60)) self.e1.Bind(wx.EVT_BUTTON, self.onclk1) self.e2.Bind(wx.EVT_BUTTON, self.onclk2) self.Show() def onclk1(self, event): with wx.FileDialog(self, "OPEN EMG FILE", wildcard="TXT Files(*.txt)|*.txt", style=wx.FD_OPEN | wx.FD_FILE_MUST_EXIST) as EmgFile: if EmgFile.ShowModal() == wx.ID_CANCEL: return self.emg_path = EmgFile.GetPath() # 类内部任意位置都可以直接调用self.emg_path取值 def onclk2(self, event): with wx.FileDialog(self, "OPEN OTHER FILE", wildcard="TXT Files(*.txt)|*.txt", style=wx.FD_OPEN | wx.FD_FILE_MUST_EXIST) as OtherFile: if OtherFile.ShowModal() == wx.ID_CANCEL: return self.other_path = OtherFile.GetPath() if __name__ == "__main__": app = wx.App() frame = MyFrame() app.MainLoop()
方案3:使用可变容器存储(不用global也不用类的过渡方案)
Python中列表、字典这类可变对象可以在内部函数中直接修改,不需要global声明:
# 外部定义列表存储路径,索引0存EMG路径,索引1存第二个路径 path_list = ["", ""] def onclk1(event): with wx.FileDialog(panel, "OPEN EMG FILE", wildcard="TXT Files(*.txt)|*.txt", style=wx.FD_OPEN | wx.FD_FILE_MUST_EXIST) as EmgFile: if EmgFile.ShowModal() == wx.ID_CANCEL: return path_list[0] = EmgFile.GetPath()
内容的提问来源于stack exchange,提问作者Rams
相关产品推荐
相关产品推荐

