Обновите графический интерфейс Tkinter, находясь во внешнем цикле - PullRequest
0 голосов
/ 14 ноября 2018

У меня настроен код для распечатки на консоль, он прогрессирует, поскольку проходит через несколько тысяч элементов. Это прекрасно работает, пока я не собираюсь упаковать его и распространить среди других, поскольку консоли больше нет. Мой текущий метод работает, но графический интерфейс постоянно зависает после нескольких итераций, пока цикл продолжает работать.

Пример кода ниже работает, но мои циклы намного сложнее и зависают. Мне любопытно, есть ли лучший способ сделать это, поскольку я люблю использовать эти графические интерфейсы, но я пока не смог найти хороший способ отправки данных в графический интерфейс, пока я в другом цикле.

from tkinter import *
import time

def do_loop(num_cycles):
    for i in range(0, int(num_cycles)):
        time.sleep(.25)
        # print(i)
        GUI_MSG.set(str(i))
        Tk.update_idletasks(FORM)

FORM = Tk()
GUI_MSG = StringVar()
FORM.wm_title('Perform Element Analysis')

IO_FRAME = LabelFrame(FORM, text=' Input/Output Directories ')
IO_FRAME.grid(row=0, sticky='W', padx=5, pady=5, ipadx=5, ipady=5)

Label(IO_FRAME, text="Numer of Loops").grid(
    row=1, column=1, padx=5, pady=(10, 2), sticky='E')
NUMBER_LOOPS = Entry(IO_FRAME, width=10)
NUMBER_LOOPS.grid(row=1, column=2, columnspan=4)

Button(FORM, text='Generate Tables', command=lambda: do_loop(
    NUMBER_LOOPS.get())).grid(row=3, column=0, sticky='WE', padx=5, pady=5)

Label(FORM, textvariable=GUI_MSG).grid(row=2, sticky='WE', padx=5, pady=20)

FORM.mainloop()

Ответы [ 2 ]

0 голосов
/ 16 ноября 2018

Следуя исходной логике вашего вопроса и используя .after() для ссылки вне функции:

from tkinter import *

def do_loop():
     global count,num_cycles,GUI_MSG
     if count<int(num_cycles):
         GUI_MSG.set(str(count))
         count+=1
         FORM.after(1000,do_loop)

def get_cycles():
     global num_cycles
     num_cycles=NUMBER_LOOPS.get()
     do_loop()

count=0    
FORM = Tk()
GUI_MSG = StringVar()
FORM.wm_title('Perform Element Analysis')

IO_FRAME = LabelFrame(FORM, text=' Input/Output Directories ')
IO_FRAME.grid(row=0, sticky='W', padx=5, pady=5, ipadx=5, ipady=5)

Label(IO_FRAME, text="Numer of Loops").grid(
row=1, column=1, padx=5, pady=(10, 2), sticky='E')
NUMBER_LOOPS = Entry(IO_FRAME, width=10)
NUMBER_LOOPS.grid(row=1, column=2, columnspan=4)

Button(FORM, text='Generate Tables', command=get_cycles).grid(row=3, column=0, sticky='WE', padx=5, pady=5)

Label(FORM, textvariable=GUI_MSG).grid(row=2, sticky='WE', padx=5, pady=20)

FORM.mainloop()
0 голосов
/ 14 ноября 2018
time.sleep()

Sleep останавливает графический интерфейс tkinter, так что вы не можете выполнять какие-либо другие действия в GUI во время его работы. Как указано в документе Python (https://docs.python.org/3/library/time.html#time.sleep)

Приостановить выполнение вызывающего потока на указанное количество секунд

Вы будете лучше обслуживаться, учитывая желаемый результат использования

.after()

И вам действительно может не понадобиться update_idletasks (). Посмотрите, работает ли это для вас:

 from tkinter import *

class myFormWindow():
   def __init__(self,FORM):
      self.count=0
      self.GUI_MSG = StringVar()
      self.FORM=FORM
      self.FORM.wm_title('Perform Element Analysis')

      IO_FRAME = LabelFrame(self.FORM, text=' Input/Output Directories ')
      IO_FRAME.grid(row=0, sticky='W', padx=5, pady=5, ipadx=5, ipady=5)

      Label(IO_FRAME, text="Numer of Loops").grid(
      row=1, column=1, padx=5, pady=(10, 2), sticky='E')
      self.NUMBER_LOOPS = Entry(IO_FRAME, width=10)
      self.NUMBER_LOOPS.grid(row=1, column=2, columnspan=4)
      Button(self.FORM, text='Generate Tables', command=self.get_cycles).grid(row=3, column=0, sticky='WE', padx=5, pady=5)
      Label(self.FORM, textvariable=self.GUI_MSG).grid(row=2, sticky='WE', padx=5, pady=20)



   def get_cycles(self):
      self.num_cycles=self.NUMBER_LOOPS.get()
      self.do_loop()

   def do_loop(self):
       if self.count<int(self.num_cycles):
       self.GUI_MSG.set(str(self.count))
       self.count+=1
       self.FORM.after(1000,self.do_loop)


if __name__=="__main__":
   FORM=Tk()
   form_window=myFormWindow(FORM)
   FORM.mainloop()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...