質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Anaconda

Anacondaは、Python本体とPythonで利用されるライブラリを一括でインストールできるパッケージです。環境構築が容易になるため、Python開発者間ではよく利用されており、商用目的としても利用できます。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

2回答

738閲覧

pythonでwhileによる無限ループが実行されない。

ppap

総合スコア68

Anaconda

Anacondaは、Python本体とPythonで利用されるライブラリを一括でインストールできるパッケージです。環境構築が容易になるため、Python開発者間ではよく利用されており、商用目的としても利用できます。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2022/08/31 14:31

前提

pythonのtkinterおよびpillowを用いて、クリックにより画像を回転させるコードを作成しています。
tag_bindで無限ループを実行するイベントを呼び出そうとしていますが、無限ループが実行されません。

実現したいこと

tag_bindで「クリックにより、1秒ごとに5°ずつ画像を左回転させる」イベントを呼び出したいと考えています。
後から「再度クリックすることで無限ループから脱出するコード」を追記する予定ですが、まずは無限ループを実行することを目標としています。

エラーメッセージは無く、どのように修正すると上手く動作するのかが分からないので教えていただけないでしょうか。

該当のソースコード

python

1#---測定コード--- 2 3import tkinter as tk 4from PIL import Image, ImageTk 5import time 6 7 8#画面サイズの指定 9WIDTH = 1300 10HEIGHT = 800 11 12 13#新規ウィンドウを作成 14root = tk.Tk() 15root.title("SVV測定") 16root.attributes("-fullscreen", True) 17 18 19#ウィンドウ上にフレームを作成 20frame = tk.Frame(root) 21frame.pack() 22 23 24#フレーム上に、キャンバスを作成 25canvas = tk.Canvas(frame, width = WIDTH, height = HEIGHT, bg = "black") 26canvas.pack() 27 28 29#画像のプリセット角を"cs"として定義 30cs = 0 31 32 33#キャンバスにSVV画像を貼り付け 34img = Image.open("D:\EXPERIMENT\programming\Python\SVV\svv_bar.png") 35img = img.rotate(cs) 36tkimg = ImageTk.PhotoImage(img, width = WIDTH, height = HEIGHT) 37canvas.create_image(WIDTH/2, HEIGHT/2, image=tkimg, anchor="center", tags="img") 38 39 40#キャンバスに、透明な画像を貼り付け 41img_snow = Image.open("D:\EXPERIMENT\programming\Python\SVV\svv_snow.png") 42tkimg_snow = ImageTk.PhotoImage(img_snow, width = WIDTH, height = HEIGHT) 43canvas.create_image(WIDTH/2, HEIGHT/2, image=tkimg_snow, anchor="center", tags="img_snow") 44 45 46#"c"の初期値を定義 47c = 0 48 49 50#イベントが発生したときの処理 51def press_L(event): 52 #左クリックの回数によって、左回転させる 53 while True: 54 time.sleep(1) 55 global img 56 global tkimg 57 global c 58 c = c + 5 59 IMG = img.rotate(c) 60 tkimg = ImageTk.PhotoImage(IMG) 61 canvas.create_image(WIDTH/2, HEIGHT/2, image = tkimg, anchor = "center", tags = "img") 62 canvas.create_image(WIDTH/2, HEIGHT/2, image=tkimg_snow, anchor = "center", tags="img_snow") 63 64 65def press_R(event): 66 #右クリックの回数によって、右回転させる 67 global img 68 global tkimg 69 global c 70 c = c - 5 71 IMG = img.rotate(c) 72 tkimg = ImageTk.PhotoImage(IMG) 73 canvas.create_image(WIDTH/2, HEIGHT/2, image = tkimg, anchor = "center", tags = "img") 74 canvas.create_image(WIDTH/2, HEIGHT/2, image=tkimg_snow, anchor = "center", tags="img_snow") 75 76 77def finish(event): 78 #Enterキーを押すことで全画面表示を終了し、回転角度を取得する 79 root.destroy() 80 print(c) 81 82 83#左クリックで呼び出すイベント 84canvas.tag_bind("img_snow", "<ButtonPress-1>", press_L) 85 86#右クリックで呼び出すイベント 87canvas.tag_bind("img_snow", "<ButtonPress-3>", press_R) 88 89 90#Enterキーで呼び出すイベント 91root.bind("<Return>", finish) 92 93 94#メインループ 95root.mainloop() 96

上記の処理に使用した画像を作成するコード

python

