プロが教える店舗&オフィスのセキュリティ対策術

Python初心者です。tkinterとcanvasで
次のように物理の斜方投射のプログラムを書き、
画面右上に座標(x,y)の値が刻々と変わるように表示させたくて、
def update_label():
position_label.config(text=f'Position: ({x}, {y})')
window.after(10, update_label)


# 目盛り線を描画 draw_scale_lines()の前に、
 update_label()

そして、
update_label()
window.mainloop()

のようにwindow.mainloop()の前にもupdate_label()を呼び出すようにしたのですが、

実行するとコマンドプロンプトが一瞬立ち上がってすぐに落ちてしまいます。
どこをどう直せば良いでしょうか?
ある時刻tの、そのときのボールの座標(x,y)が画面のどこかに表示されるようにしたいです。
インデントはdef move():から
WIDTH, HEIGHT = 800, 600
の前まで入っています。
よろしくお願いします。


import tkinter
import math

def move():
global x, y, vy, t

# ボールの新しい位置を計算
if 0 <= x and x <= WIDTH and 0 <= y and y <= HEIGHT:
x = x0 + v0*math.cos(degrees * math.pi/180) *t
y = y0+ v0*math.sin(degrees * math.pi/180) *t-(g/2)*t**2
t = t + dt
else:
x = x0
y = y0
t = t0

def update_label():
position_label.config(text=f'Position: ({x}, {y})')
window.after(10, update_label)

# ボールの位置を更新
canvas.coords('ball', x-MARGIN, (HEIGHT-y)-MARGIN, x+MARGIN, (HEIGHT-y)+MARGIN)
canvas.coords('ball1', x1-MARGIN, (HEIGHT-y1)-MARGIN, x1+MARGIN, (HEIGHT-y1)+MARGIN)

  update_label()
# 目盛り線を描画
draw_scale_lines()

window.after(50, move) # 10ミリ秒ごとにmove関数を呼び出す

def draw_scale_lines():
# 目盛り線を描画
for i in range(1, WIDTH // 10 + 1):
x_pos = i * 10
canvas.create_line(x_pos, 0, x_pos, HEIGHT, fill='#d2d2d2')

for i in range(1, HEIGHT // 10 + 1):
y_pos = i * 10
canvas.create_line(0, y_pos, WIDTH, y_pos, fill='#d2d2d2')


WIDTH, HEIGHT = 800, 600
MARGIN = 10

t0 = 0.0
dt = 0.1
g = 9.8

v0 = float(input('初速度(m/s)を入力してください'))
degrees = float(input('角度(度)を入力してください'))

theta = degrees * math.pi / 180
vx0 = v0 * math.cos(theta)
vy0 = v0 * math.sin(theta)
x0 = 10
y0 = 2 * HEIGHT / 4
x1 = 250
y1 = HEIGHT / 2
x = x0 * WIDTH
y = y0 * HEIGHT
vy = vy0 * HEIGHT
t = t0

geo_str = str(WIDTH+MARGIN*2) + 'x' + str(HEIGHT+MARGIN*2)
window = tkinter.Tk()
window.geometry(geo_str)
window.title('moving')

canvas = tkinter.Canvas(window, width=WIDTH, height=HEIGHT, bg='white')
canvas.place(x=MARGIN, y=MARGIN)
canvas.create_oval(x-MARGIN, (HEIGHT-y)-MARGIN, x+MARGIN, (HEIGHT-y)+MARGIN, fill='red', outline='', tags='ball')
canvas.create_oval(x1-MARGIN, (HEIGHT-y1)-MARGIN, x1+MARGIN, (HEIGHT-y1)+MARGIN, fill='gray', outline='', tags='ball1')

move()

update_label()
window.mainloop()

質問者からの補足コメント

  • 一応自己解決しました、有難うございました。
    またの機会にはよろしくお願いします。
    プログラムのやりとりはideoneでやりとりするのが良いようですね。

    https://ideone.com/TiuS8m

      補足日時:2023/06/05 14:13

A 回答 (2件)

ここではスペースやタブのインデントは無視されてしまうので


インデントがわからずきついです。

インデントを全角スペースとかに変換しといてもらえると
こちらで再変換してテストできるんですが・・・

またエラーが起きるとコンソールにいろいろエラーメッセージが
残るはずですが、出てないでしょうか?
ひょっとして Explorer から 直接 pythonソースをダブルクリック
してる?

コマンドプロンプトから起動することをお勧めします。

ソースの気になる点2点。

update_labelの中でupdate_labelを呼んでいるような
気がしますが気のせいでしょうか?
stack overflow で落ちると思います。


position_label って、中身を入れてるコードが
見当たらないですね。NameError例外で落ちると思います。
    • good
    • 0

あ〜、ひょっとして。


シバン抜けてない?

UNIX流儀なんだけど、ファイルの冒頭に

#! /usr/bin/env python3

とか書く。
以前は違ったんだけど、今だとWindows版PythonでもこれでパスからPythonを探せるようになった。
んで、ひょっとしたらWindowsでは

#! /usr/bin/env python

かもしんない。
DOS窓からPython立ち上げる時、"python"なのか"python3"でどっちかなのか分かる。
(多分Windowsだったら"python"だったように記憶してるけど・・・)

あと、position_labelが未定義だ。
「Pythonによる物理の斜方投射の位置座」の回答画像2
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!