【问题标题】:Changing Button Appearance On Click单击时更改按钮外观
【发布时间】:2017-05-14 05:14:58
【问题描述】:

在我的 GUI 应用程序中,我为给定列表中的每个项目创建一个按钮。当按下按钮时,所述按钮的背景变为绿色,并显示为“凹陷”。其他按钮显示为凸起并具有默认颜色。我的问题是只有最后一个创建的按钮会改变颜色和外观。我相信这是因为它包含回调函数。

我希望在第一次按下按钮后,当用户按下不同的按钮时,新按钮会变为绿色并出现凹陷,而前一个按钮会升起并变为默认颜色。我的猜测是我需要创建一个所有已创建按钮的列表,并在回调函数中对其应用逻辑以实现我想要的行为。但怎么会呢?

# ---callback functions---
def select_button():
    btn.config(bg='green', activebackground='green', relief=SUNKEN)

# ---main---
# List of buttons to be created
list = ['A', 'B', 'C']
buttons = []

# Create buttons
for i, name in enumerate(list, 2):
    btn = Button(root, text=name, command=select_button)
    btn.grid(row=i, column=0, sticky=W)
    buttons.append(btn)

【问题讨论】:

  • 我知道按钮的默认背景颜色是浅灰色。
  • for-loo 变量btn 之后只保留最后一个按钮,因此使用btn.config 你只更改最后一个按钮。
  • 此元素与问题无关,但下次不要更改问题,因为其他阅读问题和评论,他们可能不明白发生了什么。最好在原始版本下方添加有问题的解释/修改。
  • 我删除了旧的 cmets。
  • 听起来您最好使用 Radiobutton 并将 indicatoron 设置为 False,这几乎完全符合您的描述:一组按钮中只能选择一个,并且看起来是凹陷的,而其余的看起来是凸起的。您对使用 Radiobutton 小部件的解决方案感兴趣吗?

标签: python button tkinter


【解决方案1】:

在 Stackoverflow 上写了这么多次,不知道要不要再写一次。

Buttoncommand= 来分配函数,但它可以在没有参数的情况下分配函数。如果你需要参数,你必须使用lambda。我根据按钮分配功能,因此功能可以使用正确的按钮并更改它。

for-loop 中的lambda 需要arg=btnselect_button(arg),因为直接select_button(btn) 将在所有功能中使用最后一个按钮。


至于将上一个按钮更改为原始颜色,您可以使用变量来记住以前单击的按钮,然后您可以轻松更改它的颜色。

问题可能是找到按钮的原始颜色,所以我从新单击的按钮中复制它。

import tkinter as tk

# --- functions ---

def select_button(widget):
    global previously_clicked

    if previously_clicked:
        previously_clicked['bg'] = widget['bg']
        previously_clicked['activebackground'] = widget['activebackground']
        previously_clicked['relief'] = widget['relief']

    widget['bg'] = 'green'
    widget['activebackground'] = 'green'
    widget['relief'] = 'sunken'

    previously_clicked = widget

# --- main ---

names = ['Button A', 'Button B', 'Button C']

root = tk.Tk()

previously_clicked = None

for i, name in enumerate(names, 2):
    btn = tk.Button(root, text=name)

    btn.config(command=lambda arg=btn:select_button(arg))
    #btn['command'] = lambda arg=btn:select_button(arg)

    btn.grid(row=i, column=0, sticky='w')

root.mainloop()

编辑:您也可以使用 Radiobutton 和一些选项来做同样的事情 - 并且没有功能:

见:http://effbot.org/tkinterbook/radiobutton.htm

import tkinter as tk

# --- functions ---

def select_button():
    print('value:', v.get())  # selected value

# --- main ---

names = ['Button A', 'Button B', 'Button C']

root = tk.Tk()

v = tk.IntVar()  # variable for selected value

for i, name in enumerate(names, 2):
    btn = tk.Radiobutton(root, text=name, variable=v, value=i)  # assign variable and value

    btn['indicatoron'] = 0  # display button instead of radiobutton
    btn['selectcolor'] = 'green' # color after selection

    btn['command'] = select_button  # function without variables

    btn.grid(row=i, column=0, sticky='w', ipadx=5, ipady=5)

root.mainloop()

【讨论】:

  • 是的,这是一个常见问题,但我的情况不同。按下新按钮后如何更改初始按钮的外观?此初始按钮应配置为其原始状态。
  • 现在我知道你需要什么了。 - 您可以使用变量来记住以前单击的按钮,然后您可以将其更改为原始值。
  • 我用Radiobutton添加示例
  • 我想过用单选按钮代替按钮,但不知道btn['indicatoron']。我喜欢它们看起来像按钮但充当单选按钮。谢谢!
【解决方案2】:

我遇到了类似的问题,最终在函数中定义了一个函数来解决我的问题。在你的情况下,我们会得到这个:

import tkinter as tk

def select(btn):
    def select_button():
        for other_btn in buttons:
            deactivate(other_btn)
        btn.config(bg='green', activebackground='green', relief=tk.SUNKEN)
    return select_button

def deactivate(btn):
    btn.config(bg='gray', activebackground='gray', relief=tk.RAISED)

list_ = ['A', 'B', 'C']
buttons = []

root = tk.Tk()

for i, name in enumerate(list_, 2):
    btn = tk.Button(root, text=name) 
    btn['command'] = select(btn)
    btn.grid(row=i, column=0, sticky=tk.W)
    buttons.append(btn)

root.mainloop()

这里的重要部分是我们通过定义一个直接集成这些参数的函数来绕过无法将参数传递给 button['command'] 的困难。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多