質問するログイン新規登録

回答編集履歴

1

補足

2021/03/25 14:49

投稿

katsuko
katsuko

スコア3605

answer CHANGED
@@ -37,4 +37,85 @@
37
37
  ----
38
38
  というわけで、cairoで十分かと思いますが、補足。
39
39
  GTK+でOpenGLを試してみたことがありますが、どうも不安定、という印象があり、OpenGLを使うのであればQtの方がいいなぁ、というのが自分の考えです。
40
- まぁ、あくまで自分の考え、ですが。
40
+ まぁ、あくまで自分の考え、ですが。
41
+
42
+ ---
43
+ 失礼、よく読むと試してみて遅い、と書かれてますね。
44
+
45
+ もし、`cairo_rectangle`と`cairo_fill`をピクセル数分呼んでいるのであれば、`cairo_fill`は最後に一回だけ呼ぶようにしてもダメですか?
46
+
47
+ ```python
48
+ # coding: utf-8
49
+
50
+ import cairo
51
+ import gi
52
+ gi.require_version('Gtk', '3.0')
53
+ from gi.repository import Gtk, Gdk
54
+
55
+ class App(Gtk.Application):
56
+ def __init__(self, **kwargs):
57
+ super().__init__(**kwargs)
58
+ self.points = []
59
+ self.dragging = False
60
+
61
+ def do_activate(self):
62
+ window = Gtk.Window(application=self, default_width=400, default_height=300)
63
+ drawing_area = Gtk.DrawingArea(visible=True)
64
+ drawing_area.add_events(Gdk.EventMask.BUTTON_PRESS_MASK | Gdk.EventMask.POINTER_MOTION_MASK | Gdk.EventMask.BUTTON_RELEASE_MASK)
65
+ drawing_area.connect('draw', self.on_draw)
66
+ drawing_area.connect('button-press-event', self.on_button_press_event)
67
+ drawing_area.connect('motion-notify-event', self.on_motion_notify_event)
68
+ drawing_area.connect('button-release-event', self.on_button_release_event)
69
+ window.add(drawing_area)
70
+ window.present()
71
+
72
+ def on_draw(self, widget, cr):
73
+ cr.save()
74
+
75
+ #self.draw1(cr)
76
+ self.draw2(cr)
77
+
78
+ cr.restore()
79
+
80
+ def draw1(self, cr):
81
+ cr.set_source_rgb(0, 0, 0)
82
+ for x, y in self.points:
83
+ cr.rectangle(x, y, 1, 1)
84
+ cr.fill()
85
+
86
+ def draw2(self, cr):
87
+ cr.set_source_rgb(0, 0, 0)
88
+ for x, y in self.points:
89
+ cr.rectangle(x, y, 1, 1)
90
+ cr.fill()
91
+
92
+ def on_button_press_event(self, widget, ev):
93
+ if ev.type == Gdk.EventType.BUTTON_PRESS and ev.button == Gdk.BUTTON_PRIMARY:
94
+ self.points += [(int(ev.x), int(ev.y))]
95
+ widget.queue_draw()
96
+ self.dragging = True
97
+ return True
98
+ return False
99
+
100
+ def on_motion_notify_event(self, widget, ev):
101
+ if self.dragging:
102
+ self.points += [(int(ev.x), int(ev.y))]
103
+ widget.queue_draw()
104
+ return True
105
+ return False
106
+
107
+ def on_button_release_event(self, widget, ev):
108
+ if ev.type == Gdk.EventType.BUTTON_RELEASE and ev.button == Gdk.BUTTON_PRIMARY:
109
+ self.dragging = False
110
+ return True
111
+ return False
112
+
113
+ if __name__ == '__main__':
114
+ App().run()
115
+ ```
116
+
117
+ …と思って上記のサンプルを書きましたけど、本当に重いですか?
118
+ うちのPCはCorei3のそんなにいいPCではありませんですけど、`draw1`でも全然遅い感じはしなかったのですが。
119
+
120
+ もしそれでもダメであれば、`cairo_image_surface`に点を書いておいて、通常の`draw`シグナルで処理する場合はそのsurfaceを描画するようにするのも常套手段かと思います。
121
+ もっとも、ウィンドウリサイズ時の処理がめんどくさそうですが。