我有一个Python程序,它执行一组操作并在STDOUT上打印响应.现在我正在编写一个GUI,它将调用已经存在的代码,我想在GUI中打印相同的内容而不是STDOUT.我将使用Text小部件来实现此目的.我不想修改执行任务的现有代码(此代码也被其他一些程序使用).
有人可以指点我如何使用这个现有的任务定义并使用其STDOUT结果并将其插入文本小部件?在主GUI程序中,我想调用此任务定义并将其结果打印到STDOUT.有没有办法使用这些信息?
Bry*_*ley 15
您可以通过替换sys.stdout
写入文本小部件的类似文件的对象来解决此问题.
例如:
import Tkinter as tk
import sys
class ExampleApp(tk.Tk):
def __init__(self):
tk.Tk.__init__(self)
toolbar = tk.Frame(self)
toolbar.pack(side="top", fill="x")
b1 = tk.Button(self, text="print to stdout", command=self.print_stdout)
b2 = tk.Button(self, text="print to stderr", command=self.print_stderr)
b1.pack(in_=toolbar, side="left")
b2.pack(in_=toolbar, side="left")
self.text = tk.Text(self, wrap="word")
self.text.pack(side="top", fill="both", expand=True)
self.text.tag_configure("stderr", foreground="#b22222")
sys.stdout = TextRedirector(self.text, "stdout")
sys.stderr = TextRedirector(self.text, "stderr")
def print_stdout(self):
'''Illustrate that using 'print' writes to stdout'''
print "this is stdout"
def print_stderr(self):
'''Illustrate that we can write directly to stderr'''
sys.stderr.write("this is stderr\n")
class TextRedirector(object):
def __init__(self, widget, tag="stdout"):
self.widget = widget
self.tag = tag
def write(self, str):
self.widget.configure(state="normal")
self.widget.insert("end", str, (self.tag,))
self.widget.configure(state="disabled")
app = ExampleApp()
app.mainloop()
Run Code Online (Sandbox Code Playgroud)
Yuu*_*kio 11
在 python 中,每当你调用 print('examplestring') 时,你就是在间接调用 sys.stdout.write('examplestring') :
from tkinter import *
root=Tk()
textbox=Text(root)
textbox.pack()
button1=Button(root, text='output', command=lambda : print('printing to GUI'))
button1.pack()
Run Code Online (Sandbox Code Playgroud)
方法 1:在 GUI 上打印
def redirector(inputStr):
textbox.insert(INSERT, inputStr)
sys.stdout.write = redirector #whenever sys.stdout.write is called, redirector is called.
root.mainloop()
Run Code Online (Sandbox Code Playgroud)
事实上,我们正在调用 print -(callsfor)-> sys.stdout.write -(callsfor)-> redirector
方法 2:编写装饰器 - 在 CLI 和 GUI 上打印
def decorator(func):
def inner(inputStr):
try:
textbox.insert(INSERT, inputStr)
return func(inputStr)
except:
return func(inputStr)
return inner
sys.stdout.write=decorator(sys.stdout.write)
#print=decorator(print) #you can actually write this but not recommended
root.mainloop()
Run Code Online (Sandbox Code Playgroud)
装饰器所做的实际上是将 func sys.stdout.write 分配给 func inner
sys.stdout.write=inner
Run Code Online (Sandbox Code Playgroud)
和 func inner 在回调实际的 sys.stdout.write 之前添加了一行额外的代码
这是更新旧的 func sys.stdout.write 以具有新功能的方式。你会注意到我使用了一个 try-except ,这样如果在打印到文本框时出现任何错误,我至少会保留 sys.stdout.write 的原始函数到 CLI
方法 3:Bryan Oakley 的例子
...
sys.stdout = TextRedirector(self.text, "stdout")
...
class TextRedirector(object):
def __init__(self, widget, tag="stdout"):
self.widget = widget
self.tag = tag
def write(self, str):
self.widget.configure(state="normal")
self.widget.insert("end", str, (self.tag,))
self.widget.configure(state="disabled")
Run Code Online (Sandbox Code Playgroud)
他所做的是他将 sys.stdout 分配给 Class TextRedirector 使用 Method .write(str)
所以调用 print('string') -calls for-> sys.stdout.write('string') -callsfor-> TextRedirector.write('string')
归档时间: |
|
查看次数: |
14290 次 |
最近记录: |