Форум сайта python.su
Всем доброго времени суток. При изучении библиотеки tkinter (Python 3*) столкнулся с непонятным мне поведением.
Первое, когда я пытался реализовать функционал “выбрать все” по нажатию клавиш Ctrl+a:
from tkinter import * root = Tk() text = Text(root) text.pack(expand=YES, fill=BOTH) def select_all(e): e.widget.tag_add(SEL, '1.0', END) text.bind('<Control-a>', select_all) root.mainloop()
from tkinter import * root = Tk() text = Text(root) text.pack(expand=YES, fill=BOTH) def select_all(e): e.widget.tag_add(SEL, '1.0', END) return 'break' # ЭТО ДАЛО НУЖНЫЙ ЭФФЕКТ! text.bind('<Control-a>', select_all) root.mainloop()
root = Tk() text = Text(root) text.pack(expand=YES, fill=BOTH) def find_text(e): target = askstring('Find text', 'Search String?') if target: where = e.widget.search(target, INSERT, END) if where: print(where) pastit = where + ('+%dc' % len(target)) e.widget.tag_remove(SEL, '1.0', END) e.widget.tag_add(SEL, where, pastit) e.widget.mark_set(INSERT, pastit) e.widget.see(INSERT) e.widget.focus() return 'break' # РЕШИЛО ПРОБЛЕМУ!!! text.bind('<Control-f>', find_text) root.mainloop()
Офлайн
Кучу лет уже работаю с tkinter, но никогда такого не видел. Попробуйте просто вернуть None или приведите полный код, чтобы можно было протестировать.
moskitos80
Первое, когда я пытался реализовать функционал “выбрать все” по нажатию клавиш Ctrl+a:
Офлайн
4kpt_III
или приведите полный код, чтобы можно было протестировать
from Tkinter import * root = Tk() text = Text(root) text.pack(expand=YES, fill=BOTH) def find_text(e): target = "a" # текст который нужно найти if target: where = e.widget.search(target, INSERT, END) if where: print(where) pastit = where + ('+%dc' % len(target)) e.widget.tag_remove(SEL, '1.0', END) e.widget.tag_add(SEL, where, pastit) e.widget.mark_set(INSERT, pastit) e.widget.see(INSERT) e.widget.focus() return 'break' # РЕШИЛО ПРОБЛЕМУ!!! text.bind('<Control-f>', find_text) root.mainloop()
Офлайн
4kpt_III
Кучу лет уже работаю с tkinter, но никогда такого не видел. Попробуйте просто вернуть None или приведите полный код, чтобы можно было протестировать.
from tkinter import * root = Tk() text = Text(root) text.pack(expand=YES, fill=BOTH) def select_all(e): e.widget.tag_add(SEL, '1.0', END) text.bind('<Control-a>', select_all) root.mainloop()
from tkinter import * root = Tk() text = Text(root) text.pack(expand=YES, fill=BOTH) def select_all(e): e.widget.tag_add(SEL, '1.0', END) return 'break' # ЭТО ДАЛО НУЖНЫЙ ЭФФЕКТ! text.bind('<Control-a>', select_all) root.mainloop()
Офлайн
Все правильно работает…
break не нужен
P.S. Подсказка. Поменяйте <Control-a> на <Control-m>…
P.S.S. Тут имеет место дележка вызванного события.
Отредактировано 4kpt_III (Март 1, 2015 21:46:24)
Офлайн
4kpt_IIIВот! Вот про это можно по подробнее? Именно этот момент я смутно представляю себе и хочу разобраться. Я предполагал, точнее все что я смог понять со своим плохим английским на иностранных сайтах это то, что после моего обработчика вызываются какие то еще обработчики. Но я же не вешал больше ни каких обработчиков. Делаю вывод, что библиотека вызывает какие то свои обработчики т.н. действия по-умолчанию, а возвращение строки ‘break’ предотвращает их выполнение. Но что это за обработчики по умолчанию? И для чего они нужны? Зачем они сделаны? Можно пожалуйста подробнее рассказать?
P.S.S. Тут имеет место дележка вызванного события.
Офлайн
Объясню. Но с одним условием. Никогда больше вы не будете использовать конструкцию
from tkinter import*
Офлайн
4kpt_IIIБез проблем. Я её использую только в учебных целях. Я представляю все плюсы и минусы этой конструкции. В реальном коде я себе такого не позволю
Никогда больше вы не будете использовать конструкцию… Договорились?
Офлайн
Тогда держите. Этот код ответит Вам на все вопросы.
import Tkinter # root = Tkinter.Tk() # # def call(who): print who # but = Tkinter.Button(root, text="ops", width=30, height=3) but.bind("<Button-1>", lambda e: call("but")) but.pack() root.bind_class("Button", "<Button-1>", lambda e: call("class")) root.bind("<Button-1>", lambda e: call("root")) root.bind_all("<Button-1>", lambda e: call("all")) # root.mainloop()
Офлайн
Да-да этот код я понимаю. В вашем примере на одно событие явно “повешено” несколько обработчиков и событие “всплывает” через них всех. Но в моей то ситуации:
import tkinter as tk # root = tk.Tk() text = tk.Text(root) text.pack(expand=tk.YES, fill=tk.BOTH) # def select_all(e): e.widget.tag_add(tk.SEL, '1.0', tk.END) # text.bind('<Control-a>', select_all) root.mainloop()
Офлайн