@NightElf00

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

tkinterのmainloop()後の処理

解決したいこと

画面Aの「変換開始」ボタンを押すと、画面Bが表示されて、変換処理の進捗をProgressで表示し、変換結果をコンソールに表示する。
上記内容のツールを作成しています。

  • 画面はtkinterを使ってを作成する
  • 変換処理はProgressを使う
  • 進捗の計算は別スレッドで行う

発生している問題・エラー

画面Bを破棄すると、画面Bのmainloop()後の処理が実行されると思いますが、自分が書いたコードでは実行されません。
(最後の self.converter_window.destroy() で画面Bを廃棄します。廃棄後、画面描画開始処理 self.conv_main_window.mainloop() の後の処理が実行され、処理結果を画面Aのほうに戻したい)

該当するソースコード

画面A.py
from tkinter import *
import B


class A:

    # -----定数-----
    # フォント
    FONT_BTN = ('Calibri', 12)        # ボタン設定値

    # -----Window描画関数-----
    # 変換ツールのメイン画面を表示する
    def setup_window(self):

        # -----Window作成-----
        self.conv_main_window = Tk()
        self.conv_main_window.title('変換ツール')
        self.conv_main_window.geometry('800x500')            # Windowサイズ
        self.conv_main_window.resizable(False, False)        # サイズ変更不可

        # Frame設定
        frm_conv_start = Frame(self.conv_main_window, width=800, height=100)          # 変換開始フレーム

        # Frameサイズ固定
        frm_conv_start.propagate(False)

        # Frame配置
        frm_conv_start.grid(row=3, column=0)

        # <--変換後フレームの設定-->

        # 変換開始ボタン
        conv_start_btn = Button(frm_conv_start, text='変換開始', 
                                font=self.FONT_BTN, command=self.click_btn_conv_start)
        conv_start_btn.pack(padx=(0,20), pady=(20,0), anchor=SE)

        # 描画開始
        self.conv_main_window.mainloop()


    # 変更開始ボタンを押下時の処理
    def click_btn_conv_start(self):
       
        # 変換処理関数
        fct = B.B()
        conv_rst = fct.convert_main()

        # 変換処理が正常完了の場合、メッセージを表示する
        if conv_rst is True:
            print("変換完了")
        else:
            print("変換失敗")
        return


if __name__ == "__main__":
    hb = A()
    hb.setup_window()
B.py
from tkinter import *
from tkinter import filedialog, messagebox, ttk
import threading

class B:
    
    # コンストラクタ
    def __init__(self):
        pass


    # 変換メイン関数
    def convert_main(self):
         
        # ---変換開始---
        # 進捗画面設定
        self.set_converter_window()

        # ---ファイル変換処理を別スレッドで開始する---
        #conversion_thread = threading.Thread(target=self.converter_background, args=(self.followup, ))
        conversion_thread = threading.Thread(target=self.converter_background)
        conversion_thread.start()
        
        # 描画開始
        self.converter_window.mainloop()

        print("ここの処理を実行したい")     #☆☆☆ここから処理が実行されない☆☆☆
        return True



    # 進捗画面設定
    def set_converter_window(self):   

        # -----変換進捗画面描画-----
        # ---Window作成---
        self.converter_window = Tk()
        self.converter_window.title('変換進捗')
        self.converter_window.geometry('500x300')           # Windowサイズ
        self.converter_window.resizable(False, False)       # サイズ変更不可

        # Frame設定
        frm_converter_window = Frame(self.converter_window, width=500, height=300)
        frm_converter_window.propagate(False)          # サイズ固定
        frm_converter_window.pack()                    # 配置

        # プログレスバー
        self.progress = ttk.Progressbar(frm_converter_window, orient='horizontal', length=200, mode='determinate')

        # 各ウェジェットを順番に配置
        self.progress.pack()


    # 進捗変換処理関数
    def converter_background(self):
        
        try:
            # プログレスバーの初期値設定
            self.progress['maximum'] = 50
            self.progress['value'] = 0

            for i in range(50):

                # プログレスバー更新
                self.progress['value'] = i + 1

                # 描画更新
                self.progress.update_idletasks()
        except Exception as e:
            messagebox.showerror('エラー', f'例外が発生しました。{e}')
            self.converter_rst = self.CONV_EXCEPTION
        finally:
            self.converter_window.destroy()

if __name__ == "__main__":
    pass

自分で試したこと

conversion_thread = threading.Thread(target=self.converter_background, args=(self.callback, )) のようにコールバック関数を使って、なんとなく処理が続けられるが、処理結果を画面Aのほうに戻すことができませんでした。

0 likes

1Answer

自分が解決できました。
画面Bのmainloop()をdestory()で終了させると、すぐに画面Aのmainloop()に戻るので、画面Bのmainloop()後の処理が実行されません。
画面Aのmainloop()を終了させると、画面Bのmainloop()後の処理がようやく実行されます。

1Like

Your answer might help someone💌