简体   繁体   English

tkinter 二维按钮列表命令不起作用

[英]tkinter 2d button list command not working

I recently got back into using Python 3's tkinter and am working on some simple problems.我最近重新开始使用 Python 3 的 tkinter 并正在处理一些简单的问题。 I am working on creating a Tic Tac Toe program, but I am running into an issue.我正在创建一个 Tic Tac Toe 程序,但我遇到了一个问题。 I am using a 2d list of buttons to call a command function when they are clicked.单击按钮时,我正在使用二维按钮列表调用命令 function。 I have used partial to run functions with parameters previously.我以前使用 partial 来运行带参数的函数。 The program does use command functions correctly.该程序确实正确使用了命令功能。 Why is the command not executing when the buttons in the 2d list are clicked on?为什么单击二维列表中的按钮时命令不执行?

from tkinter import *
import tkinter as tk
from functools import partial

class App(tk.Tk):
    def __init__(self):
        super().__init__()
        pixel = tk.PhotoImage(width=1, height=1)


        # configure the root window
        self.title('Tic Tac Toe')
        self.geometry('500x500')

        self.turn=0
        self.options=["X","O"]

        # label
        self.label = tk.Label(self, text='Tic Tac Toe')
        self.label.config(font="Calibri 48")
        self.label.pack()

        self.gameframe=Frame(self)
        self.gameframe.pack()
        self.buttons=[[Button for i in range(3)] for j in range(3)]

        #The main issue with the code
        for i in range(3):
            for j in range(3):
                #self.buttons[i][j]['command'] = self.hello
                buttonfunction = partial(self.clickbutton, i, j)

                self.buttons[i][j]=Button(self.gameframe,image=pixel)

                self.buttons[i][j].config(command= buttonfunction)
                self.buttons[i][j].config(width=100,height=100)
                self.buttons[i][j].grid(row=i,column=j)

        print(self.buttons)
        self.button = Button(self, text='Test')
        self.button['command'] = self.hello
        self.button.pack()


    def hello(self):
        print("Hello")

    
    def clickbutton(self,x,y):
        print(x,y)
        buttontext=self.options[self.turn]
        self.buttons[y][x].config(text=buttontext)
        self.turn=(self.turn+1)%2
    

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

Image of the Python 3 Tkinter Tic Tac Toe Layout Python 3 Tkinter 井字布局的图像

This is one of the class tkinter blunders.这是 class tkinter 失误之一。 The ISSUE here is that pixel is local to the __init__ function, and the Button class doesn't grab a reference.这里的问题是pixel__init__ function 的本地像素,而Button class 没有获取引用。 When the function ends, that image is destroyed, the button becomes invalid and no longer responds.当function结束时,那个图像被销毁,按钮失效,不再响应。

Use:利用:

        self.pixel = tk.PhotoImage(width=1, height=1)
...
                image = self.pixel,

and things work better.事情变得更好了。 You may need to specify compound='c' if you want both text and image.如果您需要文本和图像,您可能需要指定compound='c'

And Paul M. is right, you need to change your button function to Paul M. 是对的,您需要将按钮 function 更改为

        buttonfunction = partial(self.clickButton, j, i)

to get the rows and columns right.使行和列正确。 Here's the code I have, which works:这是我的代码,它有效:

        for i in range(3):
            for j in range(3):
                buttonfunction = partial(self.clickbutton, j, i)

                self.buttons[i][j]=Button(self.gameframe,
                    image=self.pixel,
                    text = '--',
                    compound='c',
                    width=100,
                    height=100,
                    command=buttonfunction)
                self.buttons[i][j].grid(row=i,column=j)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM