我有一个问题围绕着什么是可行的方法来在tkinter画布上的对称,不可见网格上放置随机大小的正方形。我将对此进行彻底的解释,因为这是一个专有问题。
到目前为止,我主要尝试用数学方法解决它。但是我发现这是一个非常复杂的问题,并且采用比我尝试过的方法更好的方法似乎是合理的。
最基本的代码如下:
while x_len > canvas_width:
xpos = x_len + margin
squares[i].place(x=xpos, y=ypos)
x_len += square_size + space
i += 1
x_len是给定行上所有正方形的总宽度,并且在退出while循环时(例如,当x_len>窗口宽度时),在xpos(在X上的位置)以及重置Y时重置。轴以创建新行。
到目前为止很好。
除了布局可能无法预测之外,核心问题是正方形没有居中于“不可见网格”上-因为没有网格。
因此,为了解决这个问题,我尝试了一种方法,即根据每个给定的平方使用固定距离和相对距离。这样一来,对于第一行的Y轴,而不是X轴,Y的后续行,也不会有令人满意的结果。
请参阅示例(其中第一行以Y为中心,但随后的行而不是X):
因此,通过这种方法,我基于从包含所有生成的正方形的宽度的列表中获取的变量,在Y轴和X轴上都使用了每平方改变。
从整体上看,它是这样的(尽管它仍在进行中,所以优化程度不是很好):
square_widths = [60, 75, 75, 45...]
space = square_size*0.5
margin = (square_size+space)/2
xmax = frame_width - margin - square_size
xmin = -1 + margin
def iterate(ypos, xpos, x_len):
y = ypos
x = xpos
z = x_len
i=0
m_ypos = 0
extra_x = 0
while len(squares) <= 100:
n=-1
# row_ypos alters y for every new row
row_ypos += 200-square_widths[n]/2
# this if-statement is not relevant to the question
if x < 0:
n=0
xpos = x
extra_x = x
x_len = z
while x_len < xmax:
ypos = row_ypos
extra_x += 100
ypos = row_ypos + (200-square_widths[n])/2
xpos = extra_x + (200-square_widths[n])/2
squares[i].place(x=xpos, y=ypos)
x_len = extra_x + 200
i += 1
n += 1
这里最相关的是row_ypos,它改变每一行的Y,以及ypos,改变每一平方的Y(我还没有X的有效计算)。我想要获得的结果与第一行的Y轴类似。在所有行和列上(例如在X和Y中)。创建一个具有不同大小正方形的对称网格。
所以我的问题是: 这真的是解决此问题的最佳做法吗? 如果是这样-您是否有任何技巧可以达到目的? 如果不是-您将如何处理?
一个旁注是,它必须“手动”完成,我不能使用tkinter的内置函数来解决它。
答案 0 :(得分:1)
为什么不只使用grid
几何管理器?
COLUMNS = 5
ROWS = 5
for i in range(COLUMNS*ROWS):
row, col = divmod(i, COLUMNS)
l = tk.Label(self, text=i, font=('', randint(10,50)))
l.grid(row=row, column=col)
这将使所有内容对齐,但是随机性可能会使行和列的大小不同。您可以使用行和列配置功能进行调整:
import tkinter as tk
from random import randint
COLUMNS = 10
ROWS = 5
class GUI(tk.Frame):
def __init__(self, master=None, **kwargs):
tk.Frame.__init__(self, master, **kwargs)
labels = []
for i in range(COLUMNS*ROWS):
row, col = divmod(i, COLUMNS)
l = tk.Label(self, text=i, font=('', randint(10,50)))
l.grid(row=row, column=col)
labels.append(l)
self.update() # draw everything
max_width = max(w.winfo_width() for w in labels)
max_height = max(w.winfo_height() for w in labels)
for column in range(self.grid_size()[0]):
self.columnconfigure(col, minsize=max_width) # set all columns to the max width
for row in range(self.grid_size()[1]):
self.rowconfigure(row, minsize=max_height) # set all rows to the max height
def main():
root = tk.Tk()
win = GUI(root)
win.pack()
root.mainloop()
if __name__ == "__main__":
main()
答案 1 :(得分:0)
我发现导致结果没有达到预期效果的罪魁祸首,这不是由于计算所致。相反,事实证明,我创建的列表未按正确的顺序放置正方形(此后我应该知道)。
所以我从原始数据本身获取了宽度,这比创建列表要有意义得多。
该函数现在看起来像这样(再次,它仍在完善中,但是我只想发布它,这样人们就不会浪费时间为已经解决的问题提出解决方案了:)):< / p>
def iterate(ypos, xpos, x_len):
y = ypos
x = xpos
z = x_len
i=0
while len(squares) <= 100:
n=0
if y > 1:
ypos -= max1 + 10
if y < 0:
if ypos < 0:
ypos=10
else:
ypos += max1 + 10 #+ (max1-min1)/2
if x < 0:
n=0
xc=0
xpos = x
x_len = z
while x_len < xmax:
yc = ypos + (max1-squares[i].winfo_width())/2
if xpos <= 0:
xpos = 10
else:
xpos += max1 + 10
xc = xpos + (max1-squares[i].winfo_width())/2
squares[i].place(x=xc, y=yc)
x_len += max1 + 10
print (x_len)
i += 1
n += 1