Найти - Пользователи
Полная версия: Как предотвратить зависание кнопки tkinter при большой нагрузке?
Начало » Python для новичков » Как предотвратить зависание кнопки tkinter при большой нагрузке?
1 2 3
Oleg_Sizon
Спасибо за советы! Постараюсь все учесть! В моем коде after пока не сработал, поскольку я запускаю функцию с параметром, но буду думать..
4kpt_III
Передайте в after тоже lambda, а не прямую ссылку.
Oleg_Sizon
Прошу прощения, не нашел подобного синтаксиса, это делается так?root.after(10,lambda:make_tree(this_game_code)) Если правильно, то какие-то сбои и ошибки в вычислениях и модуле tkinter при таком запуске происходят по сравнению с make_tree(this_game_code)
4kpt_III
Трейсбек ошибки. А то загадками говорите
Oleg_Sizon
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’
4kpt_III
str(Spisok_dereva)

Ошибка где-то здесь. Это не связано никак с предыдущим постом. Нужно рыть код.
Oleg_Sizon
Не могу согласиться про ошибку с вычислениями, эта ошибка и последующая неправильность в ответах возникает только при запуске 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 математически зашифрованных?
4kpt_III
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.
Oleg_Sizon
Про 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’, а нужно наоборот!
4kpt_III
В 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()
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