tkinter: 如何在不同Frame中通过按钮获取另一Frame内ComboBox的选中值
问题核心原因
你当前代码的报错是因为没有处理跨组件的实例引用传递:ButtonFrame的on_go_pressed方法里直接访问InputFrame类的属性,而你实际需要读取的是App窗口中已经实例化的input_frame对象内的product_type变量,混淆了类属性和实例属性导致无法正常取值。
修复步骤
- 修改App类,将实例化后的
input_frame存为自身的实例属性,创建ButtonFrame时把input_frame的引用作为参数传入 - 调整
ButtonFrame的初始化方法,接收传入的input_frame引用并存储为自身属性 - 修改
on_go_pressed方法,从存储的input_frame实例中读取选中的产品类型 - 补充优化:路径字符串中的反斜杠需要转义,建议使用原始字符串避免路径解析错误;同时修复了原代码中布局配置错误、窗口高度不足的问题
完整修复后代码
import tkinter as tk from tkinter import ttk from tkinter import filedialog as fd def select_files(prod_type): # 路径用原始字符串避免转义问题 path = fr"\\10.10.3.7\Production\Test_Folder\{prod_type}" filetypes = ( ('PDF Files', '*.pdf'), ) filenames = fd.askopenfilenames( title='打开文件', initialdir=path, filetypes=filetypes) for file in filenames: print(file) class InputFrame(ttk.Frame): def __init__(self, parent): super().__init__(parent) # 修复原代码列配置错误 self.columnconfigure(0, weight=1) self.columnconfigure(1, weight=3) self.__create_widgets() def __create_widgets(self): # 产品类型 ttk.Label(self, text='产品类型:').grid(column=0, row=0, sticky=tk.W) self.product_type = tk.StringVar() self.product_combo = ttk.Combobox(self, width=30, textvariable=self.product_type) self.product_combo['values'] = ('记事本', '平面便签卡', '折叠便签卡', '日记本') self.product_combo.set('记事本') self.product_combo['state'] = 'readonly' self.product_combo.grid(column=1, row=0, sticky=tk.W) # 算法 ttk.Label(self, text='算法:').grid(column=0, row=1, sticky=tk.W) self.algo_var = tk.StringVar() algo_combo = ttk.Combobox(self, width=30, textvariable=self.algo_var) algo_combo['values'] = ('panel', 'fuzzy') algo_combo.set('panel') algo_combo.grid(column=1, row=1, sticky=tk.W) # 方向 ttk.Label(self, text='方向:').grid(column=0, row=2, sticky=tk.W) self.orientation_var = tk.StringVar() orientation_combo = ttk.Combobox(self, width=30, textvariable=self.orientation_var) orientation_combo['values'] = ('自动', '纵向', '横向') orientation_combo.set('自动') orientation_combo.grid(column=1, row=2, sticky=tk.W) # 边距 ttk.Label(self, text='边距:').grid(column=0, row=3, sticky=tk.W) self.margin = ttk.Entry(self, width=30) self.margin.grid(column=1, row=3, sticky=tk.W) # 间距 ttk.Label(self, text='间距:').grid(column=0, row=4, sticky=tk.W) self.gap = ttk.Entry(self, width=30) self.gap.grid(column=1, row=4, sticky=tk.W) # 重复次数 ttk.Label(self, text='重复次数:').grid(column=0, row=5, sticky=tk.W) self.repeat_number = tk.StringVar() repeat = ttk.Spinbox(self, from_=1, to=10, width=30, textvariable=self.repeat_number) repeat.set(1) repeat.grid(column=1, row=5, sticky=tk.W) for widget in self.winfo_children(): widget.grid(padx=0, pady=5) class ButtonFrame(ttk.Frame): def __init__(self, parent, input_frame): super().__init__(parent) # 存储传入的input_frame引用 self.input_frame = input_frame self.columnconfigure(0, weight=1) self.__create_widgets() def __create_widgets(self): ttk.Button(self, text='选择文件', command=self.on_go_pressed).grid(column=0, row=0) ttk.Button(self, text='生成PDF').grid(column=0, row=1) for widget in self.winfo_children(): widget.grid(padx=0, pady=3) def on_go_pressed(self): # 从input_frame实例中获取选中值 select_files(self.input_frame.product_type.get()) class App(tk.Tk): def __init__(self): super().__init__() self.title("PDF拼接工具") self.eval('tk::PlaceWindow . center') # 调整窗口高度适配所有控件 self.geometry('400x360') self.resizable(0, 0) self.attributes('-toolwindow', True) self.columnconfigure(0, weight=4) self.columnconfigure(1, weight=1) self.__create_widgets() def __create_widgets(self): # 将input_frame存为实例属性 self.input_frame = InputFrame(self) self.input_frame.grid(column=0, row=0, padx=10, pady=10) # 传入input_frame引用创建按钮框架 self.button_frame = ButtonFrame(self, self.input_frame) self.button_frame.grid(column=1, row=0, padx=10, pady=10) if __name__ == '__main__': app = App() app.mainloop()
内容的提问来源于stack exchange,提问作者Jason G
相关产品推荐
相关产品推荐

