【发布时间】:2014-03-15 17:01:14
【问题描述】:
我想在我的纯 python+tkinter 应用程序中添加一个控制终端小部件,类似于 Blender 中提供的 python 解释器。它应该在相同的上下文(进程)中运行,以便用户可以添加功能并控制当前从控件小部件运行的应用程序。理想情况下,我希望它还“劫持”当前应用程序的标准输出和标准错误,以便它报告正在运行的应用程序中的任何问题或调试信息。
这是我到目前为止所想出的。唯一的问题是它没有响应命令,并且当用户关闭窗口时线程也没有停止。
import Tkinter as tk
import sys
import code
from threading import *
class Console(tk.Frame):
def __init__(self,parent=None):
tk.Frame.__init__(self, parent)
self.parent = parent
sys.stdout = self
sys.stderr = self
self.createWidgets()
self.consoleThread = ConsoleThread()
self.after(100,self.consoleThread.start)
def write(self,string):
self.ttyText.insert('end', string)
self.ttyText.see('end')
def createWidgets(self):
self.ttyText = tk.Text(self.parent, wrap='word')
self.ttyText.grid(row=0,column=0,sticky=tk.N+tk.S+tk.E+tk.W)
class ConsoleThread(Thread):
def __init__(self):
Thread.__init__(self)
def run(self):
vars = globals().copy()
vars.update(locals())
shell = code.InteractiveConsole(vars)
shell.interact()
if __name__ == '__main__':
root = tk.Tk()
root.config(background="red")
main_window = Console(root)
main_window.mainloop()
try:
if root.winfo_exists():
root.destroy()
except:
pass
【问题讨论】:
-
这个问题很相似,但这个问题是如何在 tkinter Frame 中制作交互式终端,并拦截 stdout 和 stderr,提到 stdin 是一个错字,我会修复。
-
IDLE 有类似的东西叫做Python Shell window,你可以阅读它的source code。
-
我现在已经解决了大部分问题。我必须实现自己的标准输入,解释器从中读取,还必须处理关键事件并在我也只读的文本小部件上输入事件。我仍然有失控线程的问题。当窗口关闭时,我将 quit() 推送给解释器,这有时会起作用。我也不知道如何在quit() 上关闭控制台窗口。该线程似乎也从未从 shell.interact() 返回,这可能就是为什么有些线程在我身上跑掉的原因。
-
这很有趣,谢谢!但是shell似乎没有响应任何命令..你也是这种情况吗?
标签: python tkinter embed interpreter