2016-11-02 4 views
2

안녕하세요 거북이 라이브러리와 Python의 IDLE을 사용하여 약간의 문제가 발견되었습니다. 파이썬 3.5.2에 기록 된 다음 코드 준수 : 누르기 전에input()을 실행할 때 Tkinter가 응답하지 않음 IDLE

import turtle 
turtle.Turtle() 
input("Try moving/resizing the window in IDLE. Press enter than try again.") 

는 귀하의 의견을주고 입력을, 거북이 창이 응답으로 표시하고 사용자가 크기를 조정하는 것을 허용하지됩니다. 즉, IDLE로 실행 한 경우입니다. 그러나 Windows 명령 프롬프트 또는 PowerShell과 같은 명령을 실행하면 완벽하게 작동합니다.

IDLE을 실행 한 경우 사용자가 입력 한 후 ,을 자유롭게 이동하고 아무런 문제없이 크기를 조정할 수 있습니다. 이것은 우리가 더 이상 스크립트 안에 있지 않지만 파이썬의 쉘로 돌아가는 단점을 가지고 있습니다. 물론 쉘을 통해 거북이와 상호 작용할 수는 있지만 실제로 적용 할 때 원하는 것은 아닙니다. 내 주 프로그램은 input()을 사용하여 사용자에게 이동/회전 여부와 양을 묻습니다. 사용자가 'quit'과 같은 문구를 입력하여 프로그램을 종료 할 때까지 무한 루프가 반복됩니다. 나는 IDLE이더라도 거북이가 움직이고 올바르게 그려지는 것을 볼 것입니다. 문제는 창 자체가 응답하지 않는 것입니다. 내용이 모두 정확합니다.

IDLE이 나에게 그런 행동을하는 이유에 관해서는 궁금합니다. 그뿐만 아니라 거북이 창을 응답하지 않게하고 입력() 등을 사용하는 방법이 있습니까? ? 아니면 제가 생각하지 못한 대안이 있을까요? 저의 연구는 저에게 이것이 TkInter와 관련이 있다고 믿게했습니다. 왜 그것이 IDLE 밖에서 만 작동하는지 설명 할 수 있습니다.

아래는 내 처지를 보여주는 이미지입니다. 당신은 의심으로

Unresponsive turtle window

+0

참고로, cmd 셸이나 powershell에서 python.exe를 실행하는 것과 차이가 없습니다. 두 경우 모두, python.exe는 표준 I/O가 파이프 나 파일로 리디렉션되지 않는 한 콘솔 핸들 (conhost.exe의 연결된 인스턴스에 일반 IPC 용)과 콘솔의 입력 및 화면 버퍼에 대한 표준 핸들을 상속합니다. 쉘은 python.exe에 대한 프로세스 핸들을 기다리므로 파이썬이 종료 될 때까지 콘솔과 상호 작용하지 않습니다. – eryksun

+0

REPL 입력 또는'input()'에 줄 입력시 Windows 콘솔에 타이핑 할 때 거북 창이 응답하지 않게됩니다. 메인 스레드가 차단되고 PyOS_InputHook가 실행 중이 아니기 때문에 거북 창이 응답하지 않게됩니다. Tk 창. 실제로 거북이 창을 업데이트하는 경우 가장 가능성있는 설명은 pyreadline을 설치 한 것입니다. 사용자가 enter 키를 누를 때까지 차단 된 조리 된 읽기를 사용하지 않고 원시 콘솔 입력 이벤트를 읽으며 사용자가 텍스트를 입력하는 동안 계속 입력 훅을 호출하여 Tk를 업데이트 할 수 있습니다. – eryksun

답변

1

, 기본 문제는 Tkinter를 사용 거북이 애플리케이션하지 특히, Tkinter를 함께합니다. 나는 맨 처음으로 IDLE에서 tk 창을 가지고 재현했다.

import tkinter as tk 
root = tk.Tk() 
input('prompt: ') 

그런 다음 위의 내용을 3.5.2에서 한 번에 한 줄씩 Win10의 명령 프롬프트에서 대화 형으로 실행했습니다. 두 번째 행은 맨손으로 표시된 창을 표시하고 TaskManager에 항목을 추가하며 작업 표시 줄에 파이썬 아이콘을 추가합니다. CP와 Tk를 앞뒤로 클릭하면 해당 창과 아이콘이 '활성'모양이됩니다. 창 테두리는 회색에서 검은 색으로 바뀌는 반면 아이콘 배경은 검은 색에서 회색으로 바뀝니다.

