Найти - Пользователи
Полная версия: классика жанра: tkinter, таймер и MessageBox
Начало » GUI » классика жанра: tkinter, таймер и MessageBox
1 2
nonsense
Всем привет. Думаю, этот вопрос достоин занесения в FAQ, если таковой будет на этом форуме составляться. Вчера решил познакомиться поближе с Питоном и решил начать с таймера. Как вы уже многие, наверное, догадались, вот этот код:

from tkinter import *
from tkinter.messagebox import *
from threading import Timer
def timerDone():
    window.bell()
    showinfo('Alert','Alert')
window = Tk()
mainTimer = Timer(3, timerDone)
mainTimer.start()
window.mainloop()

Не работает. Да, я гуглил, читал, проблема в том, что tkinter внезапно не может в multithreading.

Помогите решить проблему красиво.

After - не предлагать. Это какой-то ужасный костыль. К тому же нужна возможность гибко управлять таймеров - выключить его в любой момент и т.д.

P.S. Еще крайне удивило отсутствие в Питоне интервального таймера - чтобы функция удобно вызывалась через определенный промежуток времени, типа setinterval в JavaScript. Не хочется изобретать велосипед - есть что-нибудь готовое на эту тему?
4kpt_II
nonsense
After - не предлагать. Это какой-то ужасный костыль.

Костыль? Разберитесь, как работает евентлуп. Не порите чушь. Идеология схожа с setTimeout в js. И по-мне даже лучше…

Есть вариант повесить на модуль threading и отвязать часть функционала от системы. Но для новичка - это хардкор.

nonsense
Не работает. Да, я гуглил, читал, проблема в том, что tkinter внезапно не может в multithreading.

Бред. Маниакально-депрессивный. Вы пришли вопросы задавать или рассказывать, почему на них нельзя ответить. Напишите, что Вы конкретно хотите и форумчане постараются Вам помочь. С таким подходом мы далеко с Вами не уедем
4kpt_II
Кстати. На этом форуме я неоднократно давал решения этой “проблемы”. И через after и через threding. Хотя по-мне это не проблема вовсе. А просто специфика.
nonsense
У меня несколько десятков таймеров с динамическим изменением интервала (что-то типа игры) - допустим, нужно добавить 10 секунд к одному таймеру, отнять у другого 15 и все такое - весь функционал уже есть в стандартном таймере без костылей. К тому же, проверять таймеры через isAlive, finished - очень удобно.

Интересует, в первую очередь, threading - как after работает я уже разобрался, интересно узнать что-то новое. Ну и threading универсальнее и правильнее что-ли.
4kpt_II
Ну так напилите свой класс. Я не вижу тут проблемы. Или Вы думаете, что для Вас уже все сделано и готово. Это во-первых. Во-вторых. Пилить игру на tkinter это тот еще геморрой. Не для этого он сделан. Не для этого придуман. Гляньте в сторону pygame. Возможно он может все это из коробки. Во вторых js уже заточен под обработку событий по времени. В tkinter это только вспомогательный функционал. Можете посмотреть в сторону PyQt. Этот GUI-архитектор поновее. Там это может быть реализовано. Я не знаю, так как его не использую из-за ненадобности. Можете спросить прямо в этой ветке. Тут народ больше в теме по PyQt, чем я, поэтому могут и отписаться.

Есть определенные подходы и технологии в каждом языке. Меня бесит setTimeout в js. Сам пишу много на JQuery. Меня он просто вымораживает. setInterval тоже нагоняет на меня тоску. Просто это специфика этого модуля. Если Вы не готовы быстро перестраиваться, то Вам будет сложно дальше. Включите “мышление новичка”. Просто рекомендации.

P.S. Задача, которую Вы описали из разряда: “Хочу ездить”. На чем? Когда? Как?
nonsense
Игра типа настольной, типа “мафии”, все работает, обычный GUI вполне достаточен, разве что с таймерами засада.

А про метод с threading расскажете?

Еще интересно, можно ли сделать, чтобы messagebox выскакивал максимально заметно, поверх другой активной программы?
4kpt_II
Должен и так выскакивать… Что-то значит его давит на более низком уровне. У меня таких проблем нет. Я просто не использую tkmessageBox. Напилил когда-то свое решение с toplevel и мне пока хватает.

Насчет threading. Написал же. Это решение не для новичка. Гляньте лучше на рекурсивный вызов after. Это нормальный подход. Здравый. Посмотрите мои сообщения в этом аккаунте или в 4kpt. Там точно должно быть.

И еще. Там же можно глянуть, почему никогда нельзя писать:

from tkinter import *

В этом же посте, кстати, подымался вопрос специфики работы с tkmessagebox и tkaskopenfilename.

P.S. Будут вопросы - пишите…
nonsense
Вобщем, я придумал решение, даже ничего переписывать не пришлось. Просто добавил один рекурсивный after, который проверяет все таймеры и вызывает окна когда нужно.

4kpt_II
Должен и так выскакивать…
Почему должен? Ведь так же нельзя делать формально? Или можно?

4kpt_II
Что-то значит его давит на более низком уровне.
PyCharm возможно.

4kpt_II
Насчет threading. Написал же. Это решение не для новичка. Гляньте лучше на рекурсивный вызов after. Это нормальный подход. Здравый.
Я не такой уж новичок в программировании. Команды asm z80 помню. Ну и after пришлось применить, но один раз. Это куда лучше, чем нормальные таймеры на костыли менять.

4kpt_II
И еще. Там же можно глянуть, почему никогда нельзя писать:
Я натыкался, читал, но толком не понял. Вернее, понял, что может быть коллизия имен, но как надо правильно писать-то?
4kpt_II
Вот тут написано почему нельзя.
Приведено целая куча причин. Если надо еще, то могу добавить по-быстрому Почитайте этот пост. Там еще описано множество проблем bind. Может помочь в начале пути.

nonsense
asm z80 помню.
Это не имеет никакого значения. Честно.


P.S. За PyCharm плюсик в карму.
nonsense
4kpt_II
Вот тут написано почему нельзя.
Приведено целая куча причин. Если надо еще, то могу добавить по-быстрому Почитайте этот пост. Там еще описано множество проблем bind. Может помочь в начале пути.
Угу. Только что делать-то? Как писать надо? Каждую переменную, класс отдельно вводить в программу или что?
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB