python - 스레딩이있는 python tkinter로 인해 충돌

기사 출처 python tkinter

tkinter 마법사가 메인 스레드에서 실행되는 tkinter mainloop와 별도의 스레드에서 실행되는 백그라운드 프로세스에 의해 자동으로 업데이트되도록 스레드를 사용하여 python tkinter 코드를 작성했습니다. 그러나 코드를 실행할 때 잠시 후 파이썬이 충돌한다는 것을 알았습니다. 또한 본질적으로 무작위이지만 파이썬은 대부분 충돌합니다. 이 문제를 보여줄 수있는 작은 테스트 코드를 작성했습니다 (원래 코드는 이와 비슷하지만 실제 프로세스와 다른 많은 기능이 있으므로 테스트 코드를 공유하고 있습니다).

######################################################################
 # Test Code for Tkinter with threads
import Tkinter
import threading
import Queue
import time

# Data Generator which will generate Data
def GenerateData(q):
    for i in range(1000000):
        #print "Generating Some Data, Iteration %s" %(i)
        time.sleep(0.01)
        q.put("Some Data from iteration %s. Putting this data in the queue for testing" %(i))

# Queue which will be used for storing Data
q = Queue.Queue()

def QueueHandler(widinst, q):
    linecount = 0
    while True:
        print "Running"
        if not q.empty():
            str = q.get()
            linecount = linecount + 1
            widinst.configure(state="normal")
            str = str + "\n"
            widinst.insert("end", str)
            if linecount > 100:
                widinst.delete('1.0', '2.0')
                linecount = linecount - 1
            widinst.see('end')
            widinst.configure(state="disabled")

# Create a thread and run GUI & QueueHadnler in it
tk = Tkinter.Tk()
scrollbar = Tkinter.Scrollbar(tk)
scrollbar.pack(side='right', fill='y' )
text_wid = Tkinter.Text(tk,yscrollcommand=scrollbar.set)
text_wid.pack()
t1 = threading.Thread(target=GenerateData, args=(q,))
t2 = threading.Thread(target=QueueHandler, args=(text_wid,q))
t2.start()
t1.start()

tk.mainloop()
######################################################################


재현하려면 :

이 코드를 IDLE에서 열고 실행하면 때때로 정지 상태 인 것처럼 보입니다. 따라서 재현하려면 수면 시간을 0.01에서 0.1로 수정하고 실행하십시오. 이 후 응용 프로그램을 중지하고 0.01로 다시 수정하고 저장하고 실행하십시오. 이번에는 실행되고 잠시 후 Python이 작동을 멈 춥니 다. Windows 7 (64 비트)을 사용하고 있습니다.

질문

파이썬 버그에 제출했지만 거부되었습니다. 그러나 나는 tkinter에서 쓰기 위해 큐를 사용하기 위해 stackoverflow 질문 중 하나 에서이 아이디어를 얻었습니다. 어떤 사람은 그것을 처리하기 위해 수행해야 할 일을 제안 할 수 있습니까?

편집 된 코드 :

# Test Code for Tkinter with threads
import Tkinter
import threading
import Queue
import time

# Data Generator which will generate Data
def GenerateData(q):
    for i in range(1000000):
        #print "Generating Some Data, Iteration %s" %(i)
        time.sleep(0)
        q.put("Some Data from iteration %s. Putting this data in the queue for testing" %(i))

# Queue which will be used for storing Data
q = Queue.Queue()

def QueueHandler():
    global widinst, q
    linecount = 0
    if not q.empty():
        str = q.get()
        linecount = linecount + 1
        widinst.configure(state="normal")
        str = str + "\n"
        widinst.insert("end", str)
        if linecount > 100:
            widinst.delete('1.0', '2.0')
            linecount = linecount - 1
        widinst.see('end')
        widinst.configure(state="disabled")
        tk.after(1,QueueHandler)

# Create a thread and run GUI & QueueHadnler in it
tk = Tkinter.Tk()
scrollbar = Tkinter.Scrollbar(tk)
scrollbar.pack(side='right', fill='y' )
text_wid = Tkinter.Text(tk,yscrollcommand=scrollbar.set)
text_wid.pack()
t1 = threading.Thread(target=GenerateData, args=(q,))
#t2 = threading.Thread(target=QueueHandler, args=(text_wid,q))
#t2.start()
widinst = text_wid
t1.start()
tk.after(1,QueueHandler)
tk.mainloop()
Tkinter는 스레드로부터 안전하지 않습니다. 메인 스레드가 아닌 다른 곳에서는 Tkinter 위젯에 접근 할 수 없습니다. QueueHandler가 메인 스레드에서 실행되도록 코드를 리팩터링해야합니다.

이 질문에 대해 Stack Overflow에서 비슷한 토론을 찾았습니다: https://stackoverflow.com/questions/14168346/

관련 기사
python - Python 속성을 사용한 특성 매핑
python - TypeError : 'str'개체를 호출 할 수 없습니다.
python - 문자열을 인용 된 요소가있는 공백으로 구분 된 목록으로 변환
python - 데비안에서 파이썬 스크립트 데몬 화
python - 사전 인 self 형식 지정
python - 서로 상대적인 Python 필터 목록 항목
python - 비 루트 사용자로서의 감독자 [닫힘]
python - REST API의 일반 (HTML이 아닌) 오류 페이지
python - 지정된 바이트 오프셋에서 파일에서 행 가져 오기
python - 파이썬의 백 슬래시 이스케이프 문자 이해