2013-04-11 3 views
2

DrawingArea의 미니 예제를 작성했습니다. 시작하면 아무 것도 표시되지 않습니다. 특정 장소에서 키보드 누르기를 대기하는 데 단지 raw_input()을 삽입하면이 기능이 작동하므로 해결 방법입니다. 코드는 다음과 같습니다.DrawingArea의 작은 예제를 만드는 방법

#!/usr/bin/env python 

import pygtk 
pygtk.require('2.0') 
import gtk 

R = 300 

window = gtk.Window(gtk.WINDOW_TOPLEVEL) 
window.set_default_size(R, R) 
drawing_area = gtk.DrawingArea() 
window.add(drawing_area) 
window.show_all() 
gc = drawing_area.get_style().fg_gc[gtk.STATE_NORMAL] 

if 0: 
    raw_input() 

drawing_area.window.draw_line(gc, R/10, R/10, R*9/10, R*9/10) 

raw_input() 

이 버전은 시작 윈도우에 그려진 선을 표시하지 않습니다. 셸에서 엔터 키를 누르면, 그냥 종료됩니다 (그리고 창을 제거). 그러나 raw_input()if 0: 블록에서 사용할 수있게되면 셸에서 입력 할 때까지 두 번 대기하고 둘 사이에 그려진 선이 표시됩니다 (일반적으로 코드가 작동하므로 이상한 새로 고침 문제 일 것 같습니다).

while gtk.events_pending(): # drain the event pipe 
    gtk.main_iteration() 

난 항상 아무 소용, 다양한 장소에 그것을 삽입 :

나는이 조각을 사용하여 GTK의 이벤트 큐를 플러시하려고 노력했다.

나는 또한 보통의 gtk.main()을 스크립트의 마지막 명령으로 시도했다. 그러나 그것은 또한 도움이되지 못했습니다.

어떻게 올바르게 수행 할 수 있습니까? 그 이상한 부작용이있는 이유는 무엇입니까 raw_input()?

+0

타이밍 문제 인 것으로 나타났습니다. 'raw_input()'은 일반적으로 충분히 오래 기다리기 때문에 작동합니다 (나는 항상 쉘 윈도우에 다시 초점을 맞추어야합니다. 'main_iteration()'메소드를 호출 한 후 이벤트 파이프 코드 스 니핏의 배수를 사용하고'sleep (0.1)'을 삽입하면 처음부터 대기열에없는 것처럼 보이는 많은 이벤트가 처리됩니다. 그래서 아마도 내 질문은 오히려 : 그리기 영역이 그리기 시도를 받아 들일 준비가되었는지 어떻게 알 수 있습니까? 'window.is_ready()'와 유사합니까? – Alfe

답변

2

그림 영역의 expose-event 신호에 연결해야합니다. 그리기 영역에서 그릴 수있는 유일한 장소입니다. 그 이유는 창을 최소화하거나 다른 창 위로 이동할 때 그리는 내용이 다시 지워지 기 때문입니다. 그러나 노출 이벤트는 적절한 시간에 항상 발생하므로 필요할 때마다 도면을 최신 상태로 유지할 수 있습니다. 이와 같이

:

def on_drawing_area_expose(drawing_area, event, data=None): 
    # ... do your drawing here ... 

drawing_area.connect('expose-event', on_drawing_area_expose) 

은 또한 바람직한 더욱 유연한 방법 카이로 드로잉 확인. Here은 자습서입니다.

+0

그건 정말 enlighting이야! 이 튜토리얼을 가져 주셔서 감사합니다. 카이로가 pygtk에 내장 된 것 같습니다. 맞습니까? 실제로, 나는 그림에서 수백만 개의 점을 설정하고 싶습니다. 이것을 한 번 이상하는 것은 의미가 없습니다 (너무 느리고 시간이 걸립니다). 그러면 비트 맵에 점들 (단일 픽셀)을 설정해야합니다. DrawingArea는 비트 맵 지향적 인 느낌이 들었습니다. 이제 벡터 지향적 인 것으로 알고 있습니다. 비트 맵 지향적 인 튜토리얼에 대한 포인터가 있습니까? – Alfe

+0

아니요, DrawingArea는 실제로 비트 맵 지향입니다. 그러나 모든 것을 한 번 이상 그리는 것을 피할 수는 없습니다. 그리기에 너무 오래 걸리면 해결 방법은지지 저장소를 사용하는 것입니다. 그 위에 포인트를 그려서 노출 이벤트가 발생할 때마다 DrawingArea에 그립니다. – ptomato

+0

흠, 기초가 부족합니다. tkinter에서 나는 픽스맵 객체를 만들고 캔버스에 픽스맵을 놓은 다음 픽스맵에서 비트를 설정할 수 있습니다. 캔버스는 나를 위해 새로 고침을 할 것입니다. pygtk에이 "backing store"항목을 수행하는 방법에 대한 힌트가 있습니까? pygtk의 tkinter-pixmap 오브젝트와 같은 것이 있습니까? – Alfe