【问题标题】:Tkinter Text Tagging Range From Start And End Indices Values From wordstart to wordend?Tkinter 文本标记范围从开始和结束索引值从 wordstart 到 wordend?
【发布时间】:2016-10-11 17:48:30
【问题描述】:

我正在尝试修改 Bryan Oakley 在 ButtonRelease-1 事件中提供的 highlights (tags) words in a tkinter Text widget 的一些惊人代码。

我想单击一些文本,而不是突出显示单个单词,将鼠标拖动到同一行的另一个区域(左或右),然后突出显示范围 wordstart 和 wordend 的整个范围边界。

例如,如果我点击下面代码中tk之后第一行的末尾,将鼠标拖到p em> 词 import 并释放我的鼠标按钮,我希望标签扩展以捕获从 1.0 到 1.20 的全部范围。

下面的代码使用两个tk.StringVar 来捕获开始和结束字符串,但是从获得的这两个索引中,我如何将这些开始和结束点应用到范围,然后扩展以突出显示wordstart 和@987654329 @ 范围?

import tkinter as tk

class Example(tk.Frame):
  def __init__(self, parent):
    tk.Frame.__init__(self, parent)
    self.text = tk.Text(self, wrap="none")
    self.text.pack(fill="both", expand=True)
    self.start = tk.StringVar()
    self.end = tk.StringVar()

    self.text.bind("<Button-1>", self.button_down)
    self.text.bind("<ButtonRelease-1>", self.button_up)
    #self.text.bind("<B1-Motion>", self._on_click)
    self.text.tag_configure("highlight", background="green", foreground="black")

    with open(__file__, "rU") as f:
      data = f.read()
      self.text.insert("1.0", data)

  def button_down(self, event):
    self.start.set(self.text.index('@%s,%s' % (event.x, event.y)))
    print(self.start.get())

  def button_up(self, event):
    self.end.set(self.text.index('@%s,%s' % (event.x, event.y)))
    print(self.end.get())

if __name__ == "__main__":
  root = tk.Tk()
  Example(root).pack(fill="both", expand=True)
  root.mainloop()

【问题讨论】:

    标签: python tkinter text tags bind


    【解决方案1】:

    您可以将"wordstart" 或"wordend" 附加到任何有效索引。此外,您不需要使用StringVar——它增加了复杂性并且没有提供比普通变量更多的价值:

    这是一种方法:

    def button_down(self, event):
        self.start = self.text.index('@%s,%s wordstart' % (event.x, event.y))
    
    def button_up(self, event):
        self.end = self.text.index('@%s,%s wordend' % (event.x, event.y))
    
        self.text.tag_add("highlight", self.start, self.end)
    

    【讨论】:

    • 我没有意识到 wordstart 和 wordend 可以附加到任何有效的索引中,所以这是一个巨大的学习时刻。我不确定如何处理用户从右到左与从左到右突出显示的情况。我在下面发布了一个解决方案,但我很好奇您对测试用户是否突出显示从左到右与从右到左的最佳方法的想法。我只是比较了索引从它们开始突出显示的位置到它们作为浮点数停止的位置。好主意?
    【解决方案2】:

    发布“我的”解决方案(99% 基于 Bryan 的代码和帮助)。如果用户从左到右和从右到左突出显示鼠标,我不确定处理它的“最佳”方法,所以我将索引作为浮点数进行比较,看看哪个大于或小于并处理 @987654322 @ 和 wordend 相应地。

    import tkinter as tk
    
    class Example(tk.Frame):
      def __init__(self, parent):
        tk.Frame.__init__(self, parent)
        self.text = tk.Text(self, wrap="none")
        self.text.pack(fill="both", expand=True)
        self.text.bind("<Button-1>", self.button_down)
        self.text.bind("<ButtonRelease-1>", self.button_up)
    
        self.text.tag_configure("highlight", background="green", foreground="black")
    
        with open(__file__, "rU") as f:
          data = f.read()
          self.text.insert("1.0", data)
    
      def button_down(self, event):
        self.xy_down = self.text.index('@%s,%s' % (event.x, event.y))
        self.start = self.text.index('@%s,%s' % (event.x, event.y))
    
      def button_up(self, event):
        self.stop = self.text.index('@%s,%s' % (event.x, event.y))
        self.xy_up = self.text.index('@%s,%s' % (event.x, event.y))
        if self.xy_down == self.xy_up:
          self.text.tag_remove('highlight', 1.0, 'end')
          self.text.tag_add("highlight", 'insert wordstart', 'insert wordend')
        elif float(self.start) > float(self.stop):
          #print('Highlight right to left')
          self.begin = self.text.index('%s wordend' % (self.start))
          self.end = self.text.index('%s wordstart' % (self.stop))
          self.text.tag_remove('highlight', 1.0, 'end')
          self.text.tag_add("highlight", self.end, self.begin)
          print(self.start, self.stop, self.begin, self.end)
        elif float(self.start) < float(self.stop):
          #print('Highlight left to right')
          self.begin = self.text.index('%s wordstart' % (self.start))
          self.end = self.text.index('%s wordend' % (self.stop))
          self.text.tag_remove('highlight', 1.0, 'end')
          self.text.tag_add("highlight", self.begin, self.end)
    
    if __name__ == "__main__":
      root = tk.Tk()
      Example(root).pack(fill="both", expand=True)
      root.mainloop()
    

    【讨论】:

    • 比较浮点数并不总是有效,因为1.10 被认为小于1.2 作为浮点数,但1.10 实际上在1.2 的右侧。文本小部件有一个专门用于比较索引的compare 方法。 effbot.org/tkinterbook/text.htm#Tkinter.Text.compare-method
    • 谢谢布莱恩。如果可以的话,我会+100。我想知道为什么当我点击第一行时它看起来有问题(不会一直可靠地突出显示)。
    猜你喜欢
    • 2017-11-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多