tkinter:如何在一个框架中使用不同框架中的按钮从 ComboBox 获取价值
tkinter: How to get value from ComboBox in one frame with button in different frame
目标是允许用户从组合框下拉列表中 select,然后单击 Select 文件按钮。该按钮将获取产品类型(组合框中的值),并将根据组合框中的选择打开正确的目录。问题是,我似乎无法获得此值,因为按钮和组合框位于不同的框架中。我觉得我在这里缺少一些基本的东西。
import tkinter as tk
from tkinter import ttk
from tkinter import filedialog as fd
def select_files(prod_type):
path = f"\\10.10.3.7\Production\Test_Folder\{prod_type}"
filetypes = (
('PDF Files', '*.pdf'),
)
filenames = fd.askopenfilenames(
title='Open files',
initialdir=path,
filetypes=filetypes)
for file in filenames:
print(file)
class InputFrame(ttk.Frame):
def __init__(self, parent):
super().__init__(parent)
# setup the grid layout manager
self.columnconfigure(0, weight=1)
self.columnconfigure(0, weight=3)
self.__create_widgets()
def __create_widgets(self):
# Product
ttk.Label(self, text='Product:').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'] = ('Notepad', 'Flat Notecard', 'Folded Notecard', 'Journal')
self.product_combo.set('Notepad')
self.product_combo['state'] = 'readonly'
self.product_combo.grid(column=1, row=0, sticky=tk.W)
# Algorithm:
ttk.Label(self, text='Algorithm:').grid(column=0, row=1, sticky=tk.W)
algo_var = tk.StringVar()
algo_combo = ttk.Combobox(self, width=30)
algo_combo['values'] = ('panel', 'fuzzy')
algo_combo.set('panel')
algo_combo.grid(column=1, row=1, sticky=tk.W)
# Orientation:
ttk.Label(self, text='Orientation:').grid(column=0, row=2, sticky=tk.W)
orientation_var = tk.StringVar()
orientation_combo = ttk.Combobox(self, width=30, textvariable=orientation_var)
orientation_combo['values'] = ('auto', 'portrait', 'landscape')
orientation_combo.set('auto')
orientation_combo.grid(column=1, row=2, sticky=tk.W)
# Margin:
ttk.Label(self, text='Margin:').grid(column=0, row=3, sticky=tk.W)
margin = ttk.Entry(self, width=30)
margin.grid(column=1, row=3, sticky=tk.W)
# Gap:
ttk.Label(self, text='Gap:').grid(column=0, row=4, sticky=tk.W)
gap = ttk.Entry(self, width=30)
gap.grid(column=1, row=4, sticky=tk.W)
# Repeat:
ttk.Label(self, text='Repeat:').grid(column=0, row=5, sticky=tk.W)
repeat_number = tk.StringVar()
repeat = ttk.Spinbox(self, from_=1, to=10, width=30, textvariable=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):
super().__init__(parent)
# setup the grid layout manager
self.columnconfigure(0, weight=1)
self.__create_widgets()
def __create_widgets(self):
ttk.Button(self, text='Select Files', command=self.on_go_pressed).grid(column=0, row=0)
ttk.Button(self, text='Generate PDF').grid(column=0, row=1)
for widget in self.winfo_children():
widget.grid(padx=0, pady=3)
def on_go_pressed(self):
select_files(InputFrame.product_type.get())
class App(tk.Tk):
def __init__(self):
super().__init__()
self.title("PDF n-up")
self.eval('tk::PlaceWindow . center')
self.geometry('400x200')
self.resizable(0, 0)
self.attributes('-toolwindow', True)
# layout on the root window
self.columnconfigure(0, weight=4)
self.columnconfigure(1, weight=1)
self.__create_widgets()
def __create_widgets(self):
# create the input frame
input_frame = InputFrame(self)
input_frame.grid(column=0, row=0)
# create the button frame
button_frame = ButtonFrame(self)
button_frame.grid(column=1, row=0)
if __name__ == '__main__':
app = App()
app.mainloop()
您可以在创建产品类型变量时将其传递给 ButtonFrame
,因为您在创建 InputFrame
之后创建了 ButtonFrame
。这是代码,相应地标记了更改和添加的行:
import tkinter as tk
from tkinter import ttk
from tkinter import filedialog as fd
def select_files(prod_type):
path = f"/home/sam/Pictures/Test/{prod_type}"
filetypes = (
('PDF Files', '*.pdf'),
)
filenames = fd.askopenfilenames(
title='Open files',
initialdir=path,
filetypes=filetypes)
for file in filenames:
print(file)
class InputFrame(ttk.Frame):
def __init__(self, parent):
super().__init__(parent)
# setup the grid layout manager
self.columnconfigure(0, weight=1)
self.columnconfigure(0, weight=3)
self.__create_widgets()
def __create_widgets(self):
# Product
ttk.Label(self, text='Product:').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'] = ('Notepad', 'Flat Notecard', 'Folded Notecard', 'Journal')
self.product_combo.set('Notepad')
self.product_combo['state'] = 'readonly'
self.product_combo.grid(column=1, row=0, sticky=tk.W)
# Algorithm:
ttk.Label(self, text='Algorithm:').grid(column=0, row=1, sticky=tk.W)
algo_var = tk.StringVar()
algo_combo = ttk.Combobox(self, width=30)
algo_combo['values'] = ('panel', 'fuzzy')
algo_combo.set('panel')
algo_combo.grid(column=1, row=1, sticky=tk.W)
# Orientation:
ttk.Label(self, text='Orientation:').grid(column=0, row=2, sticky=tk.W)
orientation_var = tk.StringVar()
orientation_combo = ttk.Combobox(self, width=30, textvariable=orientation_var)
orientation_combo['values'] = ('auto', 'portrait', 'landscape')
orientation_combo.set('auto')
orientation_combo.grid(column=1, row=2, sticky=tk.W)
# Margin:
ttk.Label(self, text='Margin:').grid(column=0, row=3, sticky=tk.W)
margin = ttk.Entry(self, width=30)
margin.grid(column=1, row=3, sticky=tk.W)
# Gap:
ttk.Label(self, text='Gap:').grid(column=0, row=4, sticky=tk.W)
gap = ttk.Entry(self, width=30)
gap.grid(column=1, row=4, sticky=tk.W)
# Repeat:
ttk.Label(self, text='Repeat:').grid(column=0, row=5, sticky=tk.W)
repeat_number = tk.StringVar()
repeat = ttk.Spinbox(self, from_=1, to=10, width=30, textvariable=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, product_type): ### EDITED THIS LINE
super().__init__(parent)
# setup the grid layout manager
self.columnconfigure(0, weight=1)
self.product_type = product_type ### ADDED THIS LINE
self.__create_widgets()
def __create_widgets(self):
ttk.Button(self, text='Select Files', command=self.on_go_pressed).grid(column=0, row=0)
ttk.Button(self, text='Generate PDF').grid(column=0, row=1)
for widget in self.winfo_children():
widget.grid(padx=0, pady=3)
def on_go_pressed(self):
select_files(self.product_type.get()) ### EDITED THIS LINE
class App(tk.Tk):
def __init__(self):
super().__init__()
self.title("PDF n-up")
self.eval('tk::PlaceWindow . center')
self.geometry('400x200')
self.resizable(0, 0)
# self.attributes('-toolwindow', True)
# layout on the root window
self.columnconfigure(0, weight=4)
self.columnconfigure(1, weight=1)
self.__create_widgets()
def __create_widgets(self):
# create the input frame
input_frame = InputFrame(self)
input_frame.grid(column=0, row=0)
# create the button frame
button_frame = ButtonFrame(self, input_frame.product_type) ### EDITED THIS LINE
button_frame.grid(column=1, row=0)
if __name__ == '__main__':
app = App()
app.mainloop()
请注意在行 button_frame = ButtonFrame(self, input_frame.product_type)
中,我将其作为参数提供 input_frame.product_type
,以便它可以随时访问它。
为此需要对 ButtonFrame
进行更改:我更改了 __init__()
方法,以便它可以接收另一个参数。然后它将 product_type
参数的值分配给一个变量,以便以后可以使用它。当它调用 select_files()
时,它只是使用 self.product_type
.
关于为什么调用select_files(InputFrame.product_type.get())
不起作用:product_type
是一个变量,只有在InputFrame
初始化时才创建。在上面的行中,您引用了 class 本身,而不是 class 的 实例 ,因此它没有被初始化。因此,未定义在 InputFrame.__init__()
中创建的任何内容,因为未调用 __init__()
。
目标是允许用户从组合框下拉列表中 select,然后单击 Select 文件按钮。该按钮将获取产品类型(组合框中的值),并将根据组合框中的选择打开正确的目录。问题是,我似乎无法获得此值,因为按钮和组合框位于不同的框架中。我觉得我在这里缺少一些基本的东西。
import tkinter as tk
from tkinter import ttk
from tkinter import filedialog as fd
def select_files(prod_type):
path = f"\\10.10.3.7\Production\Test_Folder\{prod_type}"
filetypes = (
('PDF Files', '*.pdf'),
)
filenames = fd.askopenfilenames(
title='Open files',
initialdir=path,
filetypes=filetypes)
for file in filenames:
print(file)
class InputFrame(ttk.Frame):
def __init__(self, parent):
super().__init__(parent)
# setup the grid layout manager
self.columnconfigure(0, weight=1)
self.columnconfigure(0, weight=3)
self.__create_widgets()
def __create_widgets(self):
# Product
ttk.Label(self, text='Product:').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'] = ('Notepad', 'Flat Notecard', 'Folded Notecard', 'Journal')
self.product_combo.set('Notepad')
self.product_combo['state'] = 'readonly'
self.product_combo.grid(column=1, row=0, sticky=tk.W)
# Algorithm:
ttk.Label(self, text='Algorithm:').grid(column=0, row=1, sticky=tk.W)
algo_var = tk.StringVar()
algo_combo = ttk.Combobox(self, width=30)
algo_combo['values'] = ('panel', 'fuzzy')
algo_combo.set('panel')
algo_combo.grid(column=1, row=1, sticky=tk.W)
# Orientation:
ttk.Label(self, text='Orientation:').grid(column=0, row=2, sticky=tk.W)
orientation_var = tk.StringVar()
orientation_combo = ttk.Combobox(self, width=30, textvariable=orientation_var)
orientation_combo['values'] = ('auto', 'portrait', 'landscape')
orientation_combo.set('auto')
orientation_combo.grid(column=1, row=2, sticky=tk.W)
# Margin:
ttk.Label(self, text='Margin:').grid(column=0, row=3, sticky=tk.W)
margin = ttk.Entry(self, width=30)
margin.grid(column=1, row=3, sticky=tk.W)
# Gap:
ttk.Label(self, text='Gap:').grid(column=0, row=4, sticky=tk.W)
gap = ttk.Entry(self, width=30)
gap.grid(column=1, row=4, sticky=tk.W)
# Repeat:
ttk.Label(self, text='Repeat:').grid(column=0, row=5, sticky=tk.W)
repeat_number = tk.StringVar()
repeat = ttk.Spinbox(self, from_=1, to=10, width=30, textvariable=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):
super().__init__(parent)
# setup the grid layout manager
self.columnconfigure(0, weight=1)
self.__create_widgets()
def __create_widgets(self):
ttk.Button(self, text='Select Files', command=self.on_go_pressed).grid(column=0, row=0)
ttk.Button(self, text='Generate PDF').grid(column=0, row=1)
for widget in self.winfo_children():
widget.grid(padx=0, pady=3)
def on_go_pressed(self):
select_files(InputFrame.product_type.get())
class App(tk.Tk):
def __init__(self):
super().__init__()
self.title("PDF n-up")
self.eval('tk::PlaceWindow . center')
self.geometry('400x200')
self.resizable(0, 0)
self.attributes('-toolwindow', True)
# layout on the root window
self.columnconfigure(0, weight=4)
self.columnconfigure(1, weight=1)
self.__create_widgets()
def __create_widgets(self):
# create the input frame
input_frame = InputFrame(self)
input_frame.grid(column=0, row=0)
# create the button frame
button_frame = ButtonFrame(self)
button_frame.grid(column=1, row=0)
if __name__ == '__main__':
app = App()
app.mainloop()
您可以在创建产品类型变量时将其传递给 ButtonFrame
,因为您在创建 InputFrame
之后创建了 ButtonFrame
。这是代码,相应地标记了更改和添加的行:
import tkinter as tk
from tkinter import ttk
from tkinter import filedialog as fd
def select_files(prod_type):
path = f"/home/sam/Pictures/Test/{prod_type}"
filetypes = (
('PDF Files', '*.pdf'),
)
filenames = fd.askopenfilenames(
title='Open files',
initialdir=path,
filetypes=filetypes)
for file in filenames:
print(file)
class InputFrame(ttk.Frame):
def __init__(self, parent):
super().__init__(parent)
# setup the grid layout manager
self.columnconfigure(0, weight=1)
self.columnconfigure(0, weight=3)
self.__create_widgets()
def __create_widgets(self):
# Product
ttk.Label(self, text='Product:').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'] = ('Notepad', 'Flat Notecard', 'Folded Notecard', 'Journal')
self.product_combo.set('Notepad')
self.product_combo['state'] = 'readonly'
self.product_combo.grid(column=1, row=0, sticky=tk.W)
# Algorithm:
ttk.Label(self, text='Algorithm:').grid(column=0, row=1, sticky=tk.W)
algo_var = tk.StringVar()
algo_combo = ttk.Combobox(self, width=30)
algo_combo['values'] = ('panel', 'fuzzy')
algo_combo.set('panel')
algo_combo.grid(column=1, row=1, sticky=tk.W)
# Orientation:
ttk.Label(self, text='Orientation:').grid(column=0, row=2, sticky=tk.W)
orientation_var = tk.StringVar()
orientation_combo = ttk.Combobox(self, width=30, textvariable=orientation_var)
orientation_combo['values'] = ('auto', 'portrait', 'landscape')
orientation_combo.set('auto')
orientation_combo.grid(column=1, row=2, sticky=tk.W)
# Margin:
ttk.Label(self, text='Margin:').grid(column=0, row=3, sticky=tk.W)
margin = ttk.Entry(self, width=30)
margin.grid(column=1, row=3, sticky=tk.W)
# Gap:
ttk.Label(self, text='Gap:').grid(column=0, row=4, sticky=tk.W)
gap = ttk.Entry(self, width=30)
gap.grid(column=1, row=4, sticky=tk.W)
# Repeat:
ttk.Label(self, text='Repeat:').grid(column=0, row=5, sticky=tk.W)
repeat_number = tk.StringVar()
repeat = ttk.Spinbox(self, from_=1, to=10, width=30, textvariable=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, product_type): ### EDITED THIS LINE
super().__init__(parent)
# setup the grid layout manager
self.columnconfigure(0, weight=1)
self.product_type = product_type ### ADDED THIS LINE
self.__create_widgets()
def __create_widgets(self):
ttk.Button(self, text='Select Files', command=self.on_go_pressed).grid(column=0, row=0)
ttk.Button(self, text='Generate PDF').grid(column=0, row=1)
for widget in self.winfo_children():
widget.grid(padx=0, pady=3)
def on_go_pressed(self):
select_files(self.product_type.get()) ### EDITED THIS LINE
class App(tk.Tk):
def __init__(self):
super().__init__()
self.title("PDF n-up")
self.eval('tk::PlaceWindow . center')
self.geometry('400x200')
self.resizable(0, 0)
# self.attributes('-toolwindow', True)
# layout on the root window
self.columnconfigure(0, weight=4)
self.columnconfigure(1, weight=1)
self.__create_widgets()
def __create_widgets(self):
# create the input frame
input_frame = InputFrame(self)
input_frame.grid(column=0, row=0)
# create the button frame
button_frame = ButtonFrame(self, input_frame.product_type) ### EDITED THIS LINE
button_frame.grid(column=1, row=0)
if __name__ == '__main__':
app = App()
app.mainloop()
请注意在行 button_frame = ButtonFrame(self, input_frame.product_type)
中,我将其作为参数提供 input_frame.product_type
,以便它可以随时访问它。
为此需要对 ButtonFrame
进行更改:我更改了 __init__()
方法,以便它可以接收另一个参数。然后它将 product_type
参数的值分配给一个变量,以便以后可以使用它。当它调用 select_files()
时,它只是使用 self.product_type
.
关于为什么调用select_files(InputFrame.product_type.get())
不起作用:product_type
是一个变量,只有在InputFrame
初始化时才创建。在上面的行中,您引用了 class 本身,而不是 class 的 实例 ,因此它没有被初始化。因此,未定义在 InputFrame.__init__()
中创建的任何内容,因为未调用 __init__()
。