Python Tkinter画布在使用网格布局时形状不显示,但在使用打包时显示?
这是我第一次在stackexchange发帖。我从一个月前开始自学编程,进展得比较慢。遇到了很多问题,因为我都是随便找网上的教程,根本没看过书,完全靠自己的经验,试着去做一些“项目”(即使是简单的项目也花了我很多时间)。
总之,我遇到了很多问题,最终都解决了,虽然花了不少时间。有些问题我只是绕过了,虽然不知道哪里出错了,但我知道那个地方肯定有问题。
说了这么多,我决定如果遇到解决不了的问题,就来这里问问。所以我有一个简单的问题,搞不太明白:
from Tkinter import *
root = Tk()
backgroundCanvas = Canvas(root)
backgroundCanvas.grid(row = 0, column = 0, sticky = N+S+E+W)
#backgroundCanvas.pack(fill = BOTH, expand = True)
margin= 20
padding = 10
cellWidth = 100
cellHeight = 130
xypos = [ ]
xdif = cellWidth + 2*padding
ydif = cellHeight + 2*padding
for i in range(4):
for j in range(4):
a = margin+padding+i*xdif
b = margin+j*ydif
xypos.append((a,b,a+cellWidth,b+cellHeight))
for xpos1,ypos1,xpos2,ypos2 in xypos:
backgroundCanvas.create_rectangle((xpos1,ypos1),(xpos2,ypos2), fill = "blue")
print xpos1,ypos1,xpos2,ypos2
root.mainloop()
抱歉没有附上图片,但如果我用网格布局,它只会在“第一行”创建3个完整的矩形,然后在“第二行”创建3个半切的矩形(不是行网格,行网格只有一个块,行0,列0)。但是如果我用打包布局,它就能正常显示,显示所有16个矩形。
谢谢你们花时间看这个,我知道有点不清楚!
补充一下:还有另一个问题(我知道应该在另一个帖子问,但这个问题规模小一点),假设我有四个画布,它们的父级都是根节点。它们的名字如下:
firstCanvas = Canvas(root)
secondCanvas = Canvas(root)
thirdCanvas = Canvas(root)
fourthCanvas = Canvas(root)
假设我已经把它们都打包或用网格布局了。现在我想把鼠标点击事件绑定到每一个画布上。我这样做:
firstCanvas.bind("", mousePressed) fourthCanvas.bind("", mousePressed)等等……但是如果我有10个画布,我是不是得手动复制那行代码10次?我能不能创建一个循环,把它们都整齐地绑定上?问题是我不能用类似number+Canvas.bind...这样的方式,因为这样不行。很多东西都是未定义的,更别提根本就不工作了。
用字符串来解决这个问题也不行,因为firstCanvas不是字符串,它实际上是一个指向画布的“变量”。
我曾经做过的一个变通方法是创建一个字典,里面用的确实是可以作为变量的字符串。例如,对于number in [first,...],canvas_data["%d" %(number) +Canvas] = do_your_thing_here,这样可以,但不太优雅。
更不用说我还不确定在tkinter中用字典变量来指向实际的画布是否有效(还没试过)。如果可以的话,我可以这样做……比如canvas_data[firstCanvas].bind("", mousePressed)。
但这不是重点,我想找另一种方法,是否有办法“改变”那些不是字符串的字符?
换句话说,我有一些变量叫variableA、variableB、variableC,我想做类似这样的事情(两个例子):
for letter in [A,B,C]:
variable+letter = letter
varA = 1, varB = 2, varC = 3
for letter in [A,B,C]:
print var+letter.
希望我说得够清楚……任何帮助都非常感谢。
1 个回答
在名字 firstCanvas
和 secondCanvas
的地方,使用列表和数字。
canvases = []
for x in range(10):
canvases.append( Canvas(root) )
这样你可以创建任意数量的画布,然后你可以像这样使用它们。
canvases[0]
canvases[1]
etc.
同样,你也可以对所有画布进行绑定。
for c in canvases:
c.bind(...)
或者你可以一次性做到这一点。
canvases = []
for x in range(10):
c = Canvas(root)
c.bind(...)
canvases.append( c )
在 variableA
、variableB
和 variableC
的地方,使用字典。
variables = {}
for letter in 'ABC':
variables[letter] = letter
还有
variables = {'A': 1, 'B': 2, 'C': 3}
for letter in 'ABC':
print varaibles[letter]
关于第一个/主要问题,通常情况下,当你调整窗口大小时,网格不会改变单元格的大小。
所以单元格保持原来的大小(它会根据窗口的大小来设置),你只会看到画布的一部分。如果你设置窗口的大小(或者设置画布的大小),你会看到更多的矩形。
但是你可以改变 grid
的行为,让它在你调整窗口大小时调整行或列的大小。
backgroundCanvas.grid(row = 0, column = 0, sticky = N+S+E+W)
root.grid_rowconfigure(0, weight=1) # resize row 0 vertically
root.grid_columnconfigure(0, weight=1) # resize column 0 horizontally
顺便提一下:使用 backgroundCanvas.pack()
- 不带参数 - 你也只会看到部分矩形。