Python. Tkinter. Как переключаться между несколькими полями ввода (Entry) с помощью клавиш "Вверх" и "Вниз"?

shbidibom

Новичок
Пользователь
Авг 28, 2023
3
0
1
1) Windows
2) Python 3.11.4
3) Tkinter 8.6.12

Написал демонстративный код:
Python:
from tkinter import *

def downKey(event):
        ent2.focus()

def upKey(event):
        ent1.focus()


win = Tk()
win.geometry("500x500+500+200")


win.bind('<Down>', downKey)
win.bind('<Up>', upKey)

ent1 = Entry()
ent1.pack()

ent2 = Entry()
ent2.pack()

ent3 = Entry()
ent3.pack()

ent4 = Entry()
ent4.pack()

ent5 = Entry()
ent5.pack()


win.mainloop()

Я смог додуматься как переключаться между двумя полями ввода, а вот как перемещаться между всеми, по аналогии с "Tab" и "Shift + Tab, до сих пор понять не могу. Я видел, что эту проблему решают через цикл 'for', но мне этот вариант не подходит, потому что для расположения "Entry" на окне я буду использовать метод 'Place". Подскажите, как это можно сделать просто и понятно? Буду рад любым ответам, спасибо!
 
Последнее редактирование:

regnor

Модератор
Команда форума
Модератор
Июл 7, 2020
2 661
474
83
во первых, импорт через звездочку плохая практика, так вы засоряете текущее пространство имен, могут быть конфликты

ну с кнопкой вниз можно так
Python:
def downKey(event):
     event.widget.tk_focusNext().focus_set()

с кнопкой вверх не знаю, надо что то изобретать, так как функции чтобы перевести фокус на предыдущий виджет не припомню

первое что пришло в голову, можно хранить все хендлы виджетов где то в массиве, и перемещать фокус в зависимости, где фокус сейчас
как то так (импорт ваш со звездочкой не менял)
Python:
from tkinter import *


def downKey(event):
    handle = event.widget.focus_get()
    lstHandle[lstHandle.index(handle) + 1].focus_set()

def upKey(event):
    handle = event.widget.focus_get()
    lstHandle[lstHandle.index(handle) - 1].focus_set()


win = Tk()
win.geometry("500x500+500+200")


win.bind('<Down>', downKey)
win.bind('<Up>', upKey)

lstHandle = []

ent1 = Entry()
lstHandle.append(ent1)
ent1.pack()

ent2 = Entry()
lstHandle.append(ent2)
ent2.pack()

ent3 = Entry()
lstHandle.append(ent3)
ent3.pack()

ent4 = Entry()
lstHandle.append(ent4)
ent4.pack()

ent5 = Entry()
lstHandle.append(ent5)
ent5.pack()


win.mainloop()
нужно добавить проверки на выход за границы массива и если фокуса еще не было нигде
 

shbidibom

Новичок
Пользователь
Авг 28, 2023
3
0
1
во первых, импорт через звездочку плохая практика, так вы засоряете текущее пространство имен, могут быть конфликты

ну с кнопкой вниз можно так
Python:
def downKey(event):
     event.widget.tk_focusNext().focus_set()

с кнопкой вверх не знаю, надо что то изобретать, так как функции чтобы перевести фокус на предыдущий виджет не припомню

первое что пришло в голову, можно хранить все хендлы виджетов где то в массиве, и перемещать фокус в зависимости, где фокус сейчас
как то так (импорт ваш со звездочкой не менял)
Python:
from tkinter import *


def downKey(event):
    handle = event.widget.focus_get()
    lstHandle[lstHandle.index(handle) + 1].focus_set()

def upKey(event):
    handle = event.widget.focus_get()
    lstHandle[lstHandle.index(handle) - 1].focus_set()


win = Tk()
win.geometry("500x500+500+200")


win.bind('<Down>', downKey)
win.bind('<Up>', upKey)

lstHandle = []

ent1 = Entry()
lstHandle.append(ent1)
ent1.pack()

ent2 = Entry()
lstHandle.append(ent2)
ent2.pack()

ent3 = Entry()
lstHandle.append(ent3)
ent3.pack()

ent4 = Entry()
lstHandle.append(ent4)
ent4.pack()

ent5 = Entry()
lstHandle.append(ent5)
ent5.pack()


win.mainloop()
нужно добавить проверки на выход за границы массива и если фокуса еще не было нигде
Спасибо Вам большое🔥 Подскажите, а как лучше всего тогда импортировать Tkinter и почему? Я тоже видел, что люди по разному к нему обращаются, но никто не объяснял почему
 

regnor

Модератор
Команда форума
Модератор
Июл 7, 2020
2 661
474
83
Спасибо Вам большое🔥 Подскажите, а как лучше всего тогда импортировать Tkinter и почему? Я тоже видел, что люди по разному к нему обращаются, но никто не объяснял почему
не только ткинтер, а любой модуль нужно импортировать без звездочки, так как по звездочке вы импортируете в свое пространство имен все функции из модуля, и если вы нечаянно сделаете функцию с таким же именем, как в модуле, то вы ее переопределите, и потом будете очень долго искать ошибку, почему что то не отрабатывает так, как вы ожидали

ваш код можно переделать так
Python:
import tkinter as tk


def downKey(event):
    handle = event.widget.focus_get()
    lstHandle[lstHandle.index(handle) + 1].focus_set()

def upKey(event):
    handle = event.widget.focus_get()
    lstHandle[lstHandle.index(handle) - 1].focus_set()


win = tk.Tk()
win.geometry("500x500+500+200")


win.bind('<Down>', downKey)
win.bind('<Up>', upKey)

lstHandle = []

ent1 = tk.Entry()
lstHandle.append(ent1)
ent1.pack()

ent2 = tk.Entry()
lstHandle.append(ent2)
ent2.pack()

ent3 = tk.Entry()
lstHandle.append(ent3)
ent3.pack()

ent4 = tk.Entry()
lstHandle.append(ent4)
ent4.pack()

ent5 = tk.Entry()
lstHandle.append(ent5)
ent5.pack()


win.mainloop()
 

shbidibom

Новичок
Пользователь
Авг 28, 2023
3
0
1
не только ткинтер, а любой модуль нужно импортировать без звездочки, так как по звездочке вы импортируете в свое пространство имен все функции из модуля, и если вы нечаянно сделаете функцию с таким же именем, как в модуле, то вы ее переопределите, и потом будете очень долго искать ошибку, почему что то не отрабатывает так, как вы ожидали

ваш код можно переделать так
Python:
import tkinter as tk


def downKey(event):
    handle = event.widget.focus_get()
    lstHandle[lstHandle.index(handle) + 1].focus_set()

def upKey(event):
    handle = event.widget.focus_get()
    lstHandle[lstHandle.index(handle) - 1].focus_set()


win = tk.Tk()
win.geometry("500x500+500+200")


win.bind('<Down>', downKey)
win.bind('<Up>', upKey)

lstHandle = []

ent1 = tk.Entry()
lstHandle.append(ent1)
ent1.pack()

ent2 = tk.Entry()
lstHandle.append(ent2)
ent2.pack()

ent3 = tk.Entry()
lstHandle.append(ent3)
ent3.pack()

ent4 = tk.Entry()
lstHandle.append(ent4)
ent4.pack()

ent5 = tk.Entry()
lstHandle.append(ent5)
ent5.pack()


win.mainloop()
Спасибо Вам! Вы мне правда очень помогли 👍🏼
 

Форум IT Специалистов