tkinter 中一个按钮的多个命令

Multiple commands to a button in tkinter

我是大学的停车场入场券。基本上当它是 运行 时会做什么,出现 window,要求用户输入品牌、型号、颜色和注册牌照。然后它将此数据保存到列表、数组或其他任何内容。用户按下按钮将他们的车开进停车场,还可以查看当前停车场中有哪些车。当我按下 admit vehicle 时,我需要将数据保存到这个 list/array/tree,并且还需要一个整型变量减一。这是相关的代码。还有更多,但这是相关位。

# Admit Button
    btn_admit = ttk.Button(bottom_frame)
    btn_admit.config(text='Admit Vehicle')
    btn_admit.bind('<Button-1>', self.admit)  # I need this to reduce the variable as well

...

    def admit(self, event):
        self.useful_msg.set("Vehicle Admitted")  # This is only here to show a message currently it does nothing else

这是 'spaces available' 变量:

self.num_spaces = IntVar(mid_frame)
    self.num_spaces.set = 0
    lbl_num_spaces = Label(mid_frame)
    lbl_num_spaces.config(textvariable=self.num_spaces, bg='yellow')

最后,这是 window 的代码,它显示了停车场中的汽车树(现在有一些示例汽车是硬编码的):

class ShowCarsGui:
def __init__(self, master):
    self.master = master
    self.master.geometry('1200x600+100+100')

    # Frames
    top_frame = tk.Frame(self.master)
    tree_container = tk.Frame(self.master)
    bottom_bar = tk.Frame(self.master)

    # Widgets:

    # Logo
    carpark_icon = tk.PhotoImage(file='car.gif')
    lbl_carpark_icon = tk.Label(top_frame)
    lbl_carpark_icon.config(image=carpark_icon)
    lbl_carpark_icon.image = carpark_icon

    # Header
    lbl_header = tk.Label(top_frame)
    lbl_header.config(text="Vehicles in car park", font='helvetica 32 bold')

    # Tree(ttk)
    self.tree = ttk.Treeview(tree_container)
    self.tree["columns"] = ("Make", "Model", "Colour", "Registration")
    self.tree["height"] = 10
    self.tree["show"] = 'headings'  # Gets rid of default first column
    vsb = ttk.Scrollbar(tree_container)
    vsb.configure(orient='vertical', command=self.tree.yview)
    hsb = ttk.Scrollbar(tree_container)
    hsb.configure(orient='horizontal', command=self.tree.xview)
    self.tree.configure(yscroll=vsb.set, xscroll=hsb.set)
    self.tree_populate()

    # Button
    quit_button = tk.Button(bottom_bar)
    quit_button.config(text='Quit', width=25)
    quit_button.bind('<Button-1>', self.close_window)

    # Positioning frames
    top_frame.grid_rowconfigure(0, minsize=150)  # Make row 150 pixels high
    top_frame.grid(row=0)
    tree_container.grid(row=1)
    bottom_bar.grid(row=2)

    # Top
    lbl_carpark_icon.grid(row=0, column=0, padx=10, sticky='w')
    lbl_header.grid(row=0, column=1, padx=20)

    # Middle
    self.tree.grid(column=0, row=0, sticky='nsew')
    vsb.grid(column=1, row=0, sticky='ns')
    hsb.grid(column=0, row=1, sticky='ew')

    # Bottom
    quit_button.grid(row=0, column=0)

def close_window(self, event):
    self.master.destroy()

def tree_populate(self):
    # Eventually this needs to come from car park object
    tree_columns = ("Make", "Model", "Colour", "Registration")
    tree_data = [
        ("Ford", "Ka", "Blue", "FD54 2WE"),
        ("Vauxhall", "Corsa", "Green", "KJ61 9YH"),
        ("VW", "Polo", "Silver", "AA54 9TQ"),
        ("Nissan", "Qashqai", "Red", "YRE 456W"),
        ("Toyota", "Starlet", "Gold", "J234 WYE"),
    ]

    for col in tree_columns:
        self.tree.heading(col, text=col, anchor='w')
    for country_data in tree_data:
        self.tree.insert("", 0, values=country_data)

最后是整个程序的代码:

import tkinter as tk
from tkinter import *
from tkinter import ttk


