在 Tkinter 的文本小部件中打印所有输出(实时)

Print all outputs (in realtime) in text widget in Tkinter

我正在构建一个界面来调整用户选择的文件。

我想打印处理文件 (def adjust_file()) 的函数的输出txt_process 实时小部件。 目前我设法重定向打印,但是当整个过程完成时,它会立即打印所有内容。这不是我想要的...

我想让用户知道文件处理步骤。如何使每个打印出现在 txt_process 小部件?

import time
import os.path
from datetime import datetime
from tkinter import *
from tkinter import filedialog


def select_zip_file():
    """
    Function for opening the file explorer window
    """
    zipfile_file = filedialog.askopenfilename(
        initialdir=os.path.join(os.getcwd(), '..'),
        title='Selecionar arquivo zipado (.zip)',
        filetypes=(('Zip files', '*.zip'), ('All files', '*.*'))
    )
    # Configura o Entry
    ety_zip.delete(0, END)
    ety_zip.insert(0, '{}'.format(zipfile_file))

    # Processing
    txt_process.delete(1.0, END)
    txt_process.see('end')
    print('Arquivo Selecionado: {}\n'.format(ety_zip.get()), file=redirect)


def adjust_file():
    # Do something
    print('{} Copy done'.format(datetime.now()), file=redirect)
    time.sleep(2)
    # Do something
    print('{} Rename done'.format(datetime.now()), file=redirect)
    time.sleep(2)
    # Do something
    print('{} Transform done'.format(datetime.now()), file=redirect)
    time.sleep(2)
    # Do something
    print('{} Finished'.format(datetime.now()), file=redirect)


def open_app_frame():
    global ety_zip
    global txt_process

    # Create Frames
    app_frame.config(background='#333')
    app_frame.grid(row=0, column=0, sticky=NSEW)
    app_frame.columnconfigure(0, weight=1)

    # Button/Label: File Explorer
    lbl_zip_title = Label(
        app_frame,
        text='Selecionar arquivo .zip',
        font=('Helvetica', 14, 'bold'),
        background='#333',
        foreground='white',
        height=2,
    )
    lbl_zip_title.grid(row=0, padx=(5, 5), pady=(5, 2), sticky=W)
    lbl_zip_title.grid_rowconfigure(0, weight=1)

    # Button Select File
    btn_file = Button(
        app_frame,
        text='{:^10}'.format('Browser'),
        font=('Helvetica', 10),
        command=select_zip_file
    )
    btn_file.grid(row=1, padx=(5, 5), sticky=W)
    btn_file.grid_rowconfigure(0, weight=1)

    # Entry File Selected
    ety_zip = Entry(
        app_frame,
        font=('Helvetica', 10),
        background='white',
        foreground='black',
    )
    ety_zip.grid(row=2, padx=(5, 5), sticky=EW)
    ety_zip.grid_rowconfigure(0, weight=1)

    # Title Convert
    lbl_convert_title = Label(
        app_frame,
        text='Converter .zip obtido no e-SAJ em .pdf',
        font=('Helvetica', 14, 'bold'),
        background='#333',
        foreground='white',
        height=2,
    )
    lbl_convert_title.grid(row=3, padx=(5, 5), pady=(35, 2), sticky=W)
    lbl_convert_title.grid_rowconfigure(0, weight=1)

    # Button to Convert
    btn_final = Button(
        app_frame,
        text='{:^10}'.format('Converter'),
        font=('Helvetica', 10),
        command=adjust_file
    )
    btn_final.grid(row=4, padx=(5, 5), sticky=W)
    btn_final.grid_rowconfigure(0, weight=1)

    # Processing
    txt_process = Text(
        app_frame,
        font=('Helvetica', 10),
        background='white',
        foreground='black',
        height=9,
        wrap='word'
    )
    txt_process.grid(row=7, padx=(5, 5), sticky=EW)
    txt_process.grid_rowconfigure(0, weight=1)


class RedirectText(object):
    def __init__(self, text_widget):
        """Constructor"""
        self.output = text_widget

    def write(self, string):
        """Add text to the end and scroll to the end"""
        self.output.insert('end', string)
        self.output.see('end')


# Main
root = Tk()
root.title('Test')
root_width = 600
root_height = 370
root.geometry(f'{root_width}x{root_height}')

# Frames
app_frame = Frame(root, width=root_width, height=root_height)

# Grid
root.grid_rowconfigure(0, weight=1)
root.grid_columnconfigure(0, weight=1)

# Inicial App
open_app_frame()
redirect = RedirectText(txt_process)
print('Test of Redirect. Ok!', file=redirect)

# Loop
root.mainloop()

更改您的 RedirectText write 函数以在写入后更新小部件。

class RedirectText(object):
    def __init__(self, text_widget):
        """Constructor"""
        self.output = text_widget

    def write(self, string):
        """Add text to the end and scroll to the end"""
        self.output.insert('end', string)
        self.output.see('end')
        self.output.update_idletasks()