2016-10-11 6 views
1

Я пытаюсь изменить некоторый удивительный код, предоставленный Брайаном Окли, который highlights (tags) words in a tkinter Text widget на мероприятии ButtonRelease-1.Tkinter Text Tagging Range From Start And End Индексы Значения от wordstart до wordend?

Вместо выделения одного слова, я хотел бы щелкнуть какой-либо текст, перетащить мышь в другую область на одной и той же строке (влево или вправо) и выделить весь диапазон от диапазонаи wordend.

Например, если я нажму на конец первой строки после Тк в коде ниже, перетащите мышь к р слова импорта и отпустите мою кнопку мыши , Я хочу, чтобы тег расширялся, чтобы охватить весь диапазон от 1.0 до 1.20.

Код ниже использует два tk.StringVar для захвата начала и конца строки, но из этих двух показателей, полученных, как бы я применить эти начальные и конечные точки в диапазон, а затем расширить, чтобы выделить до диапазона wordstart и 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.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() 

ответ

2

Вы можете добавить "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) 
+1

Я не понимал, что словосочетание «словостарт» и «слово» могут быть добавлены к любому действительному индексу, поэтому это огромный момент обучения. Я не был уверен, как обрабатывать случаи, когда пользователь выделяет справа налево и слева направо. Я разместил решение ниже, но мне интересно узнать, как лучше всего проверить, был ли пользователь выделен слева направо и справа налево. Я просто сравнил индексы с того места, где они начали подчеркивать, где они остановились, как плавающие. Хорошая идея? – Jarad

0

проводок «мое» решение (на 99% на код Брайана и помощь). Если пользователь выделяет мышь слева направо и справа налево, я не был уверен, что это лучший способ справиться с этим, поэтому я сравнивал индексы как float, чтобы увидеть, что больше или меньше, чем и обрабатывает wordstart и 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

, поскольку поплавки не всегда будут работать, так как '1.10' считается меньше, чем' 1.2', как float, а '1.10' фактически справа от' 1.2'. Текстовый виджет имеет метод сравнения, специально для сравнения индексов. http://effbot.org/tkinterbook/text.htm#Tkinter.Text.compare-method –

+0

Спасибо, Брайан. Я бы +100, если бы мог. Мне было интересно, почему это показалось мне ошибкой, когда я щелкнул по первой строке (не выделял бы надежно все время). – Jarad