2017-05-07 78 views
0

こんにちは、PythonでTkinterパッケージを使用する際に問題が発生しました。私は2つの主要なウィジェットを含むウィンドウを作成したいのですが、その1つは後でセルを持つグリッドを表示するキャンバスです。キャンバスを初期化するとき、私は "create_rectangle"を使ってキャンバスに目的のオブジェクトを塗りつぶします。また、セルをクリックすると(テストのために)、キャンバスは矩形の領域内の色を変更する必要があります。しかし、最初にオブジェクトを表示していない初期状態では、オブジェクトが表示されず(期待される結果は白い色の矩形のみになります)、キャンバスのクリックが実行されたときにのみ、領域の色が変更されます。 インターネットを見渡しながら、pack() - とcreate_rectangle() - メソッドのいくつかのバリエーションを試しました。これはコードです:Python Tkinter Canvasが表示されない

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

答えて

0

問題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を返します。表示されると、実際の値が返されます。これまでは、pack/place/gridオプションに依存しているため、tkinterはサイズを判別できませんでした。 –

+0

ありがとう@ブライアン、私はこの点を明確にするための答えを更新しました! – Josselin

関連する問題