python 3中GUI的抽象网格

问题描述

对于一项作业,我需要创建一个继承自tk.Canvas的类,该类实质上形成一个“抽象网格”-具有一定数量的行和列的网格,它们都应支持在特定位置创建文本基于行和列

我知道tkinter已经有一个内置网格,但是我将如何初始化该网格的一部分,比如axb区域,这取决于我输入到参数中的行数或列数,以及如何返回其位置该网格中的小部件?

谢谢!

解决方法

假设您有一个网格,其中cell_cols(x数)乘以cell_rows(y数)

然后全部归结为画布的宽度和高度(以像素为单位)。

在网格pixel_xpixel_y处单元格的左上角grid_xgrid_y像素坐标总是:

pixel_x = grid_x * canvas.width // cell_cols 
pixel_y = grid_y * canvas.height // cell_rows 

假设0→宽度1和0→高度1坐标系(对于Tkinter我不确定100%)

如果允许窗口调整大小(这是个好主意),则每次都需要重新计算位置。我只是将其设置为默认方法,然后可以灵活地用于以后的更改。

,

您可以轻松地将tk.Canvas子类化,并赋予其所需的行为:

根据行和列在特定位置创建文本

这里是一个例子:

import tkinter as tk

class TextGrid(tk.Canvas):
    
    def __init__(self,rows,cols,master):
        self.master = master
        super().__init__(self.master)
        self.rows = rows
        self.cols = cols
        
    def create_text_at(self,row,col,text):
        """support creation of text at specific positions based on row and column
        """
        x = self.winfo_width() // self.cols * (col + .5)
        y = self.winfo_height() // self.rows * (row + .5)
        self.create_text(x,y,text=text)
        
def write_text():
    row = int(row_entry.get())
    col = int(col_entry.get())
    text = txt_entry.get()
    tcv.create_text_at(row,text)
        
root = tk.Tk()
tcv = TextGrid(10,12,root)
tcv.pack(expand=True,fill=tk.BOTH)

tk.Label(root,text='col').pack()
col_entry = tk.Entry(root)
col_entry.pack()
tk.Label(root,text='row').pack()
row_entry = tk.Entry(root)
row_entry.pack()
tk.Label(root,text='text').pack()
txt_entry = tk.Entry(root)
txt_entry.pack()
cmf = tk.Button(root,text='confirm',command=write_text)
cmf.pack()

root.mainloop()

enter image description here