いろいろ試してみて分かったことは、

```

    line 19: if self.position[3] >= self.canvas_height:
    
```

でなにかしらの問題が起きていることです。  
`self.canvas_height`を500に変えたところうまくいきましたが、それは私が本当にしたいことと外れています。

あくまでも、`winfo_height`を使い解決したいです。  
もう一つ分かっていることは`self.canvas_height`をprintすると1とでてくることです。ここがなぜ500ではなく、1とでてきてしまうのでしょうか？

Q1. 赤いボールを上下させるにはどうすればいいのか。  
Q2.
なぜ`self.canvas_height`をprintすると1とでてくるのか。Canvasですでに`height=500`と書いているのになぜ1になってしまうのか。

Q2が解決できればQ1も解決できると思っています。わかる方よろしくお願いします。

```

    import tkinter
    import time
    
    class Ball:
        def __init__(self, canvas, color):
            self.canvas = canvas
            self.id = self.canvas.create_oval(10,10,25,25, fill=color)
            self.canvas.move(self.id, 250, 150)
            self.canvas_height = self.canvas.winfo_height()
            self.x = 0
            self.y = 1
            print(self.canvas_height)
        
        def draw(self):
            self.canvas.move(self.id, self.x, self.y)
            self.position = self.canvas.coords(self.id)
            if self.position[1] <= 0:
                self.y = 1
            if self.position[3] >= self.canvas_height:
                self.y = -1
            
    
    
    root = tkinter.Tk()
    root.minsize(width=500, height=500)
    root.resizable(0,0)
    canvas = tkinter.Canvas(width=500, height=500)
    canvas.place(x=0, y=0)
    
    ball = Ball(canvas, "red")
    while True:
        ball.draw()
        canvas.update()
        time.sleep(0.01)
    
    root.mainloop()
    
```
CC BY-SA 4.0
2020-08-12T10:13:44.247
69485
2020-08-13T05:51:22.263
2020-08-12T13:16:16.043
41421
question
python
pythonで赤い球をcanvas上で上下するコードを書きたいのですが以下のコードだと球が上の壁を突き抜けて画面から消えてしまいます。何を変えればいいのでしょうか。winfo_height関数をつかってつくりたいです。
> self.canvas_height = self.canvas.winfo_height() の直前で self.canvas.update()
> を実行する必要があります(widget の geometry configuration が実行されて height などの property
> が確定します)。

metropolisさんのコメントのとおり、`self.canvas_height = self.canvas.winfo_height()` の直前に
`self.canvas.update()`を挿入すると赤い玉がウィンドウの上下で反射するようになりました。

```

    import tkinter
    import time
    
    class Ball:
        def __init__(self, canvas, color):
            self.canvas = canvas
            self.id = self.canvas.create_oval(10,10,25,25, fill=color)
            self.canvas.move(self.id, 250, 150)
            self.canvas.update() 
            self.canvas_height = self.canvas.winfo_height()
            self.x = 0
            self.y = 1
            print(self.canvas_height)
        
        def draw(self):
            self.canvas.move(self.id, self.x, self.y)
            self.position = self.canvas.coords(self.id)
            if self.position[1] <= 0:
                self.y = 1
            if self.position[3] >= self.canvas_height:
                self.y = -1
    
    root = tkinter.Tk()
    root.minsize(width=500, height=500)
    root.resizable(0,0)
    canvas = tkinter.Canvas(width=500, height=500)
    canvas.place(x=0, y=0)
    
    ball = Ball(canvas, "red")
    while True:
        ball.draw()
        canvas.update()
        time.sleep(0.01)
    
    root.mainloop()
    
```
CC BY-SA 4.0
2020-08-13T05:51:22.263
69510
2020-08-13T05:51:22.263
35558
69485
answer