使用tk创建文本编辑器

时间:2014-02-12 01:58:54

标签: text tkinter editor tk

是否可以使用tk创建可以支持text editorsyntax highlighting的{​​{1}},甚至可以稍后扩展为autocomplete一种特定的语言?

我找到了IDE小部件,但不确定它是否可以支持?

我认为如果一个小部件可以在用户编写文本时对文本进行一些处理,那么它就可以用于此目的。

3 个答案:

答案 0 :(得分:8)

绝对。 tkinter文本小部件功能非常强大。你提到的一切都可以完成,等等。您还可以实现代码折叠,嵌入图像,超链接,撤消等。

以下是您可能会发现有用的相关问题的一些答案:

答案 1 :(得分:3)

不要重复,因为布莱恩奥克利已经回答了这个,但是是的。他是对的。文本小部件非常功能强大。我从来没有见过与其广泛的功能相匹配的另一个文本小部件。

Tkinter是我用来制作文本编辑器的最方便的GUI库。实际上,我一直在制作一个,我自己。你有兴趣制作一个或者你正在寻找已经用Tkinter制作的那个吗?

对我来说,语法高亮和自动完成并不是文本编辑器中最重要的功能。我更关心快速/方便的文件/项目访问,启动/编译/运行程序,Unicode或特殊字符输入,小部件颜色方案,导航键绑定,选项卡,以及我喜欢的各种野生工具的各种快捷方式让我的生活更轻松(更有趣)。所以,我现在实际上只是开始语法高亮(在完成了大部分其他工作之后)。但是,是的,语法高亮可以在Tkinter中完成。

但是,实际上,您在文本编辑器中可能需要的许多功能甚至不需要与GUI库有很多关系。例如,让它识别您正在编辑的文件类型,这样您就可以使用正确的程序运行文件(或使用正确的编译器编译它)。这与Tkinter没什么关系。

如果您想要实时聊聊文字编辑器,请与我们联系。

Python附带的IDE,IDLE,似乎也是用Tkinter编写的。查看源代码有时会有所帮助,但是他们倾向于以与我个人推荐的方式不同的方式做事情,尽管我确信有些人喜欢它比我喜欢的方式更多。

Tkinter有一些缺点,但出于我的目的,它们比我在其他GUI库中看到的缺点要好。有些事情需要更多的工作,但大多数似乎也提供了更多的灵活性。有些事情也需要更少的工作。令人印象深刻的是,Tkinter似乎没有很多错误,而且大多数存在的错误都可以编程。它非常强大。有时候,由于没有本机小部件而且没有以某种方式呈现字体,它会得到一个糟糕的说唱,但不要听别人说话。小部件很好,无论它们是否为原生,并且字体看起来很棒。如果字体出现问题,我认为他们修复了它。告诉我,如果我错了。我看起来很完美(就像在LibreOffice中一样,如果不是更好的话)。此外,Tkinter的特权不应该被忽略。 Tkinter太棒了。

Python的help()方法将成为你的朋友。在类和模块上使用它。

Tkinter最棒的一点是它几乎带有Python。因此,与WxPython不同(即使它们甚至不是3.x,虽然他们正在为其创建另一个名称),但Tkinter可能会自动支持所有未来的Python版本(直到/当他们决定用其他东西替换它时 - 我不知道他们会这样做,除非他们发现一些非常棒的东西)。此外,它不是一个巨大的下载。

无论如何,要开始使用,您需要了解标记(尤其是内置标记)和标记。你很可能会把很多东西用在很多东西上。这些对于访问窗口小部件中的特定文本区域以及对其进行操作非常重要。

INSERT是一个字符串'insert'。但是,它也是一个标志。标记是标记位置的可变索引。 'insert'标记表示文本插件中文本插入的索引。文档的开头是索引"1.0"而不是"0.0"1是第1行。0是字符0.我不相信它的开头标记。你只需使用索引。结尾的标记是END(字符串,'end')。 ' sel.first'和' sel.last'表示所选文本开头和结尾的索引。 SEL(或'sel')是一个标记。标签有点像HTML标签,因为它们标记事物的开头和结尾(以及之间的所有文本)。您可以创建自己的标签来添加文本样式(如粗体和斜体,或只是高亮,这可能对语法高亮有用)。您可以检查一系列文本以查看它是否具有某个标记。例如,

SEL in self.myTextWidget.tag_names(INSERT)

如果选择了文本插入后面(即at)的字符,将返回True

对于标记,您可以使用一些方便的表示法来获得一些方便的索引位置。例如,"insert wordstart"将为'insert'标记所在的任何单词的开头提供索引。 "insert+2c"将在插入后为您提供两个字符的位置。无论如何,有很多这样的东西。

如果您正在制作跨平台应用程序,那么您将想知道不同平台上的一些事件是不同的。所以,检查并确保它们都能正常工作。

您还要意识到,尽管文本小部件中的某些标准键盘快捷键不起作用(例如Control-a并不能全部选择),但实际上还有快捷方式。他们只是不同的捷径。但是,您可以轻松覆盖它们并轻松制作自己的:

    …
    #We're doing both a and A to make sure it works properly when caps-lock is on.
    #Control-Shift-a is different from Control-A despite how it may seem.
    self.myTextWidget.bind("<Control-a>", self.select_all)
    self.myTextWidget.bind("<Control-A>", self.select_all)

def select_all(self, event):
    self.myTextWidget.tag_add("sel", "1.0", "end-1c") #END actually goes beyond the end of the text, adding a new line (so, I subtract a character).
    return "break" #If you want to override the default binding, you need to return "break"

答案 2 :(得分:0)

Tkinter相当易受攻击,它可以用来完成许多任务。我实际上是在python 2.7中使用tkinter制作了我自己的迷你文本编辑器。但它还没有高级功能。但我认为这将是您的想法的良好基础。确保安装了python2.7。

from Tkinter import * 
import tkFileDialog

class Files(Frame):

    def __init__(self, parent):
        Frame.__init__(self, parent)   

        self.parent = parent        
        self.initUI()

    def initUI(self):

        self.parent.title("File dialog")
        self.pack(fill=BOTH, expand=1)

        menubar = Menu(self.parent)
        self.parent.config(menu=menubar)

        fileMenu = Menu(menubar)
        fileMenu.add_command(label="Save", command = self.save_command)
        fileMenu.add_command(label="Open", command = self.onOpen)
        menubar.add_cascade(label="File", menu=fileMenu)        

        self.txt = Text(self)
        self.txt.pack(fill=BOTH, expand=1)


    def onOpen(self):

        ftypes = [('Python files', '*.py'), ('All files', '*')]
        dlg = tkFileDialog.Open(self, filetypes = ftypes)
        fl = dlg.show()

        if fl != '':
            text = self.readFile(fl)
            self.txt.insert(END, text)

    def readFile(self, filename):

        f = open(filename, "r")
        text = f.read()
        return text

    def save_command(self):
        file = tkFileDialog.asksaveasfile(mode='w')
        if file != None:
                data = self.txt.get('1.0', END+'-1c')
                file.write(data)
                file.close()


root = Tk()

top = Frame(root)
top.pack(fill=BOTH, expand=1)

def build():
    l = Label(top, text="test phrase")
    l.pack(side="left")
    ent = Entry(top)
    ent.pack(side="left")

bottom = Frame(root)
bottom.pack()

ex = Files(root)
ex.pack(side="bottom")

root.geometry("300x250+300+300")
root.mainloop()