Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/321.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 在文本小部件中应用标记_Python_Tkinter - Fatal编程技术网

Python 在文本小部件中应用标记

Python 在文本小部件中应用标记,python,tkinter,Python,Tkinter,我需要一些帮助标签相关 我正在编写一个简单的编辑器,支持基本格式。 通过使用一个文本小部件(名为Text),我放置了一个标记“b”,以设置该标记应用于粗体的文本 当我将粗体应用于选择时,这不是问题: text.tag_add('b', SEL_FIRST,SEL_LAST) 当我只想在打字时打开/关闭粗体时,我遇到了两个问题。 要打开它,我找到的唯一方法是: text.insert(INSERT, ' ', 'b' ) text.mark_set("insert", INSERT+'-1c'

我需要一些帮助标签相关

我正在编写一个简单的编辑器,支持基本格式。 通过使用一个文本小部件(名为Text),我放置了一个标记“b”,以设置该标记应用于粗体的文本

当我将粗体应用于选择时,这不是问题:

text.tag_add('b', SEL_FIRST,SEL_LAST)
当我只想在打字时打开/关闭粗体时,我遇到了两个问题。 要打开它,我找到的唯一方法是:

text.insert(INSERT, '  ', 'b' )
text.mark_set("insert", INSERT+'-1c')
请注意,我必须插入两个空格。如果我插入一个,则粗体不适用。如果插入“”,则光标返回一个字符

我的第二个问题是,当我在一个粗体区域内写作时,如何关闭它——对此我一点也不知道


谢谢你的帮助

你可能没有意识到这一点,但你正试图做一些在Tkinter非常困难的事情。虽然文本小部件标签是一个强大的概念,但在创建wysywig编辑器之类的东西时,它们有一些弱点

你需要改变一下你的方法。我认为更好的解决方案不是插入空格,而是在每次插入字符时添加应用(或删除)标记的绑定。这有它自己的一套问题,但只要对细节有足够的关注,你就能克服它们。我们可以通过自定义密钥绑定来实现这一点

将字符插入文本小部件时,这由文本小部件类上的
事件上的绑定处理。因此,我们可以绑定到
来添加标记。但是,如果我们向小部件上的
添加绑定,这将在类绑定之前触发,这意味着我们的代码将在插入字符之前而不是之后执行。我们将尝试修改一些尚未实际插入小部件的内容

解决这个问题的一种方法是绑定到按键释放,而不是按键,因为字符是插入到按键上的。然而,想象一下这样一个场景:用户按下并按住一个键——将输入多个字符,但您可能只得到一个向上键事件。所以这个解决方案不是特别好

另一个解决方案是以某种方式安排自定义绑定在默认绑定之后进行。要做到这一点,我们需要做两件事:1)调整小部件的“绑定标记”,使其在类标记之后有一个额外的标记,以及2)向这个新的绑定标记添加一个绑定

这种方法也有缺点。不是因为绑定标签,而是因为除了
(例如,要粘贴的control-v不是由
绑定处理的,因此您必须为粘贴添加一个特殊情况)之外,还需要处理更多的事件

这就是说,这个解决方案可能对您来说已经足够好了,或者至少可以帮助您更好地理解问题,而理解问题往往是找到解决方案的最大障碍

在下面的示例中,我有一个文本小部件,它有一个名为“CustomText”的附加bindtag,我们将它放在标准的“text”绑定标记之后。我为
事件在这个标记上添加了一个绑定,在处理程序中,我只需将适当的标记应用于刚刚插入的字符

您必须添加自己的代码来处理剪贴板粘贴,以及处理冲突标记的问题(例如两个标记各有自己的字体)。不过,希望这个例子能起到启发作用

import Tkinter as tk

class SampleApp(tk.Tk):
    def __init__(self, *args, **kwargs):
        tk.Tk.__init__(self, *args, **kwargs)
        self.tag_vars = {
            "underline": tk.IntVar(),
            "red": tk.IntVar(),
            }

        self.text = MyText(self, width=40, height=8)
        self.text.tag_configure("red", foreground="red")
        self.text.tag_configure("underline", underline=True)

        toolbar = tk.Frame(self)
        self.underline = tk.Checkbutton(self, text="Underline", 
                                        onvalue = True, offvalue=False,
                                        variable = self.tag_vars["underline"]
                                        )
        self.red = tk.Checkbutton(self, text="Red", 
                                  onvalue = True, offvalue=False,
                                  variable = self.tag_vars["red"]
                                  )
        self.underline.pack(in_=toolbar, side="left")
        self.red.pack(in_=toolbar, side="left")

        toolbar.pack(side="top", fill="x")
        self.text.pack(side="top", fill="both", expand=True)

