#python #tkinter
#python #tkinter
Вопрос:
В следующем фрагменте кода, который рисует простой графический интерфейс с одним флажком и кнопкой, я хотел бы изменить описание кнопки и ее рельеф после нажатия кнопки и выбора пользователем файла (за которым следует трудоемкий расчет).
Вызываемая кнопка select_master_button
привязана к команде SelectMaster
.
В SelectMaster
методе configure
инструкция button помещается непосредственно после tkFileDialog.askopenfilename
вызова.
Идея состоит в том, чтобы изменить описание кнопки и рельеф, чтобы пользователь знал об операции обработки.
Однако, когда пользователь выбирает файл и покидает диалоговое окно file, конфигурация кнопки не изменяется, и только после завершения всего метода конфигурация кнопки вступает в силу.
В этом примере последняя инструкция возвращает рельеф кнопки и сообщает пользователю, что выбор файла активен. Это, конечно, работает нормально, поскольку это последняя инструкция перед тем, как метод будет оставлен.
Почему tk.Button.configure
after tkFileDialog.askopenfilename
вступает в силу только после того, как метод оставлен?
Я на Python 2.7.
Я понимаю, что размещение инструкции button configure
перед диалогом file обеспечило бы исправление, но я все еще хотел бы понять текущее поведение.
# -*- coding: utf-8 -*-
import Tkinter as tk
import tkFileDialog
import tkMessageBox
from openpyxl import Workbook, load_workbook
class MyApp():
def __init__(self, parent):
self.sort_tick_value = tk.IntVar()
self.sort_tick_value.set(1)
### GUI ###
self.myParent = parent
self.myParent.geometry("400x400")
self.myContainer = tk.Frame(parent)
self.myContainer.pack(expand=tk.YES, fill=tk.BOTH, padx=10, pady=5,
ipadx=5, ipady=5)
self.sort_selection_frame = tk.Frame(self.myContainer)
self.sort_selection_frame.pack(side=tk.TOP, expand=tk.NO, fill=tk.BOTH,
pady=10)
self.select_master_frame = tk.Frame(self.myContainer)
self.select_master_frame.pack(side=tk.TOP, expand=tk.NO, fill=tk.BOTH,
pady=10)
#### Tick Box ####
self.sort_tick_box =tk.Checkbutton(self.sort_selection_frame,
text="Sort in groups",
variable=self.sort_tick_value)
self.sort_tick_box.pack(side=tk.TOP, anchor=tk.W)
#### Choose Master File Button ####
self.select_master_button = tk.Button(self.select_master_frame)
self.select_master_button.configure(text="Select master file - "
".xlsxn(optional)",
command=self.SelectMaster)
self.select_master_button.pack(side = tk.TOP, anchor=tk.N)
def SelectMaster(self):
selected_master = tkFileDialog.askopenfilename(
parent=root, title='Choose the master file', initialdir = 'D:/')
self.select_master_button.configure(text="Select master file - "
".xlsxn(scanning file, "
"please wait)", relief=tk.SUNKEN)
print "Scanning the selected master file ..."
wb = load_workbook(selected_master, read_only=True)
ws = wb.active
while …:
# time consuming calculation ...
self.select_master_button.configure(text="Select master filen(active)",
relief=tk.RAISED)
root = tk.Tk()
root.wm_title("Title“)
myApp = MyApp(root)
root.mainloop()
Комментарии:
1. так работают все графические интерфейсы.
mainloop
вызывает множество функций по порядку — сначала получает событие мыши / клавиатуры, затем отправляет его виджету, они вызывают вашу функцию и т.д., И в конце mainloop перерисовывает виджеты (если это необходимо). Вы можете использовать root.update() , чтобы заставить mainloop перерисовывать виджеты.2. Если вы хотите принудительно обновить отображение как можно скорее, вызовите
root.update_idletasks()
сразу после вашегоself.select_master_button.configure()
вызова. Примечание:update_idletasks()
это один из многих универсальных методов виджета .3. @furas @martineau Спасибо вам обоим за объяснение основного цикла и подсказку с root.update_idletasks(), которая, кстати, отлично работает! 🙂 Я понимаю, что
self.select_master_button.configure()
действие доtkFileDialog.askopenfilename
без обновления, но не после, связано с тем, что FiledDialog открывает другой фрейм и заставляет другие виджеты ждать обновления в режиме ожидания.