Уведомления

Группа в Telegram: @pythonsu

#1 Март 23, 2015 15:11:23

Oleg_Sizon
Зарегистрирован: 2015-02-28
Сообщения: 32
Репутация: +  0  -
Профиль   Отправить e-mail  

Как предотвратить зависание кнопки tkinter при большой нагрузке?

Спасибо за советы! Постараюсь все учесть! В моем коде after пока не сработал, поскольку я запускаю функцию с параметром, но буду думать..

Офлайн

#2 Март 23, 2015 15:31:09

4kpt_III
Зарегистрирован: 2014-12-22
Сообщения: 999
Репутация: +  39  -
Профиль   Отправить e-mail  

Как предотвратить зависание кнопки tkinter при большой нагрузке?

Передайте в after тоже lambda, а не прямую ссылку.

Офлайн

#3 Март 23, 2015 15:42:33

Oleg_Sizon
Зарегистрирован: 2015-02-28
Сообщения: 32
Репутация: +  0  -
Профиль   Отправить e-mail  

Как предотвратить зависание кнопки tkinter при большой нагрузке?

Прошу прощения, не нашел подобного синтаксиса, это делается так?root.after(10,lambda:make_tree(this_game_code)) Если правильно, то какие-то сбои и ошибки в вычислениях и модуле tkinter при таком запуске происходят по сравнению с make_tree(this_game_code)

Офлайн

#4 Март 23, 2015 16:15:33

4kpt_III
Зарегистрирован: 2014-12-22
Сообщения: 999
Репутация: +  39  -
Профиль   Отправить e-mail  

Как предотвратить зависание кнопки tkinter при большой нагрузке?

Трейсбек ошибки. А то загадками говорите

Офлайн

#5 Март 23, 2015 16:46:12

Oleg_Sizon
Зарегистрирован: 2015-02-28
Сообщения: 32
Репутация: +  0  -
Профиль   Отправить e-mail  

Как предотвратить зависание кнопки tkinter при большой нагрузке?

Exception in Tkinter callback
Traceback (most recent call last):
File “C:\Python34\lib\tkinter\__init__.py”, line 1533, in __call__
return self.func(*args)
File “C:\Users\Oleg\Desktop\x_and_zero_2.pyw”, line 303, in <lambda>
b5=Button(rootf, text=“”, height=2, width=5, command=lambda:game('5'))
File “C:\Users\Oleg\Desktop\x_and_zero_2.pyw”, line 174, in game
player2_choice(4)
File “C:\Users\Oleg\Desktop\x_and_zero_2.pyw”, line 132, in player2_choice
bestresult = Slovar_dereva[str(Spisok_dereva)]
KeyError: ‘None’

Офлайн

#6 Март 23, 2015 17:04:15

4kpt_III
Зарегистрирован: 2014-12-22
Сообщения: 999
Репутация: +  39  -
Профиль   Отправить e-mail  

Как предотвратить зависание кнопки tkinter при большой нагрузке?

str(Spisok_dereva)

Ошибка где-то здесь. Это не связано никак с предыдущим постом. Нужно рыть код.

Офлайн

#7 Март 24, 2015 11:34:25

Oleg_Sizon
Зарегистрирован: 2015-02-28
Сообщения: 32
Репутация: +  0  -
Профиль   Отправить e-mail  

Как предотвратить зависание кнопки tkinter при большой нагрузке?

Не могу согласиться про ошибку с вычислениями, эта ошибка и последующая неправильность в ответах возникает только при запуске after.. Spisok_dereva, как и Slovar_dereva заполняется в функции make_tree, в них хранятся главные вычисления и они заполняются всегда одинаково и по той логике, которая была задумана, проверено тысячу раз еще при отладке без графики. Скорее всего, либо функция after запускает не совсем так, либо плохой стиль написания кода, типа повсеместного использования global, мог где-то сыграть. В общем, буду приводить код в нормальный вид. Еще раз хочу поблагодарить за помощь и задать пару глупых вопросов.
1)Чем именно опасно чрезмерное применение global?
2)В подобных часто встречающихся строках что следует предпочесть - краткость или читабельность?

    b1=Button(rootf, text="", height=2, width=5, command=lambda:game('1'))
    b2=Button(rootf, text="", height=2, width=5, command=lambda:game('2'))
    b3=Button(rootf, text="", height=2, width=5, command=lambda:game('3'))
    b4=Button(rootf, text="", height=2, width=5, command=lambda:game('4'))
    b5=Button(rootf, text="", height=2, width=5, command=lambda:game('5'))
    b6=Button(rootf, text="", height=2, width=5, command=lambda:game('6'))
    b7=Button(rootf, text="", height=2, width=5, command=lambda:game('7'))
    b8=Button(rootf, text="", height=2, width=5, command=lambda:game('8'))
    b9=Button(rootf, text="", height=2, width=5, command=lambda:game('9'))
    b1.grid(row=0,column=0)
    b2.grid(row=0,column=1)
    b3.grid(row=0,column=2)
    b4.grid(row=1,column=0)
    b5.grid(row=1,column=1)
    b6.grid(row=1,column=2)
    b7.grid(row=2,column=0)
    b8.grid(row=2,column=1)
    b9.grid(row=2,column=2)

