【问题标题】:Add advanced features to a tkinter Text widget向 tkinter Text 小部件添加高级功能
【发布时间】:2011-04-13 13:18:13
【问题描述】:

我正在开发一个简单的消息传递系统,需要将以下内容添加到 Tkinter 文本小部件:

  1. 拼写检查
  2. 更改字体的选项(在所选文本上)
  3. 更改字体颜色的选项(在所选文本上)
  4. 更改字体大小的选项(在所选文本上)

我知道 tkinter Text 小部件能够通过标记机制使用多种字体和颜色,但我不明白如何使用这些功能。

如何使用 Text 小部件的功能实现这些功能?具体来说,如何更改字词的字体系列、颜色和大小,以及如何使用它来实现诸如拼写检查之类的功能,其中拼写错误的字词带有下划线或颜色与文本的其余部分不同。

【问题讨论】:

    标签: python windows text tkinter message


    【解决方案1】:

    Tkinter 文本小部件非常强大,但您必须自己完成一些高级功能。它没有内置的拼写检查或用于加粗文本等的内置按钮,但它们很容易实现。所有功能都在小部件中,您只需要知道如何操作即可。

    以下示例为您提供了一个用于切换突出显示文本的粗体状态的按钮——选择一个字符范围,然后单击该按钮以添加然后删除粗体属性。扩展这个字体和颜色的例子对你来说应该很容易。

    拼写检查也很简单。以下示例使用 /usr/share/dict/words 中的单词(在 Windows 7 上几乎可以肯定不存在,因此您需要提供合适的单词列表)它相当简单,因为它只进行拼写检查当您按空格键时,但这只是为了将示例的代码大小保持在最小水平。在现实世界中,您会希望在进行拼写检查时更加聪明。

    import Tkinter as tk
    import tkFont
    
    class App(tk.Tk):
        def __init__(self):
            tk.Tk.__init__(self)
    
            ## Toolbar
            self.toolbar = tk.Frame()
            self.bold = tk.Button(name="toolbar", text="bold", 
                                  borderwidth=1, command=self.OnBold,)
            self.bold.pack(in_=self.toolbar, side="left")
    
            ## Main part of the GUI
            # I'll use a frame to contain the widget and 
            # scrollbar; it looks a little nicer that way...
            text_frame = tk.Frame(borderwidth=1, relief="sunken")
            self.text = tk.Text(wrap="word", background="white", 
                                borderwidth=0, highlightthickness=0)
            self.vsb = tk.Scrollbar(orient="vertical", borderwidth=1,
                                    command=self.text.yview)
            self.text.configure(yscrollcommand=self.vsb.set)
            self.vsb.pack(in_=text_frame,side="right", fill="y", expand=False)
            self.text.pack(in_=text_frame, side="left", fill="both", expand=True)
            self.toolbar.pack(side="top", fill="x")
            text_frame.pack(side="bottom", fill="both", expand=True)
    
            # clone the text widget font and use it as a basis for some
            # tags
            bold_font = tkFont.Font(self.text, self.text.cget("font"))
            bold_font.configure(weight="bold")
            self.text.tag_configure("bold", font=bold_font)
            self.text.tag_configure("misspelled", foreground="red", underline=True)
    
            # set up a binding to do simple spell check. This merely
            # checks the previous word when you type a space. For production
            # use you'll need to be a bit more intelligent about when
            # to do it.
            self.text.bind("<space>", self.Spellcheck)
    
            # initialize the spell checking dictionary. YMMV.
            self._words=open("/usr/share/dict/words").read().split("\n")
    
        def Spellcheck(self, event):
            '''Spellcheck the word preceeding the insertion point'''
            index = self.text.search(r'\s', "insert", backwards=True, regexp=True)
            if index == "":
                index ="1.0"
            else:
                index = self.text.index("%s+1c" % index)
            word = self.text.get(index, "insert")
            if word in self._words:
                self.text.tag_remove("misspelled", index, "%s+%dc" % (index, len(word)))
            else:
                self.text.tag_add("misspelled", index, "%s+%dc" % (index, len(word)))
    
    
        def OnBold(self):
            '''Toggle the bold state of the selected text'''
    
            # toggle the bold state based on the first character
            # in the selected range. If bold, unbold it. If not
            # bold, bold it.
            current_tags = self.text.tag_names("sel.first")
            if "bold" in current_tags:
                # first char is bold, so unbold the range
                self.text.tag_remove("bold", "sel.first", "sel.last")
            else:
                # first char is normal, so bold the whole selection
                self.text.tag_add("bold", "sel.first", "sel.last")
    
    if __name__ == "__main__":
        app=App()
        app.mainloop()
    

    【讨论】:

    • 哇!这就是我要找的!谢谢!真的没有意识到这有多么容易!为你 +1!
    • 我不断收到一条错误消息,指出 ("sel.first") 是一个错误的索引。我该如何解决这个问题?
    • 抱歉,这只是一个错字,但出于某种原因,我没有将文本设置为粗体。
    • 又一个错字,再次抱歉....再次感谢!
    • @bryanoakley 我理解了大部分代码...但是应用程序访问的是什么拼写检查索引?
    【解决方案2】:

    1) Tk 没有集成的拼写检查器。你可能对PyEnchant感兴趣。

    2) 3) 4) 并不难(请忘记我之前使用 wxPython 的建议)。您可以将 tag_config 作为文本小部件的插入方法的第三个参数传递。它定义了这个选择的配置。

    请参阅以下代码,该代码改编自 Scrolledtext 示例和 effbot,这是有关 Tk 的最佳参考。

    """
    Some text
    hello
    """
    
    from Tkinter import *
    from Tkconstants import RIGHT, LEFT, Y, BOTH
    from tkFont import Font
    from ScrolledText import ScrolledText
    
    def example():
        import __main__
        from Tkconstants import END
    
        stext = ScrolledText(bg='white', height=10)
        stext.insert(END, __main__.__doc__)
    
        f = Font(family="times", size=30, weight="bold")
        stext.tag_config("font", font=f)
    
        stext.insert(END, "Hello", "font")
        stext.pack(fill=BOTH, side=LEFT, expand=True)
        stext.focus_set()
        stext.mainloop()
    
    if __name__ == "__main__":
        example()
    

    【讨论】:

    • 好的,我愿意使用 wxPython。知道如何在 wx 中做到这一点吗?
    • 忘记我的 wxPython 建议。感谢 effbot,我找到了一个 Tk 解决方案。我希望它有所帮助。最佳
    • 除了在插入时添加标签,您还可以在运行时使用 tag_add 添加标签。因此,例如,您可以获取用户选择的字符范围并将一个或多个标签应用于该文本范围。
    • +1 用于附魔链接。好东西。
    猜你喜欢
    • 2023-03-12
    • 2021-04-30
    • 1970-01-01
    • 2017-08-25
    • 1970-01-01
    • 2011-03-30
    • 1970-01-01
    • 1970-01-01
    • 2011-05-09
    相关资源
    最近更新 更多