🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
Tkinter

Tkinterは、GUIツールキットである“Tk”をPythonから利用できるようにした標準ライブラリである。

Python

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

Q&A

解決済

3回答

3374閲覧

pythonで実行中の別ソースをGUIでボタン操作でキャンセルする対応

juster1

総合スコア1

Tkinter

Tkinterは、GUIツールキットである“Tk”をPythonから利用できるようにした標準ライブラリである。

Python

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

0グッド

0クリップ

投稿2021/03/04 00:33

編集2021/03/04 02:06

前提・実現したいこと

pythonで実行中のプログラムをtkinterなどで作成したGUIのボタン押下でキャンセルしたいのですが、GUIから他のプログラムに干渉する方法がわかりません。

試したこと

キャンセルしたいプログラムにGUIをそのまま組み込むとGUIの実行部分で止まってしまうので、並列処理をしなければならないことは分かったのですが、別々に動いてるプログラムを互いに干渉させる方法が分からなくて困っております。

version

python 3.6.8

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

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

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

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

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

退会済みユーザー

退会済みユーザー

2021/03/04 01:32

Pythonのバージョンを提示してください。
juster1

2021/03/04 01:44

バージョンは3.6.8です。
退会済みユーザー

退会済みユーザー

2021/03/04 01:52

質問に追記してください。 みんながコメントまで読むとは限りませんので。
guest

回答3

0

えっと、ものすごく変な方法で良ければ、こんなふうにかけます。
追記:...すみません質問をちゃんと読んでませんでした...無視してください.......

python3

1import tkinter 2import threading 3import time 4 5class threadingLabel(): 6 def __init__(self, master): 7 self.master = master 8 self.label = tkinter.Label(root) 9 self.num = 0 10 self.stop =0 11 self.pack = self.label.pack 12 def _thread(self): 13 if not self.stop: 14 self.num+=1 15 self.label.configure(text=str(self.num)) 16 time.sleep(1) 17 def start(self): 18 self.stop = 0 19 self.num= 0 20 self.thread=threading.Thread(target=self._thread) 21 self.start() 22 def stop(self): 23 self.stop = 1 24 25root = tkinter.Tk() 26root.title("thread_test") 27tl = threadingLabel() 28t1.pack() 29b = tkinter.Button(root, text="stop", command = t1.stop) 30b.pack() 31t1.start() 32root.mainloop()

...突貫工事ですみません....
本当は、ちゃんとlabelを継承すべきなのですが...
必要でしたら、書き直します...

投稿2021/03/07 06:01

編集2021/03/07 06:09
Marusoftware

総合スコア189

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

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

0

ベストアンサー

真剣に並列処理を勉強したいのであれば、teamiklが書かれているような勉強をしてください。

手早く実現したいのであれば、プロセスとシグナルで実行する方法よりも、スレッドを使えば、メモリを共有しているのでフラグを決めておいて親スレッドがフラグに書き込み、子スレッドがときどきフラグをチェックして終了するというのが最も簡単です。子スレッド側はフラグに書き込まないので排他制御も必要ありません。

処理が単純なループならば、以下のようにして実現することが出来ます。

python

1import tkinter as tk 2import threading 3import time 4 5app = tk.Tk() 6frame = tk.Frame(master=app) 7frame.pack() 8 9LIVE = True 10 11def hello(): 12 try: 13 while True: 14 print('Hello') 15 time.sleep(1) 16 if LIVE == False: 17 raise(Exception) 18 except: 19 print("Don't kill me!!") 20 21def stop(): 22 global LIVE 23 LIVE = False 24 app.destroy() 25 26btn_stop = tk.Button(frame) 27btn_stop["text"] = "Cut, cut, cut, blood, spurt" 28btn_stop["command"] = stop 29btn_stop.pack(side="top") 30 31thread1 = threading.Thread(target=hello) 32thread1.start() 33 34app.mainloop() 35 36thread1.join()

これを実行すると、thread1はターミナルに対して1秒ごとにHelloを表示し続けます。
親スレッドはtkinterを使ってボタンを表示します。tkinterのボタンを押すと、関数stopが呼び出されてフラグであるLIVEをFalseに変更します。
すると、次のタイミングでLIVEをチェックした子スレッドはtryに向けて大域脱出して終了します。

実際の動きは実行してみればわかるはずです。

単純なループでなければ、問題が起きそうな場所に

python

1 if LIVE == False: 2 raise(Exception)

を入れておけば、そこに来た時点で止まります。(関数化しておいて呼び出した方がわかりやすいでしょう)

投稿2021/03/04 04:52

編集2021/03/04 08:01
ppaul

総合スコア24670

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

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

0

期待する動作が、「キャンセル」なのか、「終了」かで変わってきますが

シグナル等で別プロセスに対して終了を通知します。
別プログラム側にも手を入れられるなら、他の手段も取れます。(プロセス間通信)

  • concurrent.futures ... Future オブジェクトの cancel()
  • multiprocessing.Process ... kill()/terminate()
  • subprocess.Popen ... kill()/terminate()
  • signal を使う、os.kill

どの方法を取るのかは状況により異なりますが、別プロセスにする場合は、
内部では大抵シグナルを用いて通知していて、終了通知を受け取ったプロセスは、
(シグナルハンドラ等で特別な対応をしない限り)処理を中断して、そのまま終了することになります。
注意点: リソースの開放等は、意図通りに行われない可能性があります。安全な操作ではありません。

※ 具体的な方法は、状況・用途により異なります。起動・終了だけで良いなら subprocess
進捗状況をGUIに表示させたい等、複雑なやりとりが必要になるなら他のプロセス間通信。


例えば、「複数のファイルのコピー」という操作を途中で「キャンセル」したい場合、
既にコピーされたファイルはそのままになる(処理を中断して終了)のか、
それとも実行前の状態に戻す(操作の取り消し)のかという違いには留意して下さい。

自動的な「操作の取り消し」は出来ないので、双方のプログラムで別途対応が必要です。

投稿2021/03/04 03:11

編集2021/03/04 06:15
teamikl

総合スコア8740

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問