繁体   English   中英

Python Tkinter Canvas不会出现

[英]Python Tkinter Canvas does not appear

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

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

我建议您按如下方式创建画布:

# 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)

然后,在您的代码中,替换每个实例:

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

width, height = self.canvas_width, self.canvas_height

问题2:

在创建每个单元格时,我认为您不需要将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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM