Tkinter:按行和列识别按钮 [英] Tkinter: Identifying button by row and column

查看:35
本文介绍了Tkinter:按行和列识别按钮的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我希望能够根据它在网格和按钮上的行和列来选择一个按钮,并控制它的文本和浮雕.我无法在以这种方式使用的小部件或单元格上找到任何内容.我更改了 root 的放置位置,现在它说我不能使用我收到的用于救济"的元组,这是有道理的,我需要访问小部件本身.任何建议

I want to be able to select a button based on what row and column it is in on a grid and the button and control its Text and Relief. I haven't been able to find anything on widgets or cells used in this manner. I changed where root is placed and now it says that I can't use a tuple that I recieved for 'relief' which makes sense, I need to access the widget itself. Any reccomendations

import tkinter
import functools
import random
from time import sleep
width = input('Enter the grid width. ')
height = input('Enter the grid height. ')
numb = input('Enter the number of bombs. ')
Matrix = [[0 for lp in range(int(width))] for fg in range(int(height))]
def ranintx():
    return  random.randint(0,int(width))
def raninty():
    return random.randint(0,int(height))

def placemines():
   y = ranintx()
   x = raninty()
   for ranintformine in range(int(numb)):
       x = ranintx()
       y = raninty()
       Matrix[y-1][x-1] = 1
placemines()
def sunken(event, self, x, y):
    button = event.widget
    button['relief'] = 'sunken'
    if x - 1 < 0 :
        return
    if x > int(width) + 1 :
        return
    if y - 1 < 0 :
        return
    if y > int(height) + 1 :
        return
    if Matrix[x][y] == 1 :
        top = tkinter.Toplevel()
        top.title("About this application...")

        msg = tkinter.Message(top, text="You Lose")
        msg.pack()

        button = tkinter.Button(top, text="Dismiss", command=top.destroy)
        button.pack()
        print('Column = {}\nRow = {}'.format(x, y))
    else:
       n1 = x - 1
       n2 = y - 1

       for lp in range(3):
            for lp2 in range(3):
                abutton = root.grid_location(n1, n2)
                abutton['relief'] = ['sunken']
                # I want to be able to change and select the button here. This was one of my poor attempt 
                n2 =+ 1
            n1 =+ 1
def push(event, self, x, y):
    button = event.widget
    if Matrix[x][y] == 1 :
         print('Column = {}\nRow = {}'.format(x, y))
 class MineSweep(tkinter.Frame):

        @classmethod
        def main(cls, width, height):
        window = cls(root, width, height)
        '''placemine()'''
        root.mainloop()

    def __init__(self, master, width, height):
        super().__init__(master)
        self.__width = width
        self.__height = height
        self.__build_buttons()
        self.grid()
    #def sunken(event):
    #    button = event.widget
    #    button['relief'] = 'sunken'
    def __build_buttons(self):
        self.__buttons = []
        for y in range(self.__height):
            row = []
            for x in range(self.__width):
                button = tkinter.Button(self, state='disabled')
                button.grid(column=x, row=y)
                button['text'] = ' '
                print(grid.slaves)
                self.checked = True
                #button['command'] = functools.partial(self.__push, x, y)
                button.bind("<Button-3>",
                    lambda event, arg=x, brg=y: push(event, self, arg, brg))
                button['relief'] = 'raised'
                button.bind("<Button-1>",
                    lambda event, arg=x, brg=y: sunken(event, self, arg, brg))


                #button['command'] = sunken
                row.append(button)
             self.__buttons.append(row)



root = tkinter.Tk()
if __name__ == '__main__':
    MineSweep.main(int(width), int(height))

推荐答案

您的程序有一些问题.首先,sunken 应该是类上的一个方法.把它放在类之外是很奇怪的,然后你将 self 作为其他参数传入.它有效,但它使代码非常混乱.

You have a few things wrong with your program. First, sunken should be a method on the class. It's very weird to have it outside the class, and then you pass in self as some other argument. It works, but it makes the code very confusing.

话虽如此,您实际上已经非常接近完成这项工作了.您已经在列表列表中保存了对每个按钮的引用,因此您应该能够使用 self.__buttons[y][x] 获取小部件.但是,因为sunken 不是类的一部分,并且因为您使用两个下划线命名变量,所以sunken 无法访问该变量功能.

That being said, you're actually very close to making this work. You're already saving a reference to each button in a list of lists, so you should be able to get the widget with self.__buttons[y][x]. However, because sunken is not part of the class, and because you named the variable with two underscores, the variable is not accessible to the sunken function.

如果您将变量更改为具有单个下划线而不是双下划线,则您的代码应该或多或少地按原样工作(一旦您修复了语法和缩进错误).另一种解决方案是使 sunken 成为类上的一个方法并修复您的调用方式(删除 self 参数,将其称为 self.sunken),它将与两个下划线.

If you change the variable to have a single underscore instead of a double, your code should work more-or-less exactly as it is (once you fix the syntax and indentation errors). The other solution is to make sunken a method on the class and fix how you call it (remove the self argument, call it as self.sunken), it will work with two underscores.

坦率地说,使用两个下划线的实际好处为零.避免使用它的诱惑.至少,在你的基本逻辑正常工作之前不要使用它,然后你可以回去隐藏你不想暴露的属性.

Frankly, using two underscores has zero practical benefit. Avoid the temptation to use it. At the very least, don't use it until you have your basic logic working, then you can go back and hide attributes you don't want to be exposed.

这篇关于Tkinter:按行和列识别按钮的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