Форум сайта python.su
Добрый день.
У меня есть задача: обеспечить навигацию в окне Tkinter по тексту. При этом стрелка влево выделяет слово, стоящее до текущего, соответственно, стрелка вправо выделяет слово, стоящее после текущего. Вот упрощенный код:
#!/usr/bin/python3 import tkinter as tk elem='тест' max_elems=1001 text=(elem+' ')*max_elems text=text[:-1] pos_lst=[] pos2=-2 for i in range(max_elems): pos1=pos2+2 pos2=pos1+len(elem)-1 pos_lst+=[[pos1,pos2]] def move_right(event): if res[0] < len(pos_lst)-1: res[0]+=1 select_term() def move_left(event): if res[0] > 0: res[0]-=1 select_term() def select_term(): if len(pos_lst) > 0: pos1=pos_lst[res[0]][0] pos1='1.'+str(pos1) pos2=pos_lst[res[0]][1] pos2='1.'+str(pos2+1) txt.tag_remove('cur_term','1.0','end') txt.tag_add('cur_term',pos1,pos2) txt.mark_set('insert',pos2) txt.tag_config('cur_term',background='cyan',font='Sans 14') txt.yview('insert') root=tk.Tk() res=[0] frame=tk.Frame(root) frame.pack() txt=tk.Text(frame) txt.focus_set() txt.insert('end',text) txt.mark_set('insert','1.0') txt.yview('1.0') txt.config(state='disabled') txt.pack(expand=1) select_term() txt.bind('<Left>',move_left) txt.bind('<Right>',move_right) root.wait_window() root.mainloop()
Отредактировано vanvanov (Март 16, 2015 10:47:45)
Офлайн
Если я правильно понял, то Вам необходимо определить на сколько проматывать виджет при переходе на следующую строчку?
P.S. Для упрощения можно еще рассмотреть вариант с отображением скрытой строки. В этом случае просто используем метод .see(index)…
Офлайн
Если я правильно понял, то Вам необходимо определить на сколько проматывать виджет при переходе на следующую строчку?В принципе, да. Я не могу понять, как определить, сколько строк/символов умещается на экране.
4kpt_IIIЭто в какой-то мере решает задачу (хотя на очень длинных строках see все равно уходит за пределы экрана, пока не понял, почему). Но мне хотелось бы, чтобы смещался не экран/текст, а выделение, а экран сменялся бы новым экраном только если выделение оказывается за границами видимости. Т.е., например, если на экране помещается 45 строк, то пусть выделение скачет между этими строками, а сам текст не смещается. А если вдруг выделение оказывается на строке 46, то пусть на экран выводится новый текст со строками 46-91 и выделение скачет уже между ними.
P.S. Для упрощения можно еще рассмотреть вариант с отображением скрытой строки. В этом случае просто используем метод .see(index)…
Офлайн
Понял. Тогда придется просчитывать. По высоте: всегда фиксированное значение. Или то, которое Вы внесете сами. Или фиксированное системой. Явно предложить ничего не могу. Нужно писать ручками. Механизм скользящего окна. А насчет размеров. Нужно смотреть в сторону
text["height"]
Отредактировано 4kpt_III (Март 16, 2015 16:59:16)
Офлайн
А можно ли как-то вычислить координаты x, y в пикселях по координатам Tkinter типа ‘5.10’? Нашел event.x, event.y, но это касается мышки.
Офлайн
Можно глянуть в сторону .bbox(index). Но предварительно не забудьте обновить характеристики Text атрибутом .update_idletasks().
Отредактировано 4kpt_III (Март 21, 2015 21:37:48)
Офлайн
Вот кусочек кода. Он все пояснит. Ну только это если я Вас правильно понял
import Tkinter # root = Tkinter.Tk() # def call(event): event.widget.update_idletasks() print event.widget.bbox("current") # text = Tkinter.Text(root, width=20, height=20) text.pack() text.bind("<Return>", call) # root.mainloop()
Офлайн
Подскажите, пожалуйста, как пролистать текст в виджете Text так, чтобы нужная строка/метка оказалась первой строкой виджета. Пробовал txt.yview('80.0'), но нужная строка оказывается пятой.
И еще, где мне найти дельные примеры, например, по yview, scroll, moveto, dragto, scanto? Каждый раз рою гугл, и там в 121 раз цитируется офиц. руководство, которое все равно без конкретных примеров малополезно.
Отредактировано vanvanov (Март 24, 2015 20:08:57)
Офлайн
Я явно так только один раз высчитывал. Вообще в 90% случаев мне хватало какого-нибудь метода типа .see(pos). Могу поискать, если уж очень надо…
Офлайн
Мне достаточно будет понять, как сделать произвольную строку первой без удаления или разделения текста. Остальное я уже накостылял.
Возможно, я плохо знаю tkinter, но у меня реально больше всего времени уходит на интерфейс. Я выбрал tkinter, потому что прочитал, что у него самая подробная документация и его не нужно доустанавливать, что он хорош для начинающих и т.д. и т.п.
А что в итоге мы имеем? Да, документация подробная, но примеры извольте искать на stackoverflow (если еще найдете). На никсах интерфейс еще куда ни шло, а на винде лучше этого не видеть. Убогая система координат в виде ‘1.2’, ‘2.5’ и пр. Если мне понадобится манипулировать текстом, придется писать костыли, чтобы это расшифровывать (и костыли весьма и весьма объемные). Привязка к главному окну. А теперь еще и выясняется, что невозможно определить, находится ли текст в виджете Text в поле видимости (!) и для этого нужны очередные костыли, а некоторые методы как будто живут сами по себе и срабатывают непредсказуемым образом (see, yview).
Извините, накипело.
Отредактировано vanvanov (Март 24, 2015 23:40:34)
Офлайн