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

TTK按钮绑定同一回调函数,点击仅触发首个分支输出问题

问题:Tkinter按钮点击后无法正确区分触发源

我写了一段Tkinter代码,期望点击不同按钮时打印对应的字符串,但不管点哪个按钮,都只会打印第一个分支的"ok"。把elif改成独立if后情况更糟,求解决方法。

我的代码如下:

ytac=[]

import tkinter as tk
from tkinter import ttk


class App(tk.Tk):
  def __init__(self, title: str):
    super().__init__()
    self.title(title)

    self.style = ttk.Style(self)
    self.style.theme_use("classic") 

    self.frame0 = ttk.Frame(self, padding=(5,5))
    self.frame1 = ttk.Frame(self, padding=(5,5))
    self.frame2 = ttk.Frame(self, padding=(5,5))
    self.frame3 = ttk.Frame(self, padding=(5,5))

    self.initialize_frames()
    self.initialize_widgets()
    self.geometry("450x400")
  

  
  def initialize_widgets(self):
    self.uno_label.grid(row=0, column=0, sticky=tk.NSEW, padx=10, pady=10, columnspan=10)
    
  def make_frame0(self):
    self.coding_button = ttk.Button(self.frame0, text="Coding", command=self.get)
    self.coding_button.grid(row=1, column=5)

  def make_frame1(self):
    self.gamedev_button = ttk.Button(self.frame1, text="Game Development", command=self.get)
    self.gamedev_button.grid(row=1 ,column=5)

  def make_frame2(self):
    self.digitalmedia_button = ttk.Button(self.frame2, text="Digital Media", command=self.get)
    self.digitalmedia_button.grid(row=1, column=5)

  def make_frame3(self):
    self.uno_label = ttk.Label(self, text="Hello fellow Ytacer or so they call 'it. Ytac is a 4 week journey that allows to \ntake a Stem class of your choosing from a not so wide range of classes. \nIt's also unfourtenetly not sponsored by Dr.Pepper(f in the chat). 'Are you ready \nto start your expedition? What's 'my name you 'ask? I have 'no name but you \ncan call me Took. 'And also, Mel 'sucks and 'shouldn't be 'appreciated \nthroughout the rest of the cohort. *ahem*, they're 3 pathways to choose from,\n Coding(1), Game Development(2), Digital Media(3). Choose from one of these \nby clicking on the respective button. But before you do that I would like for us \nto introduce our sponsors RAID SHADOW LEGE-.") 
  

  
  def initialize_frames(self):
    self.make_frame0()
    self.make_frame1()
    self.make_frame2()
    self.make_frame3()

    self.frame0.grid(row=4, column=0)
    self.frame1.grid(row=4, column=1)
    self.frame2.grid(row=4, column=2)

  def get(self):
     if self.coding_button:
       print("ok")
     elif self.gamedev_button:
       print("poyo") 
     elif self.digitalmedia_button:
       print("GUH-HUH")
      

if __name__ == "__main__":
    app = App("YTAC")
    app.mainloop()

问题原因

你的get方法判断逻辑错误:if self.coding_button:是在检查按钮对象是否存在,而不是判断当前点击的是不是这个按钮。三个按钮在初始化后都已存在,所以第一个条件永远为真,每次点击都会执行print("ok");改成独立if后,三个条件都会成立,会依次打印所有内容。

解决方案

方法一:给按钮绑定带参数的回调函数

通过lambda给每个按钮的command传递不同标识,在get方法里根据标识判断执行逻辑:

修改后的核心代码:

def make_frame0(self):
    self.coding_button = ttk.Button(self.frame0, text="Coding", command=lambda: self.get("coding"))
    self.coding_button.grid(row=1, column=5)

def make_frame1(self):
    self.gamedev_button = ttk.Button(self.frame1, text="Game Development", command=lambda: self.get("gamedev"))
    self.gamedev_button.grid(row=1 ,column=5)

def make_frame2(self):
    self.digitalmedia_button = ttk.Button(self.frame2, text="Digital Media", command=lambda: self.get("digitalmedia"))
    self.digitalmedia_button.grid(row=1, column=5)

def get(self, btn_type):
    if btn_type == "coding":
        print("ok")
    elif btn_type == "gamedev":
        print("poyo")
    elif btn_type == "digitalmedia":
        print("GUH-HUH")

方法二:通过事件对象获取触发源

让get方法接收事件参数,直接判断触发点击的控件是哪个按钮:

修改后的核心代码:

def make_frame0(self):
    self.coding_button = ttk.Button(self.frame0, text="Coding")
    self.coding_button.bind("<Button-1>", self.get)
    self.coding_button.grid(row=1, column=5)

def make_frame1(self):
    self.gamedev_button = ttk.Button(self.frame1, text="Game Development")
    self.gamedev_button.bind("<Button-1>", self.get)
    self.gamedev_button.grid(row=1 ,column=5)

def make_frame2(self):
    self.digitalmedia_button = ttk.Button(self.frame2, text="Digital Media")
    self.digitalmedia_button.bind("<Button-1>", self.get)
    self.digitalmedia_button.grid(row=1, column=5)

def get(self, event):
    if event.widget == self.coding_button:
        print("ok")
    elif event.widget == self.gamedev_button:
        print("poyo")
    elif event.widget == self.digitalmedia_button:
        print("GUH-HUH")

两种方法都能实现点击对应按钮打印对应内容的需求,推荐第一种,逻辑更清晰简洁。

内容的提问来源于stack exchange,提问作者SosaAli

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 22:40:39