return 키를 누르기 전에 입력 문을 입력하는 동안 Tk 창에 제목 표시 줄과 TaskManager에 '응답하지 않음'(몇 초 후)이 표시됩니다. 창 안쪽의 마우스가 파란색 바쁜 동그라미가됩니다. 위에서 설명한대로 창이 활성 상태가되고 이동할 수는 있지만 크기를 조정할 수 없으며 정상적으로 닫을 수 없습니다. [X]를 클릭하면 "응답하지 않음, 닫기 또는 대기 중"상자가 표시됩니다 ..

명령문이 입력되면 tk 창이 다시 정상적으로 응답하게됩니다. '사용자'가 아무 것도 입력하지 않으면 Enter 키를 눌러 입력이 완료 될 때까지 tk 창이 응답하지 않게됩니다.

CP에서 재 시도하고 Enter 키를 누르지 않고 일부 문자를 입력하십시오. 동일한 응답이 보이지 않습니까?

IDLE의 셸의 차이점 : 루트를 만들면 루트가 TaskManager에 저장되지만 새 창은 IDLE에 연결됩니다. 상. 입력 문이 쓰여지는 동안 Tk 창은 정상적으로 반응합니다. 따라서이 단계에서 IDLE이 더 좋습니다. input() 문이 입력되면 Tk 창은 언급 한 것처럼 입력 전에도 완전히 응답하지 않습니다 (이동할 수 없음). 이 부분은 더 나쁩니다.

나는 하나의 추가 실험을 시도했다. -n ('no process'옵션)을 사용하여 IDLE을 실행했다.

C:\Users\Terry>python -m idlelib -n 

이 모드에서는 (CP와 달리) 감지 할 수있는 아무런 문제가 없습니다. 거북이를 때렸을 때 이것은 여전히 ​​사실입니다. 지금은 비추천 경고를 무시할 수 있습니다.

설명 1 : IDLE은 생산 실행을위한 것이 아니라 개발 및 학습용으로 설계되었습니다. 그러나 그렇게하는 것이 이점이 있다면 후자에게 사용될 수 있습니다. -n을 사용하면 다른 문제가 발생하지 않는다는 것을 확인해야합니다. 오히려 거북이와 코드가 동일한 프로세스에서 실행될 때 IDLE을 방해하지 않는다는 것을 확인해야합니다.

설명 2 : GUI 프로그램은 일반적으로 입력 및 인쇄를 사용하지 않습니다. 그들은 일반적으로 상호 작용할 콘솔없이 실행됩니다. Windows 콘솔에서도 input()을 사용하면 프롬프트에 응답하기 전에 창을 터치하지 않아야합니다.

설명 3 : GUI 프로그램은 대개 대신 GUI 위젯을 사용하여 정보를 가져와 표시합니다. 거북이는 이것을 더 어렵게 만들지 만, 불가능한 것은 아닙니다. 당신은 코드를 간소화하고 적용 할 수 있습니다/ .py.

+0

tkinter는 PyOS_InputHook 함수로 ['EventHook'] (https://hg.python.org/cpython/file/v3.5.2/Modules/_tkinter.c#l3381)를 등록합니다. 이 훅은 콘솔 REPL에서'PyOS_ReadLine'을 통해 읽을 때 ['my_fgets'] (https://hg.python.org/cpython/file/v3.5.2/Parser/myreadline.c#l26)에 의해 호출되고' '. '_kbhit'가 true를 반환하자 마자 후크가 업데이트 루프에서 빠져 나옵니다. 그런 다음'ReadFile' 또는'ReadConsole'을 사용하여 입력 행을 읽습니다. 이 호출이 반환 될 때까지 Tk 위젯은 다시 업데이트되지 않습니다. BTW, 이것을보기 위해'input'이 필요 없습니다; REPL을 입력하십시오. – eryksun

+0

현재 3.6 베타'PyOS_Readline'은'PyOS_InputHook' 함수를 호출하지 않습니다. Steve Dower에게 언급 한 버그이지만 문제를 만드는 것을 잊고 있습니다. – eryksun

+0

IDLE은 완전히 다릅니다. 그것은 REPL을 사용하지 않고 간단한'PyFile_GetLine' 호출을 통해'input'을 읽습니다. 'readline'은 소켓을 통해 작업자 프로세스에서 IDLE 쉘로 프록시됩니다. 입력 줄을 기다리는 동안 작업자 프로세스의 주 루프는 분명히 ['handle_tk_events'] (https://hg.python.org/cpython/file/v3.5.2/Lib/idlelib/run)를 호출하지 않습니다. .py # l58). – eryksun