PR

PythonのGUIが固まる理由とThreadの使い方【XYテーブル自作 第8.5回】

RaspberryPi
スポンサーリンク

はじめに

XYテーブル製作シリーズ 第8.5回

スポンサーリンク

はじめに:なぜ Thread を使う必要があるのか

第8回でTkinterのGUIからXYテーブルを操作できるようになりました。しかし、なぜ Thread を使う必要があるのでしょうか? Thread を使わないと、GUIは簡単に固まってしまいます。今回はその理由と、Threadによる解決方法を解説します。

この記事で分かること

  • GUIは「イベントループ」で動いていて、それは1つのメインスレッドで回っている
  • 時間のかかるモーター処理を同じスレッドで実行するとイベント処理が止まる=GUIが固まる
  • threading.Thread でモーター処理を別スレッドに逃がすとGUIが止まらない
  • ThreadからGUIを直接触るとエラーになるので queue.Queue で通信する(定番パターン)

スポンサーリンク

GUIプログラムの仕組み(イベントループ)

Tkinterなどの GUI はイベントループで動いています。

イベント待ち → ボタンが押された? → 処理実行 → 画面更新 → イベント待ち …

この処理は1つのスレッド(GUIメインスレッド)で回っています。

スポンサーリンク

GUIが固まる原因

ボタンを押したときにモーター制御を直接実行するとします。

def start_xy():
    run_motor()   # forループ → GPIO制御 → time.sleep() を数千回

この処理は数秒〜数十秒かかります。しかもGUIメインスレッドで実行されるため、その間イベント処理が止まります。

GUIスレッド → モーター処理(長時間)→ イベント処理停止
→ 画面更新されない・ボタン押せない・ウィンドウ動かない = GUIが固まる

スポンサーリンク

Threadで解決する

そこで threading.Thread を使い、モーター処理を別スレッドで実行します。

threading.Thread(
    target=run_motor,
    args=(...)
).start()

すると処理が分かれます。

  • GUIスレッド:画面更新・ボタン操作を受け付け続ける
  • モータースレッド:裏でGPIO制御・ステップループを回す

結果、GUIは操作可能なまま、モーターは裏で動く状態になります。

スポンサーリンク

XY同時制御にもThreadが必要

XYテーブルでは2軸を同時に動かします。XモーターThreadYモーターThread を作れば、XY同時移動ができます。


スポンサーリンク

Threadの問題:GUIとの通信

Threadには問題もあります。GUIスレッド以外から直接GUIを操作するとエラーになることがあるのです(現在位置表示・エラー表示・完了通知など)。

解決方法:queue.Queue

message_queue = queue.Queue()

# モータースレッド側:メッセージを送るだけ
message_queue.put(("pos", axis, current_mm))

# GUIスレッド側:root.after で定期的に取り出して画面更新

モータースレッドは Queue にメッセージを入れるだけ、GUIスレッドが Queue から取り出して画面を更新する——これが Python GUI設計の定番パターンです。実装は第9回で行います。


スポンサーリンク

まとめと次回予告

  • GUIはイベントループ(1メインスレッド)で動く
  • モーター処理は時間がかかる → 同じスレッドで実行するとGUIが固まる
  • Threadを使うとGUIが止まらない
  • Thread → GUI の通信には Queue を使う

次回・第9回では、この設計を踏まえて原点復帰GUI・現在位置表示・ソフトリミットを実装し、本格的なXYテーブルコントローラにします。

次に読む記事

🏠 次回はこちら(第9回) XYテーブルGUIに原点復帰・現在位置表示・ソフトリミットを実装|Queueでスレッド安全にGUI更新 Queueパターンを実際に実装する。 🖥️ 前回(第8回) PythonのTkinterでXYテーブルをGUI操作する|移動量入力・XY同時実行・緊急停止ボタン GUIの土台になったコード。 🗺️ 全体像 自作XYテーブルの全手順ロードマップ|Raspberry Pi+ステッピングモーターで2軸制御 第0回〜第11回の全工程をまとめたロードマップ。

スポンサーリンク

よくある質問(FAQ)

Qtime.sleep をやめれば Thread なしでもGUIは固まりませんか?

