问题描述
对于一项作业,我需要创建一个继承自tk.Canvas的类,该类实质上形成一个“抽象网格”-具有一定数量的行和列的网格,它们都应支持在特定位置创建文本基于行和列
我知道tkinter已经有一个内置网格,但是我将如何初始化该网格的一部分,比如axb区域,这取决于我输入到参数中的行数或列数,以及如何返回其位置该网格中的小部件?
谢谢!
解决方法
假设您有一个网格,其中cell_cols
(x数)乘以cell_rows
(y数)
然后全部归结为画布的宽度和高度(以像素为单位)。
在网格pixel_x
,pixel_y
处单元格的左上角grid_x
和grid_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()