Открыть сайт который ввел с кнопки tkinter
Элемент Entry представляет поле для ввода текста. С помощью конструктора Entry можно установить ряд параметров, основные из них:
- background : фоновый цвет
- cursor : курсор указателя мыши при наведении на текстовое поле
- foreground : цвет текста
- font : шрифт текста
- justify : устанавливает выравнивание текста. Значение LEFT выравнивает текст по левому краю, CENTER — по центру, RIGHT — по правому краю
- show : задает маску для вводимых символов
- state : состояние элемента, может принимать значения NORMAL (по умолчанию) и DISABLED
- textvariable : устанавливает привязку к элементу StringVar
- width : ширина элемента
Элемент Entry имеет ряд методов. Основные из них:
- insert(index, str) : вставляет в текстовое поле строку по определенному индексу
- get() : возвращает введенный в текстовое поле текст
- delete(first, last=None) : удаляет символ по индексу first. Если указан параметр last, то удаление производится до индекса last. Чтобы удалить до конца, в качестве второго параметра можно использовать значение END.
- focus() : установить фокус на текстовое поле
Простейшее текстовое поле:
from tkinter import * from tkinter import ttk root = Tk() root.title("METANIT.COM") root.geometry("250x200") ttk.Entry().pack(anchor=NW, padx=8, pady= 8) root.mainloop()

Получение введенного текста
Для получения текста из Entry, можно использовать его метод get() . Так, определим элемент Entry и по нажатию на кнопку выведем введенный текст на текстовую метку:
from tkinter import * from tkinter import ttk def show_message(): label["text"] = entry.get() # получаем введенный текст root = Tk() root.title("METANIT.COM") root.geometry("250x200") entry = ttk.Entry() entry.pack(anchor=NW, padx=6, pady=6) btn = ttk.Button(text="Click", command=show_message) btn.pack(anchor=NW, padx=6, pady=6) label = ttk.Label() label.pack(anchor=NW, padx=6, pady=6) root.mainloop()

Вставка и удаление текста
Рассмотрим вставку и удаление текста в Entry:
from tkinter import * from tkinter import ttk def clear(): entry.delete(0, END) # удаление введенного текста def display(): label["text"] = entry.get() # получение введенного текста root = Tk() root.title("METANIT.COM") root.geometry("250x150") label = ttk.Label() label.pack(anchor=NW, padx=6, pady=6) entry = ttk.Entry() entry.pack(anchor=NW, padx=6, pady=6) # вставка начальных данных entry.insert(0, "Hello World") display_button = ttk.Button(text="Display", command=display) display_button.pack(side=LEFT, anchor=N, padx=6, pady=6) clear_button = ttk.Button(text="Clear", command=clear) clear_button.pack(side=LEFT, anchor=N, padx=6, pady=6) root.mainloop()
При запуске программы в текстовое поле сразу же добавляется текст по умолчанию:
entry.insert(0, "Hello World")
Кнопка Clear очищает оба поля, вызывая метод delete:
def clear(): entry.delete(0, END)
Вторая кнопка, используя метод get, получает введенный текст:
def display(): label["text"] = entry.get()
Валидация
С помощью параметра validate конструктора Entry можно задать, когда проводить валидацию введенного значения. Этот параметр может принимать следующие значения:
- none : отсутствие валидации, значение по умолчанию
- focus : валидация при получении фокуса
- focusin : валидация при изменении фокуса
- focusout : валидация при потере фокуса
- key : валидация при каждом вводе нового символа
- all : валидация при измении фокуса и вводе символов в поле
Параметр validatecommand позволяет установить команду валидации.
Рассмотрим небольшой пример. Допустим, пользовтаель должен ввести номер телефона в формете +xxxxxxxxxxx. То есть сначала должен идти знак +, а затем 11 цифр, например, +12345678901:
from tkinter import * from tkinter import ttk import re def is_valid(newval): return re.match("^\+\d$", newval) is not None root = Tk() root.title("METANIT.COM") root.geometry("250x200") check = (root.register(is_valid), "%P") phone_entry = ttk.Entry(validate="key", validatecommand=check) phone_entry.pack(padx=5, pady=5, anchor=NW) root.mainloop()
Итак, параметр validate=»key» указывает, что мы будем валидировать ввод при каждом нажати на клавиатуру. Параметр validatecommand=check говорит, что валидировать ввод будет команда «check». Эта команда представляет кортеж из двух элементов:
check = (root.register(is_valid), "%P")
Первый элемент — вызов метода root.register(is_valid) регистрирует функцию, которая собственно будет производить валидацию — это функция is_valid() . Второй элемент — подстановка «%P» представляет новое значение, которое передается в функцию валидации.
Собственно саму валидацию выполняет функция is_valid() . Она принимает один параметр — текущее значение Entry, которое надо валидировать. Она возвращает True, если значение прошло валидацию, и False, если не прошло. Сама логика валидации представляет проверку строки на регулярное выражение «^\+\d*$» . Если новое значение соответствует этому выражению, и в нем не больше 12 символов, то оно прошло валидацию.
В итоге мы сможем ввести в текстовое поле только символ + и затем только 11 цифр.