Atime.sleep 中もループ自体がGUIメインスレッドを占有するので、sleepを短くしても数千回のステップ出力の間GUIは固まります。root.update() を挟む方法もありますが、応答が不安定になりがちで、別スレッド化のほうが素直です。

Qthreading と multiprocessing はどちらを使うべきですか?

AGPIO制御やtime.sleep主体の待ち処理は threading で十分です(GILの影響が小さい)。CPUをフルに使う重い計算を並列化したいときだけ multiprocessing を検討します。XYテーブル制御は threading が定番です。

QThreadからGUIを直接更新したらたまたま動きました。

ATkinterはスレッドセーフではなく、別スレッドからのGUI操作は「動くこともあるが、たまにクラッシュ・フリーズする」不安定な状態です。queue.Queue + root.after でメインスレッドに処理を戻すのが安全です。

Q緊急停止はThreadをどう止めればいいですか?

APythonのスレッドは外部から強制終了できません。グローバルなフラグ(stop_flag = True)を立て、モーターループが毎回それをチェックして return する「協調的キャンセル」を使います。あわせて GPIO.output(EN, HIGH) で電流も切ります。


スポンサーリンク

XYテーブル製作シリーズ(全12回)

補足記事

第1.5回・補足 A4988の電流制限(Vref)調整方法|焼損を防ぐ計算式とテスターでの設定手順 モーターを回す前に必ずやる A4988 の電流調整。 🔀 番外編 L6470が動かない原因|A4988との違いとSPI通信・デイジーチェーンの罠 高機能ドライバ L6470 を A4988 と同じ感覚で使ってハマった話。 🗺️ 全体像 自作XYテーブルの全手順ロードマップ|Raspberry Pi+ステッピングモーターで2軸制御 第0回〜第11回の全工程をまとめたロードマップ。

ニンジン🥕アイコン

Follow me on X

本ブログの中の人「ニンジン🥕」はXやってます。新着記事はいち早くポストでお知らせしているので、見逃したくない方は @ninjin_py_vba をフォローしてみてください🥕

@ninjin_py_vba をフォロー

この記事が役に立ったら、シェアしてもらえると嬉しいです🥕

Xでポスト はてブ LINE Pocket

PROJECT LOG — SERIES INDEX
スポンサーリンク

シリーズ記事一覧

電子工作・自動化ツールの製作記録をシリーズごとにまとめています。気になるテーマからお読みください。


超音波距離センサーHC-SR04をRaspberry Pi Picoで使う|仕組み・配線・精度検証
.uds1-block { position: relative; overflow: hidden; border-radius: 12px; border: 1px solid #f0cba8; background: linear-g…
今週の注目ガジェット〜09/07週〜|電子工作・自作向け新製品まとめ(TickrCast/Radxa Linkr ほか)
ニンジンのガジェット通信 09/07週。ESP32-P4の自作気象モニター、極小IP-KVM「Radxa Linkr」、ESP32のDINレール型PLC、LTE開発キットなど、電子工作で使えそうな新製品5つを解説。
サーボモータの角度をタクトスイッチで可変|OLED(SSD1306)に現在角度をリアルタイム表示
Raspberry Pi Pico 2W×MG996RにタクトスイッチとOLED(SSD1306)を追加。ボタンで角度を可変しながら現在角度をリアルタイム表示するMicroPython実装を、framebufの文字拡大やサーボの遊び対策まで実機ベースで解説します。
MG996RサーボモーターをRaspberry Pi Pico 2Wで動かす:PWM制御とキャリブレーション実践
MG996RサーボモーターをRaspberry Pi Pico 2Wで動かす方法を解説。公称180度のはずが実測198度だった個体差の原因究明から、ホーンのズレ補正、タクトスイッチでの角度制御まで実機検証の様子を紹介します。
Tapo P110Mの消費電力をExcelレポート化する【年次集計・電気代試算・セキュリティ判断編】
FastAPI+openpyxlでTapo P110Mの消費電力をExcelレポート化。15秒間隔の生ログを日次集計する設計や、31円/kWhでの電気代試算、外部公開を見送った理由まで解説します。

コメント