Python Tkinter Canvas 形状在 Canvas 网格化时不显示,但在打包时显示?

标签 python tkinter

第一次使用stackexchange 所以我从一个月前就开始自学编程,进展得很慢。 我遇到了很多问题,因为我一直在临时随机浏览在线教程,甚至没有看过任何书籍或任何东西,通过 self 经验学习并尝试构建“项目”(这占用了如此多的时间)很多时间做一些简单的事情)。

总之,我遇到了很多问题,最后都解决了,花了很多时间。我绕过了一些问题,不知道出了什么问题,但只是记住该区域确实出了问题。

好了,我已经决定,任何我无法解决的问题,我都可以在这里提问。这是一个我不太理解的简单问题:

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 个半切矩形(不是行网格,这是仅一个 block ,第 0 行,第 0 列)。但是,如果我打包它,它会正确显示,显示所有 16 个矩形。

预先感谢您花时间阅读本文,我知道这有点不清楚!

编辑:还有另一个问题(我知道我应该在另一篇文章中询问,但这是一个规模较小的问题),假设我有四张 Canvas ,其 parent 为根。他们的名字如下:

firstCanvas = Canvas(root)
secondCanvas = Canvas(root)
thirdCanvas = Canvas(root)
fourthCanvas = Canvas(root)

并说我已经将它们全部打包/网格化或者诸如此类。现在我想将鼠标点击绑定(bind)到它们中的每一个。我愿意: firstCanvas.bind("", mousePressed) FourthCanvas.bind("", mousePressed)

等等...,但是如果我有 10 个 Canvas ,我是否必须为其中的 10 个手动粘贴该行?我可以创建一个将它们整齐地绑定(bind)在一起的循环吗?这里的问题是我不能对 [first,second,third...] 中的数字说 number+Canvas.bind... 等,因为它不能像那样工作。很多事情都未定义,更不用说它根本不起作用。

使用字符串来解决它也不起作用,因为firstCanvas不是一个字符串,它实际上是一个指向 Canvas 的“变量”。

我已经做过很多次的解决方法是创建一个字典,其中它们确实使用可以是变量的字符串。例如,对于 [first,...] 中的数字,canvas_data["%d"%(number) +Canvas] = do_your_thing_here,这可以工作,但不是很优雅。

更不用说我什至不确定在 tkinter 中使用分配给实际 Canvas 的字典变量实际上是否有效(尚未尝试)。如果是的话,那么我可以这样做......说 canvas_data[firstCanvas].bind("", mousePressed)。

但这不是重点,我正在寻找另一种方法来做到这一点,无论如何要“更改”不是字符串的字符?

换一种说法,我有变量,称为variableA、variableB、variableC 我想做一些类似的事情(2个例子):

    for letter in [A,B,C]:
        variable+letter = letter

    varA = 1, varB = 2, varC = 3
    for letter in [A,B,C]: 
        print var+letter.

我希望我足够清楚......对此事的任何帮助都会很棒。

最佳答案

使用列表和数字来代替名称 firstCanvassecondCanvas

canvases = []

for x in range(10):
    canvases.append( Canvas(root) )

通过这种方式,您可以创建任意数量的 Canvas ,然后可以将其用作

canvases[0]
canvases[1]
etc.

以同样的方式绑定(bind)到所有 Canvas

for c in canvases:
    c.bind(...)

或者您可以立即执行此操作

canvases = []

for x in range(10):
    c = Canvas(root)
    c.bind(...)
    canvases.append( c )
<小时/>

使用字典代替variableAvariableBvariableC

variables = {}

for letter in 'ABC':
    variables[letter] = letter

variables = {'A': 1, 'B': 2, 'C': 3}

for letter in 'ABC': 
    print varaibles[letter]
<小时/>

至于第一/主要问题 - 通常,当您调整窗口大小时,网格不会更改单元格大小。

因此单元格保持大小(它获取窗口的大小),并且您只能看到 Canvas 的一部分。如果您设置窗口大小(或者设置 Canvas 大小),您将看到更多矩形。

但是您可以在调整窗口大小时更改网格行为来调整行或列的大小。

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() - 不带参数 - 并且你也只能得到矩形的一部分。

<小时/>

Tkinterbook : The Tkinter Grid Geometry Manager , The Tkinter Pack Geometry Manager

关于Python Tkinter Canvas 形状在 Canvas 网格化时不显示,但在打包时显示?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24875969/

相关文章:

python - 如何设置子窗口的标题

python - 同时运行多个 Python 脚本,然后依次运行

python - 类型错误 : input expected at most1 arguments got 3

python - 当光标放在python中的按钮上时显示文本

python - Tkinter 窗口由于列表框中的项目而改变大小

python - 如何解决 tkinter 渲染质量低的问题

python - 在 Python 中使用 Tkinter canvas 循环浏览图像

python - webfaction 中的 Tornado Web 服务器

python - 从 Python 中的 unicode 字符串中删除 HTML 标签

python - 快速将带有索引的 numpy 数组转换为以该索引为键的 numpy 数组的字典