PR

【第8.5回】Pythonでモーター制御GUIを作るときのThreadの使い方(GUIが固まる理由を解説)(XYテーブル製作シリーズ)

スポンサーリンク
RaspberryPi
スポンサーリンク

はじめに

第8回では、PythonのGUI(Tkinter)から
XYテーブルを操作できるようになりました。

  • 移動量入力
  • XY同時制御
  • 緊急停止

とりあえず動かしました
しかし実際の装置では

しかし、ここで多くの人が疑問に思います。
なぜ Thread を使う必要があるのでしょうか?
もし Thread を使わないと、
GUIは簡単に 固まってしまいます。

今回は「GUIが固まる原因と、Threadによる解決方法」を解説します。

スポンサーリンク

GUIプログラムの仕組み

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

イメージ

イベント待ち

ボタンが押された?

処理実行

画面更新

イベント待ち

この処理は 1つのスレッドで動いています。

これを

GUIメインスレッド

と呼びます。

スポンサーリンク

GUIが固まる原因

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

def start_xy():
run_motor()

モーター制御は次のような処理です。

forループ

GPIO制御

time.sleep()

数千回繰り返す

この処理は数秒〜数十秒かかります。

問題はここです。

この処理は

GUIスレッドで実行されます。

つまり

GUIスレッド

モーター処理

イベント処理停止

結果

画面更新されない
ボタン押せない
ウィンドウ動かない

つまり

GUIが固まる
スポンサーリンク

Threadで解決する

そこで使うのが

threading.Thread

です。

Threadを使うと
モーター処理を 別スレッドで実行できます。

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

すると処理はこう分かれます。

GUIスレッド

画面更新
ボタン操作モータースレッド

GPIO制御
ステップループ

つまり

GUIは操作可能
モーターは裏で動く

という状態になります。

Threadなし
GUI

モーター処理

GUI停止
Threadあり
GUIスレッド

画面更新
ボタン操作モータースレッド

モーター制御
スポンサーリンク

XY同時制御にもThreadが必要

XYテーブルでは
2軸を同時に動かす必要があります。

その場合

XモーターThread
YモーターThread

を作ります。

イメージ

Thread X → Xモーター
Thread Y → Yモーター

これで XY同時移動ができます。

スポンサーリンク

しかしThreadにも問題がある

Threadには問題もあります。

それは

GUIとThreadの通信

です。

例えば

  • 現在位置表示
  • エラー表示
  • 動作完了通知

などです。

GUIスレッド以外から
直接GUIを操作すると

エラー

になることがあります。

解決方法:Queue

そのため次の方法を使います。

queue.Queue()

仕組み

モータースレッド

Queueにメッセージ送る

GUIスレッド

メッセージ受信

画面更新

これは

Python GUI設計の定番パターン

です。

スポンサーリンク

まとめ

今回解説した内容

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

さらに

  • Thread通信にはQueueを使う

という設計になります。

スポンサーリンク

次回予告(第9回)

次回は、XYテーブルを
装置として完成させます。

追加する機能

  • 原点復帰GUI
  • 現在位置表示
  • ソフトリミット

これで

本格的なXYテーブルコントローラ

になります。

コメント