Не могу вызвать функцию для изменения stringvar - PullRequest
0 голосов
/ 15 марта 2019

Я пытаюсь создать маленькие часы, меняя метку tkinter и используя Time Module. Чего я не могу понять, так это как вызвать функцию test() с помощью цикла while, потому что я постоянно получаю сообщение об ошибке, поскольку timee не определено или test() не определено. Я что-то упускаю?

import time
from tkinter import *

def test():
    seconds = time.time()
    local_time = time.ctime(seconds)
    timee.set('The Time Is: ' + local_time)

while 1 > 0:
    test()

root = Tk()
timee = StringVar()

l = Label(root, textvariable=timee)
l.pack(side=TOP)

root.mainloop()

Ответы [ 3 ]

1 голос
/ 15 марта 2019

Если вы представляете, что ваша программа работает сверху вниз, вы никогда не достигнете той части, где вы создаете объект Tk, StringVar и Label;поскольку он застревает в бесконечном цикле while.Ошибка, которую вы получаете, заключается в том, что когда вы звоните test, timee еще не определено.

Проще говоря, ваша программа может делать только одно за раз.Когда он занят работой часов, он не может создавать окна TKinter.OTOH, когда он управляет окном tkinter (функция .mainloop), он не может обновить ваши часы.

Вам нужно получить оба, чтобы хорошо играть друг с другом.Для объекта Tkinter существует специальный метод, который сообщает ему, что вы хотите что-то сделать: after.(См. Документы по виджетам tkinter ):

import time
from tkinter import *

def test():
    seconds = time.time()
    local_time = time.ctime(seconds)
    timee.set('The Time Is: ' + local_time)
    # after updating, schedule next call in 1 second
    root.after(1000, test)

root = Tk()
timee = StringVar()

l = Label(root, textvariable=timee)
l.pack(side=TOP)

# Before starting up, instruct Tkinter to run test after 1 second
root.after(1000, test)
root.mainloop()

Как видите, явного вызова test() больше нет.Вместо этого в after() тестовая функция передается как переменная.Вы можете подумать о том, чтобы передать after() список инструкций без их выполнения.

Затем, когда tkinter запускает свое окно (вызов .mainloop()), он просматривает свой список действий.и найдет test звонок, который вы заказали.В нужный момент он вызовет функцию test один раз;затем в конце функции запланирован следующий вызов.

0 голосов
/ 15 марта 2019

Приложения Tkinter ориентированы на пользователя, что означает, что обычные методики процедурного программирования часто не работают - вся обработка должна выполняться во время работы mainloop().

В этом случае вы можете использовать универсальный метод виджетовafter{} для планирования вызовов к вашей функции тестирования через регулярные промежутки времени, как каждые 1 / 4 секунда (250 мс):

import time
from tkinter import *

def test():
    seconds = time.time()
    local_time = time.ctime(seconds)
    timee.set('The Time Is: ' + local_time)

def poll():
    test()
    root.after(250, poll)  # Schedule another call.

root = Tk()
timee = StringVar()

l = Label(root, textvariable=timee)
l.pack(side=TOP)

poll()  # Start periodic calls to test()
root.mainloop()
0 голосов
/ 15 марта 2019

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

def test():
    global timee
    seconds = time.time()
    local_time = time.ctime(seconds)
    timee.set('The Time Is: ' + local_time)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...