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

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

ただいまの
回答率

90.47%

  • HTML

    9269questions

    HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

  • Python 3.x

    6876questions

    Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

  • Tkinter

    165questions

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

tkinterのボタンをクリックしても コマンドが 実行されない

受付中

回答 1

投稿 編集

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

Beginner_ABC

score 4

Python で 困っております

Htmlを 取得して それを 加工して ファイルに書き出す コードを 作成しております

実行を 中断できるように tkinterのボタンを クリックした際に
sys.exit() を 実行させたいのですが クリックしても
スクリプトが 終了しません

ボタンクリック時の動作だけのコードでは 正常に機能します

どのような 解決方法が ありますでしょうか?

書き遅れましたが 処理中断時には 
ファイルを閉じ、 self.root.destroy() sys.exit() を実行させたいですが
このような場合は ProcessPoolExecutor で よいのでしょうか?
また、ファイルをクローズするので ファイル破損対策の処理は 記述しなくても よいのでしょうか?

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 1

+1

過去の質問で参考になるもの→wxpythonでボタンなどからイベント実行後、GUIをフリーズさせたくない

◇キャンセルの要件によるのですが、
スクリプトを終了したい=sys.exit()ならば、ボタン実行時の処理をTreadまたはThreadPoolExecutorに流す形にすれば良いかと。

要件が変わってsys.exit()ではなく一連の処理(タスク)を途中でキャンセルしたくなったらProcessPoolExecutorになります。

そして、ファイルの書き出し部分に関しては外部からキャンセルされてもファイル内容が破損しないように
tempファイルos.replaceを使ったアトミックな書き出し処理に変更してくださいな。


厳密にキャンセルしている訳ではないですが、ブロッキングの方だけ回避する方法を。
1,executor.submitで別タスクを実行
2,閉じるボタンやexitボタンを押下した時は、画面を非表示(withdraw)にする。

以下のコードはmax_workers=1に指定しているので、並列度が1です、
この場合だと同じファイルでも並列に実行されることが起こりえないため問題ないかと。

ProcessPoolExecutorの

# -*- coding: utf-8 -*-
from concurrent.futures import ThreadPoolExecutor, ProcessPoolExecutor, Future, as_completed
from contextlib import closing
from threading import current_thread, get_ident
from random import randint
import tkinter as tk
import sys
from time import sleep
import requests


def on_application_exit():
    # Windowを閉じた時に行いたい処理
    sys.exit(0)


# max_workersは並列度
executor = ProcessPoolExecutor(max_workers=1)


def hard_task(url: str, seconds: int):
    print(f'tid:{get_ident()}, {current_thread().getName()}, {seconds}')
    sleep(seconds)
    print(f'Wake up{seconds}')
    r = requests.get(url)
    # os.replaceを使ってアトミックに書き出してくださいな。
    with open('yahoo.txt', 'a') as f:
        f.write(r.text)


class MyFrame(tk.Frame):
    def __init__(self, root):
        super().__init__(root)
        self.pack()
        self.btn_task = tk.Button(self, text='task', command=self.task)
        self.btn_task.pack()
        self.btn_exit = tk.Button(self, text='exit', command=on_application_exit)
        self.btn_exit.pack()

    def close(self):
        self.master.withdraw()

    def task(self):
        seconds = randint(2, 5)
        url = 'https://www.yahoo.co.jp'
        task = executor.submit(hard_task, url, seconds)


def main() ->None:
    root = tk.Tk()
    root.title("ProcessPoolExecutor")
    root.protocol("WM_DELETE_WINDOW", on_application_exit)
    root.geometry("400x200")
    with closing(MyFrame(root)) as f:
        root.mainloop()


if __name__ == '__main__':
    main()

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2018/05/06 18:50

    早速の回答 ありがとうございます

    書き遅れましたが 処理中断時には 
    ファイルを閉じ、 self.root.destroy() sys.exit() を実行させたいですが
    このような場合は ProcessPoolExecutor で よいのでしょうか?
    また、ファイルをクローズするので ファイル破損対策の処理は 記述しなくても よいのでしょうか?

    キャンセル

  • 2018/05/06 18:54

    >VBA_Macroさんへ
    回答のコメント欄ではなく、この質問を見ている他の人にも分かるように。質問文の本文を変更して頂けませんか。

    キャンセル

  • 2018/05/06 19:02

    申し訳 ありません
    本文に 加筆いたしました

    キャンセル

  • 2018/05/06 23:08

    >VBA_Macroさんへ
    質問文への加筆ありがとうございました。

    キャンセル

関連した質問

  • 解決済

    Python Tkinterでカウントダウンウィンドウを作成したい

    前提・実現したいこと TkinterでGUIを作っています。選択ウィンドウで選択後選択ウィンドウを破棄、新しいウィンドウを作成してLabelウィジェットを使用しカウントダウンを表

  • 解決済

    python tkinter キャンバスのスクロールバーについて

    Python3 でキャンバスを使って絵を描きました。 この絵を上下・左右のスクロールバーを使って移動したいと思いました。 調べてみたところ、リストに対するスクロールバーの説明は

  • 解決済

    バインドの解除

    前提・実現したいこと Python・Tkinterで簡単なアプリケーションを作成していて、下記の様なコードを書きました。特にエラー等はないのですが、一度root.bind('<R

  • 解決済

    1つのウィンドウで画面遷移を行うには、どうすればよいのか。

     前提・実現したいこと 画面1から、画面2に遷移できるようにしたい。(画面1と別にウィンドウが作られるのではなく、画面1のウィンドウに画面2が表示されるようにする。下記のコードは、

  • 解決済

    tkinterのライブラリについて

    閲覧ありがとうございます。 import tkinter as tk import tkinter.messagebox as mb import sys while Tru

  • 受付中

    python tkinterのフォルダダイアログが出たままフリーズします(mac乗り換え

    コード これまで以下のようなコードを使ってフォルダダイアログを出し、フォルダのパスを取得していました(WIN10)。特に問題が起きたことはありませんでした。 import tk

  • 解決済

    tkinter 画像

     tkinterでwebから画像をスクレイピングする部分を関数化してキャンパスに描写できない tkinterでボタンをクリックしたらwebから画像を習得したいのですが、毎回webか

  • 解決済

    python 3.6.5でのtkinterエラー

    python3.6.5においてpythonの公式ドキュメントの下記のコードを実行したところ下記のエラーが でました。解決方法を教えて頂きたいです。 <コード> import

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

  • HTML

    9269questions

    HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

  • Python 3.x

    6876questions

    Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

  • Tkinter

    165questions

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