我有一个问题,围绕着在tkinter-canvas上的对称不可见网格上放置随机大小的正方形的可行方法。我将非常彻底地解释它,因为这是一个专有的问题。
到目前为止,我主要是尝试用数学方法来解决这个问题。但我发现这是一个相当复杂的问题,而且似乎有一种比我尝试过的更好的方法来解决它。
在其最基本的形式中,代码如下所示:
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 > window width时),其中包含xpos (X上的位置),以及改变Y轴以创建新行。
当放置相同大小的方块时,它看起来像这样:
到目前一切尚好。
然而,当正方形是随机大小时,它看起来像这样(最好):
核心问题,除此之外,布局可能是相当不可预测的,是正方形没有居中到“看不见的网格”-因为没有。
因此,为了解决这个问题,我尝试了一种方法,其中我使用固定距离和基于每个给定方块的相对距离。这会在第一行的Y轴上产生令人满意的结果,但不会在X轴上产生满意的结果,也不会在Y上产生令人满意的结果。
请参见示例(其中第一行在Y上居中,但后面的行在Y上居中,而X不在Y上):
所以在这个方法中,我在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的内置函数来解决它。
发布于 2018-07-28 06:28:09
为什么不直接使用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)
这将使所有内容排列在一起,但随机性可能会使行和列的大小不同。您可以使用row- and can columnconfigure函数对其进行调整:
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()
发布于 2018-07-28 09:32:12
我找到了导致结果不符合预期的罪魁祸首,这不是由于计算。相反,事实证明我创建的列表没有将方块按正确的顺序排列(这一点我在前面就应该知道了)。
因此,我从原始数据本身获取宽度,这比创建列表更有意义。
这个函数现在看起来像这样(同样,它还在改进中,但我只是想发布这篇文章,这样人们就不会浪费时间去想出一个已经解决的问题的解决方案:):
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
https://stackoverflow.com/questions/51565707
复制相似问题