Найти - Пользователи
Полная версия: Tkinter > Label.Update() доводит пайтон до самоубиения.
Начало » GUI » Tkinter > Label.Update() доводит пайтон до самоубиения.
1
BusyBox
##                                                                  IMPORT
from Tkinter import *
import pyHook,win32api
##                                                              MAIN WINDOW CREATION
CursorPosWindow = Tk()
##                                                                  GLOBAL VARs
CursorPos = win32api.GetCursorPos()
##                                                                  FUNCs
def DWin():
    CursorPosWindow.title("Cursor Pos")
    CursorPosWindow.geometry("200x30")
    CursorPosWindow.resizable(False, False)
    CursorPosWindow.iconbitmap("./tcl/cur.ico")
    global CursorPosL
    CursorPosL = Label(CursorPosWindow,
                        fg="black",width=15, text=CursorPos)
    TextCur = Label(CursorPosWindow,
                    text="Position X,Y:")
    CursorPosL.place(x=100,y=5)
    TextCur.place(x=4,y=5)
    CursorPosWindow.mainloop()
def HookESC(DWin):
        EscStatus = win32api.GetKeyState(0x1B)
        LMButtonStatus = win32api.GetKeyState(0x08)
        if (EscStatus < 0):
            CursorPosWindow.quit()
            return()
        elif (LMButtonStatus < 0): ## Проверка нажатия клавиши BACKSPACE,если нажата, то вызываем обновление виджета
            CursorPosL.update()
##                                                              PyHOOK MODULE USING
hm = pyHook.HookManager()
hm.KeyAll = HookESC
hm.HookKeyboard()
##                                                                  USING FUNCs
DWin()

Жмем BACKSPACE и пайтон самовыпиливается. И такое не только в конкретном случае. Есть скриптик,который в параллельном потоке делает цикл в котором используется widget.update(), как только дело доходило до потока с циклом, пайтон умирал
4kpt_III
BusyBox
Есть скриптик,который в параллельном потоке делает цикл в котором используется widget.update(), как только дело доходило до потока с циклом, пайтон умирал

Модуль threading, небойсь, использовали.

Напишите, что хотите реализовать. Может есть альтернативные варианты.
BusyBox
4kpt_III
Использовал thread. До момента самовыпиливания пайтона,думал,что могу реализовать обновление содержимого Label'а.В принципе мне нужна замена Label.update() на то,что не доводило бы пайтон до самоубиения. То же самое происходит и при замене Label на Text и редактировании строки:
        elif (LMButtonStatus < 0): ## Проверка нажатия клавиши BACKSPACE,если нажата, то вызываем обновление виджета
            CursorPosL.delete(1.0, END)
            CursorPosL.insert(1.0, CursorPos)
По нажатию BKSPACE пайтон умирает.
Paranoia_Agent
BusyBox
В принципе мне нужна замена Label.update() на то,что не доводило бы пайтон до самоубиения.
А у меня всё работает:
import Tkinter
import threading
import time
    
class programm:
    def __init__(self):
        self.var = 0
        self.go = False
        self.root = Tkinter.Tk()
        self.root.title('Test Thread')
        self.root.protocol('WM_DELETE_WINDOW', self.quit)
        self.button = Tkinter.Button(text = 'Click me', command = self.button_press)
        self.button.grid(row = 1, column = 1, padx = 30, pady = 10)
        self.label = Tkinter.Label(text = self.var)
        self.label.grid(row = 2, column = 1, padx = 30, pady = 10)
        self.root.mainloop()
    
    def button_press(self):
        if self.go:
            self.go = False
            self.button.config(text = 'Click me')
        else:
            self.go = True
            self.th = threading.Thread(target = self.th_foo)
            self.th.start()
            self.button.config(text = 'Stop me')
    
    def th_foo(self):
        while self.go:
            self.var += 1
            self.label.config(text = self.var)
            self.label.update()
            time.sleep(0.1)
    
    def quit(self):   
        self.go = False     
        self.root.quit()
    
if __name__ == '__main__':
    programm()
4kpt_III
Paranoia_Agent
Под чем запускаете?

P.S. Fedora - не работает

TclError: out of stack space (infinite loop?)
BusyBox
Paranoia_Agent
Дак в том то и дело,что под арчем на питоне 2.7 мой скрипт тоже вполне себе работает,а под win 7 x86 не хочет, самовыпиливается пайтон. Если быть точнее,то работает widget.update() с формой, только я там не по нажатию клавиши т.к. вин апи,а по нажатию кнопки в форме делал.
Paranoia_Agent
4kpt_III
Paranoia_Agent
Под чем запускаете?
Как ни странно: Fedora 21, python 2.7.8

BusyBox
Дак в том то и дело,что под арчем на питоне 2.7 мой скрипт тоже вполне себе работает,а под win 7 x86 не хочет
А если пустить update в том же потоке, что и GUI, а обновление запускать по флагу?
import Tkinter
import threading
import time
    
class programm:
    def __init__(self):
        self.var = 0
        self.go = False
        self.flag = False
        self.root = Tkinter.Tk()
        self.root.title('Test Thread')
        self.root.protocol('WM_DELETE_WINDOW', self.quit)
        self.button = Tkinter.Button(text = 'Click me', command = self.button_press)
        self.button.grid(row = 1, column = 1, padx = 30, pady = 10)
        self.label = Tkinter.Label(text = self.var)
        self.label.grid(row = 2, column = 1, padx = 30, pady = 10)
        self.root.mainloop()
    
    def button_press(self):
        if self.go:
            self.go = False
            self.button.config(text = 'Click me')
        else:
            self.go = True
            self.th = threading.Thread(target = self.th_foo)
            self.th.start()
            self.button.config(text = 'Stop me')
            while self.go:
                if self.flag:
                    self.label.config(text = self.var)
                    self.label.update()
                    self.flag = False
    
    def th_foo(self):
        while self.go:
            self.var += 1 
            self.flag = True    
            time.sleep(0.1)
    
    def quit(self):   
        self.go = False     
        self.root.quit()
    
if __name__ == '__main__':
    programm()
Griffon
Встречался с такой ерундой. Долго не заморачивался и использовал Queue и self.after(…). То есть периодически проверяю очередь сообщений и обновляю отображение, а в потоках эту очередь обновляю.
4kpt_III
Griffon

Я приводил пример. Можно просто отдельно GUI открепить в отдельный поток, я рядом запускать любое количество потоков. Ничего сложного и страшного там нет
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