为了账号安全,请及时绑定邮箱和手机立即绑定

python tkinter:使文本小部件自动随文本滚动

python tkinter:使文本小部件自动随文本滚动

心有法竹 2022-12-27 16:32:25
我已将 STDOUT 重定向到文本小部件。然后我使用线程来运行子进程,通过 poll() 捕获标准输出并打印它(重定向到文本小部件)。现在我希望小部件随文本小部件自动滚动,以便用户始终可以看到最新的输出。(文本小部件的唯一用途是显示运行脚本的输出,因此请随意提出替代方案)class myGui:  def __init__(self, master=none)    self.text_Output = tk.Text(frame_Output)    self.text_Output.config(borderwidth='1', height='10', insertborderwidth='2', relief='ridge')    self.text_Output.config(width='50')    # redirect stdout    redir = RedirectText(self.text_Output)    sys.stdout = redir  def runCode:   self.p = subprocess.Popen(["COMMAND HERE"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, bufsize=1, universal_newlines=True)    while self.p.poll() is None:        msg = self.p.stdout.readline().strip()        if msg:            print(msg)class RedirectText(object):    def __init__(self, text_ctrl):        """Constructor"""        self.output = text_ctrl    def write(self, string):        self.output.insert(tk.END, string)
查看完整描述

1 回答

?
Helenr

TA贡献1780条经验 获得超4个赞

Text有方法see(...)可以在插入新文本后使用。


如果你使用see('end')它会滚动到最后。


最小的工作示例 - 每次滚动到末尾insert()


编辑:我添加了see()用于滚动到顶部 ( see('1.0')) 或末尾 ( see('end')) 的按钮。


import tkinter as tk


root = tk.Tk()


text = tk.Text(root)

text.pack()


button_top = tk.Button(root, text="Move to TOP", command=lambda:text.see('1.0'))

button_top.pack()


button_end = tk.Button(root, text="Move to END", command=lambda:text.see('end'))

button_end.pack()


# instert to Text and scroll it

for x in range(50):

    text.insert('end', str(x) + '\n')

    text.see('end')  # move to the end after adding new text


root.mainloop()    

编辑:使用类的最小示例RedirectText


import tkinter as tk

import sys

import datetime


# --- classes ---


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')


# --- functions ---


def add_time():

    """Add current time every 2 seconds"""

    print(datetime.datetime.now())

    root.after(2000, add_time)


# --- main ---


root = tk.Tk()


text = tk.Text(root)

text.pack()


button_top = tk.Button(root, text="Move to TOP", command=lambda:text.see('1.0'))

button_top.pack()


button_end = tk.Button(root, text="Move to END", command=lambda:text.see('end'))

button_end.pack()


# keep original `stdout` and assing `RedirectText` as `stdout`

old_stdout = sys.stdout

sys.stdout = RedirectText(text)


# add some datetime at the beginning 

print('--- TOP ---')

for _ in range(50):

    print(datetime.datetime.now())


# add new datetime every 2 seconds

add_time()


# write to console when `print()` and `sys.stdout` redirect to `Text`

old_stdout.write('Hello World!\n')      # needs `\n` 

print('Hello World!', file=old_stdout)  # doesn't need `\n`


root.mainloop()    


# assign back original `stdout`    

sys.stdout = old_stdout

顺便说一句:如果您需要在print()重定向到时打印到控制台Text


old_stdout.write('Hello World!\n')      # needs `\n` 


print('Hello World!', file=old_stdout)  # doesn't need `\n`

顺便说一句:您也可以使用file=打印而不分配RedirectText给sys.stdout


redirect = RedirectText(text)


print('Hello World!', file=redirect)


查看完整回答
反对 回复 2022-12-27
  • 1 回答
  • 0 关注
  • 500 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号