эту последовательность можно сократить так:
number=1
while number <10:
globals()['b'+str(number)]=Button(rootf, text="", height=2, width=5, command=lambda:game(str(number)))
globals()['b'+str(number)].grid(row=int((number-0.1)/3),column=int((number-0.1)%3))
number+=1
Но правильно ли это - из 300 строк кода сделать 150 математически зашифрованных?

Отредактировано Oleg_Sizon (Март 24, 2015 12:00:57)

Офлайн

#8 Март 24, 2015 12:20:33

4kpt_III
Зарегистрирован: 2014-12-22
Сообщения: 999
Репутация: +  39  -
Профиль   Отправить e-mail  

Как предотвратить зависание кнопки tkinter при большой нагрузке?

1. .after там все же не виноват. Когда разберете свой код Вы в этом убедитесь.
2. чтобы понять чем плох global придется прочитать про сборщик мусора.
3. Ну и код я бы сокращал не так

Если не участвуют в дальнейших вычислениях:

for pos in xrange(1, 10):
    Button(rootf, text="", height=2, width=5, command=lambda:game(pos)).grid(row=0,column=0)

Если участвуют (ключ будет совпадать с pos):

buttons = {}  # в качестве альтернативы можно использовать список
for pos in xrange(1, 10):
    buttons[pos] = Button(rootf, text="", height=2, width=5, command=lambda:game(pos))
    buttons[pos].grid(row=0,column=0)

Есть еще вариант с использованием bind. Тогда на обработчик события передается волшебный event:

def callback(event):
    event.widget["bg"] = "red"
#
for pos in xrange(1, 10):
    but = Button(rootf, text="", height=2, width=5)
    but.grid(row=0,column=0)
    but.bind("<Button-1>", game)

P.S. Забудьте по цикл while. Это цикл с постусловием. Он для других задач. Себя и людей путаете Для фиксированных данных лучше использовать for.

Офлайн

#9 Март 24, 2015 14:48:24

Oleg_Sizon
Зарегистрирован: 2015-02-28
Сообщения: 32
Репутация: +  0  -
Профиль   Отправить e-mail  

Как предотвратить зависание кнопки tkinter при большой нагрузке?

Про while постараюсь учесть! Сейчас еще раз проверил Ваш пример на кратком коде, он не работает!!!

from tkinter import *
import time
#
def go():
    for x in range(10):
        time.sleep(1)
        print (x)
#
def start():
    global startg, startgfr
    startg=Tk()
    startg.resizable(height=FALSE, width=FALSE)
    startgfr=Frame(startg)
    startgfr2=Frame(startg)
    startg.minsize(100,20)
    ws=startg.winfo_screenwidth()
    hs=startg.winfo_screenheight()
    x=(ws/2)-105
    y=(hs/2)-66
    startg.geometry('%dx%d+%d+%d' %(210,70,x,y))
    Button(startgfr, text="Hard work", command=lambda: hard_work()).grid(row=1, column=1)
    startgfr.pack(anchor=CENTER)
    startgfr2.pack(anchor=CENTER)
    startg.mainloop()
def hard_work():
    global startg, startgfr, x
    Button(startgfr, text="Button Done!", command=lambda:hard_work()).grid(row=1, column=1)
    startg.after(1, go)
start()
После нажатия ‘Наrd work’ сначала считается x, а потом создается ‘Button done’, а нужно наоборот!

Отредактировано Oleg_Sizon (Март 24, 2015 14:49:31)

Офлайн

#10 Март 24, 2015 16:07:23

4kpt_III
Зарегистрирован: 2014-12-22
Сообщения: 999
Репутация: +  39  -
Профиль   Отправить e-mail  

Как предотвратить зависание кнопки tkinter при большой нагрузке?

В 2.Х все работает. У меня не стоит 3.Х. Помогли проверить.

Подход неверный, так как Вы создаете кнопку поверх существующей… Поэтому все же придется править. Ну а чтобы не висла в 3.Х подправил:

from tkinter import *
import time
#
def go():
    for x in range(10):
        time.sleep(1)
        print (x)
#
def start():
    global startg, startgfr
    startg=Tk()
    startg.resizable(height=FALSE, width=FALSE)
    startgfr=Frame(startg)
    startgfr2=Frame(startg)
    startg.minsize(100,20)
    ws=startg.winfo_screenwidth()
    hs=startg.winfo_screenheight()
    x=(ws/2)-105
    y=(hs/2)-66
    startg.geometry('%dx%d+%d+%d' %(210,70,x,y))
    Button(startgfr, text="Hard work", command=lambda: hard_work()).grid(row=1, column=1)
    startgfr.pack(anchor=CENTER)
    startgfr2.pack(anchor=CENTER)
    startg.mainloop()
def hard_work():
    global startg, startgfr, x
    Button(startgfr, text="Button Done!", command=lambda:hard_work()).grid(row=1, column=1)
    startg.update()
    startg.after(1, go)
start()

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version