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

В частности, для tkinter.Listbox, заставить Ctrl-A выбрать все (так же, как {{X2 }}), а также сделайте то же самое для Ctrl+<the keys corresponding to those two in my national keyboard layout>.

Поскольку выполняемые подпрограммы существуют на уровне Tk, а не на уровне Python, я не могу просто .bind() для них, как я сделал бы для функции Python.

0
ivan_pozdeev 25 Фев 2018 в 17:44

3 ответа

Лучший ответ

Если вы хотите продублировать любую существующую привязку, первое, что вам нужно сделать, это понять, с чем связана исходная последовательность. В этом случае привязка <Control-/> привязана к тегу привязки «Список» (имя класса внутреннего виджета)

Первый шаг - получить существующую привязку, сделав необработанный вызов интерпретатора Tcl:

func = root.call("bind", "Listbox", "<Control-/>")

Второй шаг - связать эту исходную функцию с новой комбинацией клавиш:

root.call("bind", "Listbox", "<Control-A>", func)

Примечание: вышеупомянутое будет связывать привязку со всеми виджетами списка, а не только с конкретным списком.

1
Bryan Oakley 25 Фев 2018 в 16:37

Я задавал очень похожий вопрос сам.

Вы можете просто создать событие, которое вы хотите имитировать.


Генерация события Control - / , чтобы он обрабатывал все, начиная с этого момента:

lb.bind('<Control-Key-a>',
                    lambda event:lb.event_generate('<Control-Key-slash>'))

Полный пример:

try:                        # In order to be able to import tkinter for
    import tkinter as tk    # either in python 2 or in python 3
except ImportError:
    import Tkinter as tk


if __name__ == '__main__':
    root = tk.Tk()
    lb = tk.Listbox(root)
    for i in range(4):
        lb.insert('end', i)

    lb.bind('<Control-Key-a>',
                    lambda event:lb.event_generate('<Control-Key-slash>'))
    # assign anything but "single" or "browse"
    # so that the effect is obvious
    lb['selectmode'] = 'asd'
    lb.pack()
    tk.mainloop()
-2
Nae 25 Фев 2018 в 15:59

Из исходного кода вы можете узнать, какая команда используется для конкретной привязки.


Для конкретного случая Listbox событие Control - / сначала активирует виртуальное событие <<SelectAll>>. Который затем вызывает команду Tcl для процедуры Tcl списка tk::ListboxSelectAll.

Давайте назначим Control-A для имитации Control - / .

Создайте событие <<SelectAll>>, чтобы оно вызывало все, что должно было вызываться:

lb.bind('<Control-Key-a>', lambda event: lb.event_generate('<<SelectAll>>'))

Или вы можете прямо позвонить, как <<SelectAll>> в конце концов вызовет:

lb.bind('<Control-Key-a>', lambda event: lb.tk.call('tk::ListboxSelectAll', lb))

Вы можете связать все объекты Listbox:

lb.bind_class(lb.winfo_class(), '<Control-Key-a>',
                    lambda event: lb.tk.call('tk::ListboxSelectAll', lb))

Полный пример:

try:                        # In order to be able to import tkinter for
    import tkinter as tk    # either in python 2 or in python 3
except ImportError:
    import Tkinter as tk


if __name__ == '__main__':
    root = tk.Tk()
    lb = tk.Listbox(root)
    for i in range(4):
        lb.insert('end', i)
    lb.bind_class(lb.winfo_class(), '<Control-Key-a>',
                        lambda event: lb.tk.call('tk::ListboxSelectAll', lb))
    # assign anything but "single" or "browse"
    # so that the effect is obvious
    lb['selectmode'] = 'asd'
    lb.pack()
    tk.mainloop()

Наконец, обратите внимание, что вы также можете привязать к <Control-Key-A>, так что привязка работает даже при включенной Caps Lock.

Это также эффективно свяжет Ctrl-Shift-A, что вы можете или не можете хотеть. И наоборот, при включенном Caps Lock Tk будет интерпретировать Ctrl-Shift-A как Ctrl-A.

0
ivan_pozdeev 28 Фев 2018 в 12:58