Найти - Пользователи
Полная версия: Определение координат виджета (кнопки) в сетке grid
Начало » GUI » Определение координат виджета (кнопки) в сетке grid
1
justacoder
Нужно определить координаты кнопки but не в пикселях, а в столбцах и рядках. Облазив кучу сайтов, в том числе и официальный сайт Python, ничего не нашёл и начал уже сомневаться в возможности осуществления задуманного) Может, мимо глаз проскочило. Знает кто, что делать?

 from tkinter import *
root = Tk()
but = Button(root, text='Print')
but.grid(row=0, column=0)
def coordinates(event):
    print("""???""")
but.bind('<Button-1>', coordinates)
mainloop()

FishHook
justacoder
Облазив кучу сайтов
Это вы зря. Не надо забывать про волшебные свойства функции dir.
Вот смотрите, за две минуты изысканий без просмотра кучи сайтов я нашел для вас решение, хотя с Tkinter-ом вообще не работаю и не знаю.
   
# -*-coding:utf-8-*-
from Tkinter import *
root = Tk()
but = Button(root, text='Print')
but.grid(row=10, column=0)
def coordinates(event):
    print(but.grid_info()["row"])
but.bind('<Button-1>', coordinates)
mainloop()
justacoder
Огромное спасибо) Я себя экспертом и вообще опытным программистом назвать уж никак не могу, про dir напрочь забыл.
justacoder
Недолго счастье длилось…
Новая проблема. Почему-то в качестве координаты y (column) везде при определении показывает 19, то есть координату последнего столбца, хотя если бы при расставлении кнопок стояло это значение, то, сами понимаете, видно было бы только один столбец.
 from tkinter import *
root = Tk()
def create_grid(x, y):
    def create_line(x1, y1):
        def print_x_y(event):
            x_y = []
            row = (but.grid_info()['row'])
            column = (but.grid_info()['column'])
            x_y.append(row)
            x_y.append(column)
            print(x_y)
        for j in range(20):
            but = Button(root, bg='white')
            but.grid(row=x1, column=y1)
            but.bind('<Button-1>', print_x_y)
            y1 += 1
    for i in range(20):
        create_line(x, y)
        x += 1
create_grid(0, 0)
mainloop()
4kpt_IV
У меня есть только 1 вопрос. Зачем Вам знать позицию кнопки в гриде?
justacoder
Что ж, я пытаюсь написать игру Сапёр. Мины у меня хранятся в качестве списка, содержащего списки с парой координат. Чтобы проверить, является ли кнопка заминированной, я сверяю её координаты с теми, что содержатся в списке. Мне этот вариант показался вполне приемлимым, единственной проблемой оказалось определение координат кнопки для сравнения. Сделал так, как посоветовали, получил новую проблему. Позиция row определяется правильно, но column всегда показывает 19. Если же сначала выстраивать столбцы, а не рядки, в функции create_line, то row всегда будет 19, а column будет иметь правильное значение. Может, это связано с тем, что функция, определяющая координаты и выводящая их в консоль, внутри функции, которая создаёт линию? Попробовал сделать так - координаты выводятся в консоль сразу после создания кнопок, даже без нажатия, на которые потом не реагирует.
 from tkinter import *
root = Tk()
def print_x_y(but):
    x_y = []
    row = (but.grid_info()['row'])
    column = (but.grid_info()['column'])
    x_y.append(row)
    x_y.append(column)
    print(x_y)
def create_grid(x, y):
    def create_line(x1, y1):
        for j in range(20):
            but = Button(root, bg='white')
            but.grid(row=x1, column=y1)
            but.bind('<Button-1>', print_x_y(but))
            y1 += 1
    for i in range(20):
        create_line(x, y)
        x += 1
create_grid(0, 0)
mainloop()
FishHook
Не то вы делаете

 from tkinter import Tk, Button
import sys
matrix = [
    [0, 0, 0, 0, 1],
    [0, 1, 0, 0, 0],
    [0, 0, 1, 0, 0],
    [1, 0, 0, 1, 1],
    [0, 0, 1, 1, 1],
]
root = Tk()
def but_click(e):
    if e.widget.value:
        print("BOOM")
        sys.exit()
    else:
        e.widget.destroy()
def bomb_around(row, cell):
    i = 0
    def inc(r, c):
        if r < 0 or c < 0:
            return 0
        try:
            return matrix[r][c]
        except IndexError:
            return 0
    # cross
    i += inc(row - 1, cell)
    i += inc(row, cell - 1)
    i += inc(row + 1, cell)
    i += inc(row, cell + 1)
    #diag
    i += inc(row - 1, cell - 1)
    i += inc(row + 1, cell - 1)
    i += inc(row - 1, cell + 1)
    i += inc(row + 1, cell + 1)
    return i
for row_index, row in enumerate(matrix):
    for cell_index, cell in enumerate(row):
       button = Button(root, text=bomb_around(row_index, cell_index) or '')
       button.grid(row=row_index, column=cell_index)
       button.value = cell
       button.bind("<Button-1>", but_click)
root.mainloop()
justacoder
Что ж, пожалуй, Ваш вариант лучше. Да и свою проблему я уже решил.
 from tkinter import *
root = Tk()
def print_x_y(event):
    x_y = []
    row = (event.widget.grid_info()['row'])
    column = (event.widget.grid_info()['column'])
    x_y.append(row)
    x_y.append(column)
    print(x_y)
def create_grid(x, y):
    def create_line(x1, y1):
        for j in range(20):
            but = Button(root, bg='white')
            but.grid(row=x1, column=y1)
            but.bind('<Button-1>', print_x_y)
            y1 += 1
    for i in range(20):
        create_line(x, y)
        x += 1
create_grid(0, 0)
mainloop()
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB