如何通过单击更改tkinter.Button的背景

时间:2018-06-26 15:23:18

标签: python-3.x tkinter

基本上,我想通过 command = *function parameter*

调用非静态和非全局函数

我想创建一个tkinter.Button,使其在单击时改变其颜色。

我试图创建一个子类来添加其他具有其他优势的属性:

import tkinter as tk

class Cell(tk.Button):

    def __init__(self, master, coord , command, bg = "ghost white", state = 0):
        tk.Button.__init__(self, master, bg = bg, height = height, width = width, relief = relief, bd = bd)
        self.coord = coord
        self.state = state

    def switch(self):
        if self.state:
            self.state = 0
            self.config(bg = "gray1")
        else:
            self.state = 1
            self.config(bg = "ghost white")

但是总之,我想做这样的事情:

tk.Button(master, command = lambda: self.config(bg = "color"))

这可能吗?


EDIT : 进一步的背景,因为我认为我的解释并没有完全传达到国外。以及更多错误消息:

我的基本概念:我想要一个矩形网格,您可以在其中单击一个单元格,然后该单元格将颜色从白色变为黑色或以其他方式改变。 因为我没有其他想法(对Tkinter不太熟悉),所以我使用了按钮,但是如果有人有更好的想法,我会很感兴趣

问题:

  1. 如果我尝试使用self.,我会得到

    NameError:名称“ self”未定义

在函数的开头-无需调用它。这样就行不通了。

  1. 我可以做

    cell = tk.Button(master,command = cell.switch)

但是我有很多按钮,我将它们存储在一个数组中

board = []
for i in range(x):
    row = []
    for j in range(y):
        # Button or selfmade Cell class - no difference
        cell = tk.Button(master, command = 'needed')
        row.append(cell)
    board.append(row)

是我的设置

我尝试了以下选项:

  1. command = board[x][y].switch 引发索引错误。大概是因为在声明时索引不存在

    • 使用lambda: board[x][y].switch:我没有收到任何错误提示,但点击没有任何反应
    • 带有lambda: board[x][y].switch():我没有收到任何错误,但它只调用了添加到数组中的最后一个单元格上的switch
  2. command = lambda: board[x][y].config(bg = "grey1")-正常工作,但每个按钮仅更改添加到最后一个按钮的颜色 board

2 个答案:

答案 0 :(得分:0)

如果我理解您的问题,则应该在lambda中调用switch()函数

tk.Button(master, command = lambda: self.switch())

但是我认为您可以对此进行更多操作,例如,可以添加颜色的可选arg:

def switch(self, *args):
  if args:
     self.state = args['state']
     self.config(bg = args['bg'])
  else:
      if self.state:
          self.state = 0
          self.config(bg = "gray1")
      else:
          self.state = 1
          self.config(bg = "ghost white")

我以前做过这样的事情,但是我现在没有项目...

编辑:

我刚刚看到了您的修改,并且我想可以为您提供帮助...

尝试将开关功能设置为@staticmethod,这样就不需要self

为此,您需要传递state,如果需要,您可以添加*args,如上所示...

别忘了您可以始终为command提供一个默认值,然后在声明对象后将其更改。

希望对您有所帮助!

答案 1 :(得分:0)

如果单击按钮,则可以使用lambda方法更改按钮的颜色。

这个简单的例子说明了原理

import tkinter as tk

root = tk.Tk()

btn = tk.Button(root,text="click me", command = lambda: btn.config(bg="green"))
btn.grid()

root.mainloop()

只要您要更改按钮的颜色就可以了。

如果您希望它做其他事情以及改变颜色,请尝试执行类似的操作,如您所建议的那样,创建一个继承tk.Button行为的新类,并且在单击时也改变颜色。

import tkinter as tk

root = tk.Tk()

class SpecialButton(tk.Button):
    def __init__(self, master=None, **kw):
        self.clicked_color = kw.pop('clickedbg','green')
        tk.Button.__init__(self,master,**kw)
        self.bind('<Button-1>',self.clicked)
    def clicked(self,*args):
        self['bg'] = self.clicked_color

def somethingElse():
    print("Doing something else")

btn = tk.Button(root,text="click me", command = lambda: btn.config(bg="green"))
btn.grid()
btn2 = SpecialButton(root,text="You can click me too", command=somethingElse, clickedbg='red')
btn2.grid()

root.mainloop()

我为此按钮clickedbg添加了一个新关键字,您可以使用该关键字来配置按钮应更改为哪种颜色。