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

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

ただいまの
回答率

88.81%

PySimpleGUIの無限ループをボタンを利用して抜けたい

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 495

rinkyo

score 6

[ 実現したいこと ]
PySimpleGUIを用いて、開始ボタンを押すと指定した動作を一定間隔で実行するGUIを作成しています。以下に示すコードで実装しているのですが、指定した処理を中断させるのに、現状ではコマンドプロンプト上でCtrl+Cを入力することで実現しています。
この中断方法を、ボタンのGUIを利用して実現したいと考えてます。

import PySimpleGUI as sg
import pyperclip
import subprocess
import time
import threading
import pyautogui as pgui

#変数宣言***************
#省略
#************************

def set_pisi:
    #省略

def update(i):
    #繰り返す処理(省略)

sg.theme('LightGray1')
layout = [ [sg.Text('切り替え時間  約',font=('小塚ゴシック',12)),sg.InputText(default_text='5',size=(2,3), key='enter_time'),sg.Text('秒(最低2)',font=('小塚ゴシック',12))],
           [sg.Text('切り替えTabの数',font=('小塚ゴシック',12)),sg.InputText(default_text='2',size=(2,3), key='tab_number'),sg.Text('(最高4)',font=('小塚ゴシック',12))],
           [sg.Text('座標初期値は切り替えTab数2かつ以下を想定',font=('小塚ゴシック',10),text_color='#000000')],
           [sg.Text('  →総Tab数4~5 : 切り替えTab=3,4',font=('小塚ゴシック',10))],
           [sg.Text('コマンドプロンプト上でCtrl + C でループ抜ける',font=('小塚ゴシック',10),text_color='#000000')],
           [sg.Button('開始',key='start'),sg.Button('座標設定',key='posi')] ]

window = sg.Window('Enter/Tag自動',layout,resizable=True,size=(300,180))

while True:
    event, values = window.read()

    if event == 'posi':
        #省略

    if event == 'start':
        #省略
        #ループに入るために値変更
        auto = True

    if event == None:
        break

    if auto:
       try:
     #以下繰り返し処理のためのループ
         #このループをボタンクリックで抜けたい
         while True:

           t = threading.Thread(target = update(tab_posi))
           t.start()
           next_time = ((base_time - time.time()) % interval) or interval
           time.sleep(next_time)

           #省略

       #Ctrl+Cでループを抜ける
       except KeyboardInterrupt:
         print("out roop")
         auto = False

window.close()


このコードを基盤に改良して実現できるのが一番ですが、
根本から変更しなければ実現できないのであれば、最初から作り直そうと思います。
是非ご教授お願いします!

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

0

sg.one_line_progress_meter で、
ループの中断条件に使えるプログレスバーを表示できます。
(但し、time.sleepが長すぎる場合は任意のタイミングで動きません)

window.read のオプションに指定する timeout オブションも調べてみて下さい。
一定間隔の時間でイベントを送ってくれるので、タイマーのように扱えます。

構造的な改良を加えるなら、
ループ内で毎回スレッドを作るのではなく、スレッド内でループ処理をして、
中断時にフラグなどでスレッド側のループ条件を抜けるようにすると良いです。

参考: Pysimpleguiのデバックウインドウやプログレスメーターのボタンで処理を中断できるようにしたい

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2020/06/14 18:11

    回答ありがとうございます!
    リンクの記事など参考にさせていただきました
    また、スレッドの生成に関しても自分なりに改良していきたいと思います!

    キャンセル

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

  • ただいまの回答率 88.81%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る