简体   繁体   English

Python Tkinter Canvas不会出现

[英]Python Tkinter Canvas does not appear

Hello I got a problem with using the Tkinter package on python. 你好我在python上使用Tkinter包有问题。 I want to create a window containing two major widgets of which one is a canvas that will later show a grid with cells. 我想创建一个包含两个主要小部件的窗口,其中一个是一个画布,稍后将显示带有单元格的网格。 When initializing the canvas I use "create_rectangle" to fill the canvas with the desired objects. 在初始化画布时,我使用“create_rectangle”来用所需的对象填充画布。 Also when clicking on a cell (for testing reasons) the canvas should change its color in the area of the rectangle. 此外,当单击一个单元格(出于测试原因)时,画布应该在矩形区域中更改其颜色。 However when initialy displaying the window at first no objects can be seen (the expected result would be only white colored rectangles) and only when a Click on the canvas is performed the area changes its color as desired. 然而,当首先初始显示窗口时,不能看到任何对象(预期结果将只是白色矩形),并且仅当执行对画布的单击时,该区域根据需要改变其颜色。 While looking through the internet I tried several variations of the order of the pack()- and create_rectangle()-methods. 在浏览互联网时,我尝试了pack() - 和create_rectangle() - 方法的几种变体。 This is the code: 这是代码:

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

Problem 1 : 问题1

Your main problem is that, before the canvas is actually displayed, canvas.winfo_width() and canvas.winfo_height() do not return the canvas width and height, but the value 1 . 您的主要问题是,在实际显示画布之前, canvas.winfo_width()canvas.winfo_height()不返回画布宽度和高度,而是返回值1

I suggest you create the canvas as follows: 我建议您按如下方式创建画布:

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

Then, in your code, replace each instance of: 然后,在您的代码中,替换每个实例:

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

with

width, height = self.canvas_width, self.canvas_height

Problem 2: 问题2:

When creating each cell I don't think you need to add 1 to x0 and y0 . 在创建每个单元格时,我认为您不需要将1添加到x0y0 Instead, it should be: 相反,它应该是:

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