Теперь немного изменим код и добавим вывод ошибок валидации:
from tkinter import * from tkinter import ttk import re def is_valid(newval): result= re.match("^\+\d$", newval) is not None if not result and len(newval)
Здесь для вывода ошибок валидации добавлен виджет Label. Если введенное значение не соответствует регулярному выражению (например, пользователь попытался ввести нецифровой символ), и длина ввода меньше и равно 12 символов (проверять ввод больше 12 символов нет смысла, так как номер телефона содержит только 12 символов), то в метке выводим сообщение об ошибке

Также мы можем передать значение параметра validate, чтобы в функции валидации в зависимости от того, нажал пользователь на клавишу или убрал фокус с поля, производить те или иные действия. В этом случае необходимо передать команде валидации дополнительный аргумент:
check = (root.register(is_valid), "%P", "%V")
Здесь значение "%V" представляет событие, которое вызывает валидацию (focus/focusin/focusout/key). Тогда в функции валидации с помощью второго параметра мы сможем получить это значение:
def is_valid(newval, op): result= re.match("^\+\d$", newval) is not None if op=="key": # некоторые действия elif op=="focus": # некоторые действия return result
Как в Python & tkinter при использовании MVC создать главное окно программы?
В классе, отвечающим за создание главного окна приложения не знаю какие параметры использовать, - не отображаются элементы окна.
В примере 2 окна обмениваются данными, поэтому у них родительский класс выбран Toplevel. Но Toplevel не позволяет использовать вложенные элементы, такие как меню, ttk.Notebook и пр. и его рекомендуется использовать для диалоговых окон.
Как я понимаю, что происходит:
В main.py создается объект контроллера, ему передается ссылка на главное окно приложения, созданное с помощью root = Tk() => app = Controller(root).
В сонтроллере MainController.py создается объект окна self.view_main_window = ViewMainWindow(root) которому, в свою очередь, передается ссылка на главное окно приложения уже из класса контроллера.
MainView.py получает ссылку в конструкторе def init(self, parent), переименовывает self.master = parent. Дальше виджеты используют ее для определения своей принадлежности.
Это в теории, на практике, - после запуска окна нет, но и сообщений об ошибках тоже нет.
main.py from tkinter import * from controllers.MainController import Controller if __name__ == '__main__': root = Tk() root.title("PyDOE-tk") root.withdraw() app = Controller(root) root.mainloop() controllers/MainController.py from models.MainModel import Model from views.MainView import ViewMainWindow class Controller: def __init__(self, root): self.model = Model() self.view_main_window = ViewMainWindow(root) views/MainView.py from tkinter import * class ViewMainWindow(Frame): def __init__(self, parent): Frame.__init__(self, parent) self.master = parent self.frame = Frame() self.frame.pack() self.button = Button(self.frame, text="myButton") self.button.pack(side=BOTTOM) self.name = Label(self.frame, text='Label') self.name.pack()
Если выбрать родительским классом Toplevel (как в примере на github), то окно показывается, но пустое:
class ViewMainWindow(Toplevel): def __init__(self, parent): Toplevel.__init__(self, parent) self.master = parent self.protocol('WM_DELETE_WINDOW', self.master.destroy) self.frame = Frame() self.frame.pack() self.button = Button(self.frame, text="myButton") self.button.pack(side=BOTTOM) self.name = Label(self.frame, text='Label') self.name.pack()
Если сделать файл исполняемым, как в примере ниже, то все работает. Отображается окно с кнопкой и текстом.
Потому и вопрос: какие параметры нужно передать из файла точки запуска через контроллер, что бы окно появилось с содержимым.
from tkinter import * class ViewMainWindow: def __init__(self, parent): self.master = parent self.frame = Frame() self.frame.pack() self.button = Button(self.frame, text="myButton") self.button.pack(side=BOTTOM) self.name = Label(self.frame, text='Label') self.name.pack() self.master.mainloop() root = Tk() ViewMainWindow(root)
PS 2: Думал, что как то ссылка на главное окно не передается, ввел строку
print('type of root: ', type(parent), id(parent))
в main, контроллер и представление, оказалось, что ссылка на главное окно передается одна и та же:
type of root from main: 2774823903920 type of root from controller: 2774823903920 type of root from view: 2774823903920
- Вопрос задан более трёх лет назад
- 1049 просмотров