10

tkinter.messagebox予期しない例外が発生した場合に、トレースバックの詳細を含むエラー メッセージを表示するために使用する Python スクリプトがあります。

import tkinter.messagebox as tm
import traceback

try:
    1/0
except Exception as error:
    tm.showerror(title="Error",
                 message="An error has occurred: '" + str(error) + "'.",
                 detail=traceback.format_exc())

標準 tkinter エラー

この方法でトレースバックを表示することには、いくつかの欠点があります。

デフォルトでエラーの詳細を表示する代わりに、読み取り専用のテキスト フィールドに詳細情報を表示する「詳細を表示」ボタンを追加したいと考えています。

の詳細なエラー

「詳細を表示」ボタンをtkinterメッセージボックスに追加するにはどうすればよいですか?

4

1 に答える 1

10

ウィンドウを使用しToplevel()て、独自の顧客エラー ボックスを作成します。

ここでボタンを使用するのは良い考えだと思います。ttkフレームとウェイトを組み合わせることで、ウィンドウを十分に見栄えよくすることができます。

ユーザーがウィンドウのサイズを変更できないようにするために、詳細テキストボックスを切り替える方法も設定する必要がありました。追跡変数と、設定が簡単な if/else ステートメントの使用。

最後に、テキストボックスを無効にすることができます.config(state="disabled")

import tkinter as tk
import tkinter.ttk as ttk
import traceback


class MyApp(tk.Tk):
    def __init__(self):
        super().__init__()
        tk.Button(self, text='test error', command=self.run_bad_math).pack()

    @staticmethod
    def run_bad_math():
        try:
            1/0
        except Exception as error:
            title = 'Traceback Error'
            message = "An error has occurred: '{}'.".format(error)
            detail = traceback.format_exc()
            TopErrorWindow(title, message, detail)


class TopErrorWindow(tk.Toplevel):
    def __init__(self, title, message, detail):
        tk.Toplevel.__init__(self)
        self.details_expanded = False
        self.title(title)
        self.geometry('350x75')
        self.minsize(350, 75)
        self.maxsize(425, 250)
        self.rowconfigure(0, weight=0)
        self.rowconfigure(1, weight=1)
        self.columnconfigure(0, weight=1)

        button_frame = tk.Frame(self)
        button_frame.grid(row=0, column=0, sticky='nsew')
        button_frame.columnconfigure(0, weight=1)
        button_frame.columnconfigure(1, weight=1)

        text_frame = tk.Frame(self)
        text_frame.grid(row=1, column=0, padx=(7, 7), pady=(7, 7), sticky='nsew')
        text_frame.rowconfigure(0, weight=1)
        text_frame.columnconfigure(0, weight=1)

        ttk.Label(button_frame, text=message).grid(row=0, column=0, columnspan=2, pady=(7, 7))
        ttk.Button(button_frame, text='OK', command=self.destroy).grid(row=1, column=0, sticky='e')
        ttk.Button(button_frame, text='Details', command=self.toggle_details).grid(row=1, column=1, sticky='w')

        self.textbox = tk.Text(text_frame, height=6)
        self.textbox.insert('1.0', detail)
        self.textbox.config(state='disabled')
        self.scrollb = tk.Scrollbar(text_frame, command=self.textbox.yview)
        self.textbox.config(yscrollcommand=self.scrollb.set)

    def toggle_details(self):
        if self.details_expanded:
            self.textbox.grid_forget()
            self.scrollb.grid_forget()
            self.geometry('350x75')
            self.details_expanded = False
        else:
            self.textbox.grid(row=0, column=0, sticky='nsew')
            self.scrollb.grid(row=0, column=1, sticky='nsew')
            self.geometry('350x160')
            self.details_expanded = True


if __name__ == '__main__':
    App = MyApp().mainloop()

結果:

ここに画像の説明を入力

ここに画像の説明を入力

サイズ変更中:D

ここに画像の説明を入力

アップデート:

以下のあなたの声明に応えて:

Tk インスタンスが最初に初期化されていない場合、エラー ウィンドウは表示されません。

クラスを独自のTk()インスタンスとして設定すると、スタンドアロンのエラー ポップアップとして使用できます。また、コメントで言及されている標準エラーメッセージにこのクラスをもう少し準拠させるために、いくつかの配置の変更とサイズ変更コントロールを追加しました。

以下のコードを参照してください。

import tkinter as tk
import tkinter.ttk as ttk


class TopErrorWindow(tk.Tk):
    def __init__(self, title, message, detail):
        super().__init__()
        self.details_expanded = False
        self.title(title)
        self.geometry('350x75')
        self.minsize(350, 75)
        self.maxsize(425, 250)
        self.resizable(False, False)
        self.rowconfigure(0, weight=0)
        self.rowconfigure(1, weight=1)
        self.columnconfigure(0, weight=1)

        button_frame = tk.Frame(self)
        button_frame.grid(row=0, column=0, sticky='nsew')
        button_frame.columnconfigure(0, weight=1)
        button_frame.columnconfigure(1, weight=1)

        text_frame = tk.Frame(self)
        text_frame.grid(row=1, column=0, padx=(7, 7), pady=(7, 7), sticky='nsew')
        text_frame.rowconfigure(0, weight=1)
        text_frame.columnconfigure(0, weight=1)

        ttk.Label(button_frame, text=message).grid(row=0, column=0, columnspan=3, pady=(7, 7), padx=(7, 7), sticky='w')
        ttk.Button(button_frame, text='OK', command=self.destroy).grid(row=1, column=1, sticky='e')
        ttk.Button(button_frame, text='Details',
                   command=self.toggle_details).grid(row=1, column=2, padx=(7, 7), sticky='e')

        self.textbox = tk.Text(text_frame, height=6)
        self.textbox.insert('1.0', detail)
        self.textbox.config(state='disabled')
        self.scrollb = tk.Scrollbar(text_frame, command=self.textbox.yview)
        self.textbox.config(yscrollcommand=self.scrollb.set)
        self.mainloop()

    def toggle_details(self):
        if self.details_expanded:
            self.textbox.grid_forget()
            self.scrollb.grid_forget()
            self.resizable(False, False)
            self.geometry('350x75')
            self.details_expanded = False
        else:
            self.textbox.grid(row=0, column=0, sticky='nsew')
            self.scrollb.grid(row=0, column=1, sticky='nsew')
            self.resizable(True, True)
            self.geometry('350x160')
            self.details_expanded = True

結果:

ここに画像の説明を入力

ここに画像の説明を入力

キャンバスを使用して、必要なエラー画像のタイプで画像を追加することもできます。

于 2018-06-01T20:48:42.340 に答える