0

我一直在尝试创建自己的基本 Python IDE。我创建了一个界面,其中包含一个输入文本框,允许我输入语法和一个 pmw.ScrolledText,它显示 Python 解释器的结果输出。

我真正希望做的是将这两个小部件组合成一个可以处理输入和输出的小部件。我还没有找到任何这样的小部件,但我相当肯定有可能以某种方式做到这一点,因为 Idle 是用 Tk 编写的,它基本上是我在我的应用程序中寻找的。查看 Idle 源代码并没有真正向我展示一种简洁的方式来做到这一点。

基本上我正在寻找一个类似于 pmw.ScrolledText 的东西,它接受输入并且还可以显示输出。

我只是想知道 Tk 是否可以做到这一点,以及关于可以采取哪些潜在途径使其发挥作用的任何想法。

谢谢。

4

1 回答 1

3

这绝对是可能的。文本小部件是您想要使用的,但您必须进行一些编码来处理显示提示,然后在用户按下返回键时执行操作。

我认为最简单的做法是在插入提示后立即设置一个标记,然后当您检测到返回键时,抓取从该标记到文件末尾的所有内容作为要运行的命令。

这是一个说明该技术的简短示例。它并不完美(例如,您可以删除提示),但它显示了总体思路。

import Tkinter as tk

class Application(tk.Frame):
    def __init__(self, master):
        tk.Frame.__init__(self, master)
        self.text = tk.Text(self, wrap="word", height=20)
        self.vsb = tk.Scrollbar(self, orient="vertical", command=self.text.yview)
        self.text.configure(yscrollcommand=self.vsb.set)
        self.vsb.pack(side="right", fill="y")
        self.text.pack(side="left", fill="both", expand=True)

        self.text.bind("<Return>", self.process_input)
        self.prompt = ">>> "

        self.insert_prompt()

    def insert_prompt(self):
        # make sure the last line ends with a newline; remember that
        # tkinter guarantees a trailing newline, so we get the
        # character before this trailing newline ('end-1c' gets the
        # trailing newline, 'end-2c' gets the char before that)
        c = self.text.get("end-2c")
        if c != "\n":
            self.text.insert("end", "\n")
        self.text.insert("end", self.prompt, ("prompt",))

        # this mark lets us find the end of the prompt, and thus
        # the beggining of the user input
        self.text.mark_set("end-of-prompt", "end-1c")
        self.text.mark_gravity("end-of-prompt", "left")

    def process_input(self, event=None):
        # if there is an event, it happened before the class binding,
        # thus before the newline actually got inserted; we'll
        # do that here, then skip the class binding.
        self.text.insert("end", "\n")
        command = self.text.get("end-of-prompt", "end-1c")
        self.text.insert("end", "output of the command '%s'...!" % command)
        self.text.see("end")
        self.insert_prompt()

        # this prevents the class binding from firing, since we 
        # inserted the newline in this method
        return "break"

root = tk.Tk()
root.wm_geometry("400x100")
app = Application(root).pack(side="top", fill="both", expand=True)

root.mainloop()
于 2013-07-24T16:48:51.573 回答