1#---SVV測定に使用する画像の作成--- 2 3from PIL import Image, ImageDraw 4 5#背景色が黒色のキャンパスを作成。 6im = Image.new('RGB', (500, 500), (0, 0, 0)) 7draw = ImageDraw.Draw(im) 8 9 10#中央に線を描画 11draw.line((50, 250, 450, 250), fill=(255, 255, 255), width=10) 12 13 14#同じサイズの画像を作成 15im_clear = Image.new("RGBA", im.size, (0, 0, 0, 0)) 16width = im.size[0] 17height = im.size[1] 18 19 20#色ごとに処理 21for x in range(width): 22 for y in range(height): 23 pixel = im.getpixel( (x, y) ) 24 25 # 黒なら処理しない 26 if pixel[0] == 0 and pixel[1] == 0 and pixel[2] == 0: 27 continue 28 29 # 黒以外なら、用意した画像にピクセルを書き込み 30 im_clear.putpixel( (x, y), pixel ) 31 32 33#SVVで表示させるバーをpng形式で保存 34im_clear.save("D:\EXPERIMENT\programming\Python\SVV\svv_bar.png", quality=100) 35 36 37 38#---透明なpng画像の作成--- 39 40#画像サイズの指定 41WIDTH = 1500 42HEIGHT = 1000 43 44 45#新しい画像を作成 46im_snow = Image.new("RGBA", (WIDTH, HEIGHT), (0, 0, 0, 0)) 47 48 49#新しい画像をもう一つ作成 50im_snow2 = Image.new("RGBA", (WIDTH, HEIGHT), (0, 0, 0, 0)) 51 52 53#色ごとに処理 54for x in range(width): 55 for y in range(height): 56 pixel = im_snow2.getpixel( (x, y) ) 57 58 # 黒なら処理しない 59 if pixel[0] == 0 and pixel[1] == 0 and pixel[2] == 0: 60 continue 61 62 # 黒以外なら、用意した画像にピクセルを書き込み 63 im_snow.putpixel( (x, y), pixel ) 64 65 66#透明な画像をpng形式で保存 67im_snow.save("D:\EXPERIMENT\programming\Python\SVV\svv_snow.png", quality=100) 68

試したこと

以下のようなコードをコードの中に含めて、クリックで呼び出したところ問題なく実行されました。

python

1 2def sample(event): 3 while True: 4 time.sleep(1) 5 global c 6 c = c + 5 7 print(c) 8 9#5 10#10 11#15 12#20 13#25 14#30 15#と、5ずつ増えながらカウントされます。

補足情報(FW/ツールのバージョンなど)

AnacondaでPythonを使用しています。

・Anacondaのバージョン:conda 4.12.0
・Pythonのバージョン:Python 3.9.12
・Windowsのバージョン:version 21H2

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

while、sleepの代わりに、root.after を使用します。

python

1#イベントが発生したときの処理 2def press_L(event): 3 #左クリックの回数によって、左回転させる 4 #while True: # 削除 5 # time.sleep(1) # 削除 6 global img 7 global tkimg 8 global c 9 c = c + 5 10 IMG = img.rotate(c) 11 tkimg = ImageTk.PhotoImage(IMG) 12 canvas.create_image(WIDTH/2, HEIGHT/2, image = tkimg, anchor = "center", tags = "img") 13 canvas.create_image(WIDTH/2, HEIGHT/2, image=tkimg_snow, anchor = "center", tags="img_snow") 14 root.after(1000,press_L, None) # 追加 15 16 17

投稿2022/08/31 20:21

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ppap

2022/09/01 01:48

ありがとうございます。 目指していた処理を行うことができました。
ppap

2022/09/06 07:55

先日は回答を頂き、ありがとうございました。 こちらは、なぜ「while、sleepの代わりに、root.after を使用する」必要があったのでしょうか? お手数ですが、ご教授頂けますと幸いです。
退会済みユーザー

退会済みユーザー

2022/09/13 14:57

sleepだとメインスレッドを止めてしまいます。メインスレッドが止まると、描画自体が止まってしまいますので意図した動作になりません。 一方、root.after は 「指定した秒数後に指定した関数を実行させるよう登録する」処理ですのでメインスレッドを止めることはありません。(指定した秒数経過後に自動的に実行するようスケジューリングされ、それ以外の時間は描画や他の処理に使えるので、動作がストップしません)
guest

0

ありがとうございます。
目指していた処理を行うことができました。

投稿2022/09/01 01:47

ppap

総合スコア68

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問