更好地理解 tkinter-Python 中的 combox - 如何在 tkinter 中获取选定的值

问题描述

我正在尝试学习 Python,但我一直在努力理解以下问题:

我的目标是收集用户在组合框中选择的值。就在下面,我把我正在组装的程序的一个片段放在一起。然而,一个疑问出现了: 在PageOne Class-selected函数中,为什么代码“list_1.append(var.get())”有效而代码“list_1=(var.get())”无效???

另外,在这部分代码中,对list_1变量的任何操作也不可用,指出错误:UnboundLocalError: local variable 'list_1' referenced before assignment.

你能帮我更好地理解这个问题吗?

from tkinter import *
from tkinter import ttk

list_1 = []

class Validation_Tool(Tk):

    def __init__(self,*args,**kwargs):
        Tk.__init__(self,**kwargs)
        container = Frame(self)
        container.pack(side="top",fill="both",expand=True)
        container.grid_rowconfigure(0,weight=1)
        container.grid_columnconfigure(0,weight=1)
        self.frames = {}

        for F in (PageOne,PageTwo):
            page_name = F.__name__
            frame = F(parent=container,controller=self)
            self.frames[page_name] = frame

            frame.grid(row=0,column=0,sticky="nsew")

        self.show_frame("PageOne")

    def show_frame(self,page_name):
        frame = self.frames[page_name]
        frame.tkraise()

    def quit(self):
        self.destroy()

class PageOne(Frame):

        # ComboBox event handler. ADDED
    def selected(self,event,var):
        # list_1=(var.get())        # DOES NOT WORK !!!!!!!!!!!!!!!!!
        list_1.append(var.get())    # IT WORKS!!!!!!!!!!!!

    def button(self,list_1):
        print(list_1)

    def __init__(self,parent,controller):
        Frame.__init__(self,parent)
        self.controller = controller

        comboBox_var = StringVar()  # ADDED.
        comboBox = ttk.ComboBox(self,values=list('abcde'),textvar=comboBox_var)  # For each ComboBox. ADDED.
        comboBox.grid(row=1,column=0)
        comboBox.bind('<<ComboBoxSelected>>',# Bind event handler.           ADDED.
                        lambda event,var=comboBox_var: self.selected(event,var))  # ADDED.

        quit_button = Button(self,text="Quit Program",command=lambda: controller.quit())
        next_button = Button(self,text='Show options',command= lambda: self.button(list_1))

        quit_button.place(relx=0.98,rely=0.98,anchor=SE)
        next_button.place(relx=0.76,anchor=SE)

class PageTwo(Frame):

    def __init__(self,parent)
        self.controller = controller


if __name__ == "__main__":
    root = Validation_Tool()
    root.geometry('400x300+430+250')
    root.title("Validation Tool")
    root.mainloop()

解决方法

我想我修好了:

from tkinter import ttk
import tkinter as tk


list_1 = None

class Validation_Tool(tk.Tk):
    def __init__(self,*args,**kwargs):
        super().__init__(*args,**kwargs)
        container = tk.Frame(self)
        container.pack(side="top",fill="both",expand=True)
        container.grid_rowconfigure(0,weight=1)
        container.grid_columnconfigure(0,weight=1)
        self.frames = {}

        for FrameClass in (PageOne,PageTwo):
            page_name = FrameClass.__name__
            frame = FrameClass(parent=container,controller=self)
            self.frames.update({page_name: frame})

            frame.grid(row=0,column=0,sticky="news")

        self.show_frame("PageOne")

    def show_frame(self,page_name):
        frame = self.frames[page_name]
        frame.tkraise()

    def quit(self):
        self.destroy()


class PageOne(tk.Frame):
    def __init__(self,parent,controller):
        super().__init__(parent)
        self.controller = controller

        self.combobox_var = tk.StringVar()
        self.combobox = ttk.Combobox(self,values=list("abcde"),textvar=self.combobox_var)
        self.combobox.grid(row=1,column=0)
        self.combobox.bind("<<ComboboxSelected>>",self.selected)

        quit_button = tk.Button(self,text="Quit Program",command=self.controller.quit)
        next_button = tk.Button(self,text="Show options",command=self.button)

        quit_button.place(relx=0.98,rely=0.98,anchor="se")
        next_button.place(relx=0.76,anchor="se")

    def selected(self,event):
        # `list_1` need to be global as we are assigning a value to it
        global list_1
        list_1 = self.combobox_var.get()

    def button(self):
        print(list_1)


class PageTwo(tk.Frame):
    def __init__(self,controller):
        super().__init__(parent)
        self.controller = controller


if __name__ == "__main__":
    root = Validation_Tool()
    root.geometry("400x300+430+250")
    root.title("Validation Tool")
    root.mainloop()

我所要做的就是将绑定更改为:

self.combobox.bind("<<ComboboxSelected>>",self.selected)

和方法:

def selected(self,event):
    # `list_1` need to be global as we are assigning a value to it
    global list_1
    list_1 = self.combobox_var.get()

如果你想给一个全局对象赋值,你需要通过使用 global list_1 来告诉 python 把这个对象当作一个全局变量。我还让你的代码更加 Pythonic。