class CarParkGui:
    def __init__(self, master):
        self.master = master
        self.master.configure(bg='light cyan')
        self.master.title("Collyer's Car Park")
        self.master.option_add('*Font', 'Georgia 12')  # Font for all             widgets
        self.master.option_add('*Font', 'helvetica 20 bold')
        self.master.option_add('*Background', 'light cyan')  # background of all widgets
        self.master.geometry('1200x500+100+100')  # w,h,x,y (top left corner)
        self.top()  # Build top bar
        self.middle()  # Define middle frame
        self.bottom()  # Define Bottom Frame

    def top(self):
        # Frame for top section
        top_frame = Frame(self.master)

        # Logo
        carpark_icon = PhotoImage(file='car.gif')
        lbl_carpark_icon = Label(top_frame)  # Instance of tkinter label (parent is frame)
        lbl_carpark_icon.config(image=carpark_icon)
        lbl_carpark_icon.image = carpark_icon  # Have to have this as well as previous one

        # Header
        lbl_header = Label(top_frame)
        lbl_header.config(text='Admit Vehicle', font='helvetica 32 bold')

        # Grid positioning for top frame
        top_frame.grid_rowconfigure(0, minsize=150)  # Make row 150 pixels high
        top_frame.grid(row=0)

        # Within Frame
        lbl_carpark_icon.grid(row=0, column=0, padx=10)
        lbl_header.grid(row=0, column=1, padx=20)

    def middle(self):
        # Frame to contain other widgets
        mid_frame = Frame(self.master)

        # Label - Car Make
        lbl_make = Label(mid_frame)
        lbl_make.config(text='Make')  # Presentation

        # Label - Car  Model
        lbl_model = Label(mid_frame)
        lbl_model.config(text='Model')

        # Label - Colour
        lbl_colour = Label(mid_frame)
        lbl_colour.config(text='Colour')

        # Label - Registration
        lbl_reg = Label(mid_frame)
        lbl_reg.config(text='Registration')

        # Label - Spaces
        lbl_spc = Label(mid_frame)
        lbl_spc.config(text='Spaces')

        # Text Entry - Make
        self.make = StringVar(mid_frame)
        txt_make = Entry(mid_frame)
        txt_make.config(textvariable=self.make, width=20)

        # Text Entry - Model
        self.model = StringVar(mid_frame)
        txt_model = Entry(mid_frame)
        txt_model.config(textvariable=self.model, width=20)

        # Text Entry - Colour
        self.colour = StringVar(mid_frame)
        txt_colour = Entry(mid_frame)
        txt_colour.config(textvariable=self.colour, width=20)

        # Text Entry - Registration
        self.reg = StringVar(mid_frame)
        txt_reg = Entry(mid_frame)
        txt_reg.config(textvariable=self.reg, width=20)

        # Label for number of space available (WILL BE UPDATED)
        self.num_spaces = IntVar(mid_frame)
        self.num_spaces.set = 0
        lbl_num_spaces = Label(mid_frame)
        lbl_num_spaces.config(textvariable=self.num_spaces, bg='yellow')

        # Display
        mid_frame.grid_columnconfigure(0, minsize=100)  # Make row 150 pixels high
        mid_frame.grid(row=1, sticky='w')

        # Row 0
        lbl_make.grid(row=1, column=0)
        txt_make.grid(row=1, column=1)
        lbl_spc.grid(row=1, column=2)
        lbl_num_spaces.grid(row=1, column=3, sticky='w')

        # Row 1
        lbl_model.grid(row=2, column=0)
        txt_model.grid(row=2, column=1, padx='10')

        # Row 2
        lbl_colour.grid(row=3, column=0)
        txt_colour.grid(row=3, column=1, padx='10')

        # Row 3
        lbl_reg.grid(row=4, column=0)
        txt_reg.grid(row=4, column=1, padx='10')

    def bottom(self):
        # Frame for bottom section
        bottom_frame = Frame(self.master)

        # Grid reference for bottom frame
        bottom_frame.grid(row=2)

        # Guidance message (WILL BE UPDATED)
        self.useful_msg = StringVar(bottom_frame)
        self.useful_msg.set("Enter your vehicle details")
        self.lbl_msg = Label(bottom_frame)  # Use self so we can change config at
        self.lbl_msg.config(textvariable=self.useful_msg, fg='red', width=20)

        # Admit Button
        btn_admit = ttk.Button(bottom_frame)
        btn_admit.config(text='Admit Vehicle')
        btn_admit.bind('<Button-1>', self.admit)

        # Show Vehicles Button
        btn_show = ttk.Button(bottom_frame)
        btn_show.config(text='Show Vehicles In Car Park')
        btn_show.bind('<Button-1>', self.show)

        # Within bottom_frame
        # row 0
        self.lbl_msg.grid(row=0, column=0)

        # row 1
        btn_admit.grid(row=1, column=0, sticky='e')
        btn_show.grid(row=1, column=1, sticky='e')

    def admit(self, event):
        self.useful_msg.set("Vehicle Admitted")

    def show(self, event):
        self.new_window = Toplevel(self.master)
        self.app = ShowCarsGui(self.new_window)

___ 这就是 ShowCarsGui() ____

的地方
def main():
    root = Tk()
    CarParkGui(root)
    root.mainloop()


main()

要执行 "two things with one button",正确的解决方案是创建一个执行这些操作的函数 "two things",然后将该函数与按钮相关联。

btn_admit = ttk.Button(bottom_frame)
btn.configure(command=self.admit)


def admit(self):
    self.num_spaces.set(self.num_spaces.get()-1)
    self.useful_msg.set("Vehicle Admitted")

注意:上面的示例使用了 command 属性而不是绑定。使用 command 属性是更可取的,因为它具有 built-in 对键盘遍历的支持。当然,在 admit 中,您可以随心所欲地做多做少 -- 您不限于一两件事。