class MyText(tk.Text):
    def __init__(self, parent, *args, **kwargs):
        tk.Text.__init__(self, *args, **kwargs)

        self.parent = parent

        # add a new bind tag, "CustomText" so we
        # can have code run after the class binding
        # has done it's work
        bindtags = list(self.bindtags())
        i = bindtags.index("Text")
        bindtags.insert(i+1, "CustomText")
        self.bindtags(tuple(bindtags))

        # set a binding that will fire whenever a 
        # self-inserting key is pressed
        self.bind_class("CustomText", "<Key>", self.OnKey)

    def OnKey(self, event):
        # we are assuming this is called whenever 
        # a character is inserted. Apply or remove
        # each tag depending on the state of the checkbutton
        for tag in self.parent.tag_vars.keys():
            use_tag = self.parent.tag_vars[tag].get()
            if use_tag:
                self.tag_add(tag, "insert-1c", "insert")
            else:
                self.tag_remove(tag, "insert-1c", "insert")

if __name__ == "__main__":
    app = SampleApp()
    app.mainloop()
将Tkinter作为tk导入
类SampleApp(tk.tk):
定义初始化(self,*args,**kwargs):
tk.tk.\uuuuu初始化(self,*args,**kwargs)
self.tag_vars={
“下划线”:tk.IntVar(),
“红色”:tk.IntVar(),
}
self.text=MyText(self,宽度=40,高度=8)
self.text.tag\u configure(“红色”,前台=“红色”)
self.text.tag_configure(“underline”,underline=True)
工具栏=tk.Frame(self)
self.underline=tk.Checkbutton(self,text=“underline”,
onvalue=True,offvalue=False,
变量=self.tag_vars[“下划线”]
)
self.red=tk.Checkbutton(self,text=“red”,
onvalue=True,offvalue=False,
变量=self.tag_vars[“红色”]
)
self.underline.pack(在工具栏中,side=“left”)
self.red.pack(在工具栏中,side=“left”)
工具栏包装(side=“top”,fill=“x”)
self.text.pack(side=“top”,fill=“both”,expand=True)
类MyText(tk.Text):
定义初始化(自、父、*args、**kwargs):
tk.Text.\uuuu init\uuuuu(self,*args,**kwargs)
self.parent=parent
#添加一个新的绑定标记“CustomText”,以便
#可以在类绑定后运行代码
#已经完成了它的工作
bindtags=list(self.bindtags())
i=bindtags.index(“文本”)
bindtags.insert(i+1,“自定义文本”)
self.bindtags(元组(bindtags))
#设置一个绑定,该绑定将在
#按下自动插入键
self.bind_类(“CustomText”,“self.OnKey”)
def OnKey(自我,事件):
#我们假设它在任何时候都被调用
#插入一个字符。应用或删除
#每个标签取决于checkbutton的状态
对于self.parent.tag_vars.keys()中的标记:
使用\u tag=self.parent.tag\u vars[tag].get()
如果使用_标签:
自我标记添加(标记“插入-1c”、“插入”)
其他:
自行拆除标签(标签“插入-1c”、“插入”)
如果名称=“\uuuuu main\uuuuuuuu”:
app=SampleApp()
app.mainloop()

谢谢你,Bryan,但是在我看来,你的方法太复杂了,我也不太想开始为缺少的东西编写绑定—例如粘贴

我简单地写下了以下内容,它似乎起了作用

        l=text.tag_names('insert')
        if l==() or l[0]!='b':   # select bold
          text.insert(INSERT, '  ', 'b' )
          text.mark_set('insert', 'insert-1c')
        else:                    # deselect bold
          text.insert(INSERT, ' ' )
          text.tag_remove ('b','insert-1c') 
          text.mark_set('insert', 'insert-1c')
我唯一剩下的问题是,在选择粗体时,我还没有找到不插入额外空格的方法,但我可以接受它