Python Tkinter画布不出现

问题描述:

你好,我在使用python的Tkinter包时遇到了问题。我想创建一个窗口,其中包含两个主要的小部件,其中一个是稍后将用单元格显示网格的画布。初始化画布时,我使用“create_rectangle”来填充所需对象的画布。同样,当点击一个单元格时(出于测试的原因)画布应该改变矩形区域的颜色。然而,当初始显示窗口时,首先看不到任何对象(预期的结果将只是白色的矩形),并且只有当执行画布上的单击时,区域才会根据需要更改其颜色。 通过互联网浏览时,我尝试了pack()和create_rectangle()方法的顺序的几个变体。这是代码:Python Tkinter画布不出现

from tkinter import * 
from tkinter.ttk import * 
import cells 

GRID_WIDTH = 15 
GRID_HEIGHT = 15 


class Ui(Frame): 
    """ Class to represent the ui of conways game of life""" 

    def __init__(self, parent, grid): 
     self.parent = parent 
     self.grid = grid 
     Frame.__init__(self, parent) 
     self.__setup() 

    def __setup(self): 
     """ Method to setup the components of the ui """ 
     self.parent.title("Conway's game of life") 
     self.pack() 

     #Setup a frame to hold control components 
     frame_cntrl = Frame(self) 
     frame_cntrl.pack(side = RIGHT, anchor="n") 
     self.__setup_cntrl_components(frame_cntrl) 

     #Setup a frame to hold the Grid 
     self.canvas = Canvas(self) 
     self.canvas.pack(side = LEFT) 
     self.__draw_grid() 
     self.canvas.bind("<Button-1>", self.__canvas_clicked) 


    def __setup_cntrl_components(self, parent): 
     """ Method to setup the control elements of the ui""" 
     #Setup a label for the generation 
     self.lb_generation = Label(parent, text="dummy") 
     self.lb_generation.pack(side = TOP) 

     #Setup a button for iteration 
     self.bt_iteration = Button(parent, text="Iterate") 
     self.bt_iteration.pack(side = TOP) 



    def __draw_cell(self, x, y): 
     """ Draws a cell on the canvas""" 
     width, height = self.canvas.winfo_width(), self.canvas.winfo_height() 
     color = "black" if self.grid.cell_alive(x, y) else "white" 
     x0 = width * x/self.grid.width + 1 
     x1 = width * (x + 1)/self.grid.width 
     y0 = height * y/self.grid.height + 1 
     y1 = height * (y + 1)/self.grid.height 
     self.canvas.create_rectangle(x0, y0, x1, y1, width=0, fill=color) 

    def __draw_grid(self): 
     """ Method to setup the grid itself""" 
     width, height = self.canvas.winfo_width(), self.canvas.winfo_height() 
     for i in range(0, self.grid.width): 
      for j in range(0, self.grid.height): 
       self.__draw_cell(i, j) 


    def __canvas_clicked(self, event): 
     """ Method for when the cell was clicked """ 
     x, y, width, height = event.x, event.y, self.canvas.winfo_width(), self.canvas.winfo_height() 
     cell_x = int(x/width * self.grid.width) 
     cell_y = int(y/height * self.grid.height) 
     self.grid.switch_cell(cell_x, cell_y) 
     self.__draw_cell(cell_x, cell_y) 




if __name__ == "__main__": 
    Ui(Tk(), cells.Grid(GRID_WIDTH, GRID_HEIGHT)).mainloop() 

问题1

你的主要问题是,实际上是显示在画布前,canvas.winfo_width()canvas.winfo_height()不返回画布宽度和高度,但价值1

我建议你创建画布如下:与

width, height = self.canvas_width, self.canvas_height 

问题2

width, height = self.canvas.winfo_width(), self.canvas.winfo_height() 

# Define canvas and save dimensions 
self.canvas_width = 300 
self.canvas_height = 200 
self.canvas = Canvas(self, width = self.canvas_width, 
          height = self.canvas_height) 

然后,在你的代码,更换的每个实例:

创建每个单元格时,我认为您不需要将1添加到x0y0。相反,它应该是:

x0 = width * x/self.grid.width 
x1 = width * (x + 1)/self.grid.width 
y0 = height * y/self.grid.height 
y1 = height * (y + 1)/self.grid.height 
+0

在画布实际显示在屏幕上之前,FWIW'winfo_width()'和'winfo_height()'只返回1。一旦显示,它将返回实际值。在此之前,tkinter无法确定大小,因为它取决于pack/place/grid选项。 –

+0

谢谢@Bryan,我已经更新了答案以澄清这一点! – Josselin