You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 16:57:02