質問編集履歴

5

サンプルコードへ補足

2021/03/25 21:15

投稿

nanikamado
nanikamado

スコア13

test CHANGED
File without changes
test CHANGED
@@ -52,7 +52,11 @@
52
52
 
53
53
 
54
54
 
55
- Pythonによるサンプルも追記します。@katsukoさんが書いてくださったサンプルコードを少し書き換えたものです。私が書いているRustのコードを全部載せても良いのですが、@katsukoさんのPythonによるコードがとても簡潔で、こちらを使った方が分かりやすいと思ったので、このようにしました。実行するとかくついているのが分かると思います。
55
+ Pythonによるサンプルも追記します。@katsukoさんが書いてくださったサンプルコードを少し書き換えたものです。私が書いているRustのコードを全部載せても良いのですが、@katsukoさんのPythonによるコードがとても簡潔で、こちらを使った方が分かりやすいと思ったので、このようにしました。
56
+
57
+
58
+
59
+ 簡単にするために、このサンプルでは点を1つ打つごとに全ピクセルを描画し直していますが、Rustで書いているものでは更新があった場所だけ描画しています。なので点を打つのはもっと速いです。ですが、ウインドウをリサイズした時にはこのサンプルと同じように全ピクセルを描画し直しています。リサイズ時の重さは同じくらいです。
56
60
 
57
61
 
58
62
 

4

Markdownの修正

2021/03/25 21:15

投稿

nanikamado
nanikamado

スコア13

test CHANGED
File without changes
test CHANGED
@@ -48,7 +48,7 @@
48
48
 
49
49
  flamegraphで各関数の実行にかかっている時間を調べると、次のようになりました。rectangleとfillにかなりの時間がかかっています。
50
50
 
51
- ![![flamegraph](b59b0411514c9874b07402731735d54b.png)](6d2ed4da3229d39efb9be244db0126ad.png)
51
+ ![flamegraph](b59b0411514c9874b07402731735d54b.png)
52
52
 
53
53
 
54
54
 

3

サンプルコードを追記

2021/03/25 19:04

投稿

nanikamado
nanikamado

スコア13

test CHANGED
File without changes
test CHANGED
@@ -41,3 +41,197 @@
41
41
 
42
42
 
43
43
  もしGTKの`GLArea`にOpenGLで描画する以外におすすめの方法があれば、それも教えてほしいです。
44
+
45
+
46
+
47
+ ### 追記
48
+
49
+ flamegraphで各関数の実行にかかっている時間を調べると、次のようになりました。rectangleとfillにかなりの時間がかかっています。
50
+
51
+ ![![flamegraph](b59b0411514c9874b07402731735d54b.png)](6d2ed4da3229d39efb9be244db0126ad.png)
52
+
53
+
54
+
55
+ Pythonによるサンプルも追記します。@katsukoさんが書いてくださったサンプルコードを少し書き換えたものです。私が書いているRustのコードを全部載せても良いのですが、@katsukoさんのPythonによるコードがとても簡潔で、こちらを使った方が分かりやすいと思ったので、このようにしました。実行するとかくついているのが分かると思います。
56
+
57
+
58
+
59
+ ```python
60
+
61
+ # coding: utf-8
62
+
63
+
64
+
65
+ import cairo
66
+
67
+ import gi
68
+
69
+ gi.require_version('Gtk', '3.0')
70
+
71
+ from gi.repository import Gtk, Gdk
72
+
73
+
74
+
75
+ class App(Gtk.Application):
76
+
77
+ def __init__(self, **kwargs):
78
+
79
+ super().__init__(**kwargs)
80
+
81
+ self.points = []
82
+
83
+ self.canvas = [[(1, 1, 1)] * 300 for _ in range(400)]
84
+
85
+ self.dragging = False
86
+
87
+
88
+
89
+ def do_activate(self):
90
+
91
+ window = Gtk.Window(application=self, default_width=400, default_height=300)
92
+
93
+ drawing_area = Gtk.DrawingArea(visible=True)
94
+
95
+ drawing_area.add_events(Gdk.EventMask.BUTTON_PRESS_MASK | Gdk.EventMask.POINTER_MOTION_MASK | Gdk.EventMask.BUTTON_RELEASE_MASK)
96
+
97
+ drawing_area.connect('draw', self.on_draw)
98
+
99
+ drawing_area.connect('button-press-event', self.on_button_press_event)
100
+
101
+ drawing_area.connect('motion-notify-event', self.on_motion_notify_event)
102
+
103
+ drawing_area.connect('button-release-event', self.on_button_release_event)
104
+
105
+ window.add(drawing_area)
106
+
107
+ window.present()
108
+
109
+
110
+
111
+ def on_draw(self, widget, cr):
112
+
113
+ cr.save()
114
+
115
+
116
+
117
+ #self.draw1(cr)
118
+
119
+ #self.draw2(cr)
120
+
121
+ self.draw3(cr)
122
+
123
+
124
+
125
+ cr.restore()
126
+
127
+
128
+
129
+ def draw1(self, cr):
130
+
131
+ cr.set_source_rgb(0, 0, 0)
132
+
133
+ for x, y in self.points:
134
+
135
+ cr.rectangle(x, y, 1, 1)
136
+
137
+ cr.fill()
138
+
139
+
140
+
141
+ def draw2(self, cr):
142
+
143
+ cr.set_source_rgb(0, 0, 0)
144
+
145
+ for x, y in self.points:
146
+
147
+ cr.rectangle(x, y, 1, 1)
148
+
149
+ cr.fill()
150
+
151
+
152
+
153
+ def draw3(self, cr):
154
+
155
+ for x, v in enumerate(self.canvas):
156
+
157
+ for y, color in enumerate(v):
158
+
159
+ cr.set_source_rgb(*color)
160
+
161
+ cr.rectangle(x, y, 1, 1)
162
+
163
+ cr.fill()
164
+
165
+
166
+
167
+ def on_button_press_event(self, widget, ev):
168
+
169
+ if ev.type == Gdk.EventType.BUTTON_PRESS and ev.button == Gdk.BUTTON_PRIMARY:
170
+
171
+ self.points += [(int(ev.x), int(ev.y))]
172
+
173
+ for x in range(int(ev.x), int(ev.x)+5):
174
+
175
+ for y in range(int(ev.y),int(ev.y)+5):
176
+
177
+ try:
178
+
179
+ self.canvas[x][y] = (1, 0, 0)
180
+
181
+ except:
182
+
183
+ pass
184
+
185
+ widget.queue_draw()
186
+
187
+ self.dragging = True
188
+
189
+ return True
190
+
191
+ return False
192
+
193
+
194
+
195
+ def on_motion_notify_event(self, widget, ev):
196
+
197
+ if self.dragging:
198
+
199
+ self.points += [(int(ev.x), int(ev.y))]
200
+
201
+ for x in range(int(ev.x), int(ev.x)+5):
202
+
203
+ for y in range(int(ev.y),int(ev.y)+5):
204
+
205
+ try:
206
+
207
+ self.canvas[x][y] = (1, 0, 0)
208
+
209
+ except:
210
+
211
+ pass
212
+
213
+ widget.queue_draw()
214
+
215
+ return True
216
+
217
+ return False
218
+
219
+
220
+
221
+ def on_button_release_event(self, widget, ev):
222
+
223
+ if ev.type == Gdk.EventType.BUTTON_RELEASE and ev.button == Gdk.BUTTON_PRIMARY:
224
+
225
+ self.dragging = False
226
+
227
+ return True
228
+
229
+ return False
230
+
231
+
232
+
233
+ if __name__ == '__main__':
234
+
235
+ App().run()
236
+
237
+ ```

2

日本語を修正

2021/03/25 19:03

投稿

nanikamado
nanikamado

スコア13

test CHANGED
File without changes
test CHANGED
@@ -14,7 +14,7 @@
14
14
 
15
15
 
16
16
 
17
- Gtk-rsでGUIをつくり、入力イベントからビットマップを作って、それをGTKの`DrawingArea`に表示させようと考えました。`DrawingArea`にはcairoを使って書き込むことになるのですが、どうやらcairoには1ピクセルを描画する関数は無いようで、`cairo::Context::rectangle()`と`cairo::Context::fill()`を使うか、`cairo::Context::move_to()`と`cairo::Context::stroke()`を使うかしなければいけないようです。
17
+ まずGtk-rsでGUIをつくり、入力イベントを元に画像を作って、それをGTKの`DrawingArea`に表示させてみました。`DrawingArea`にはcairoを使って書き込むことになるのですが、どうやらcairoには1ピクセルを描画する関数は無いようで、`cairo::Context::rectangle()`と`cairo::Context::fill()`を使うか、`cairo::Context::move_to()`と`cairo::Context::stroke()`を使うかしなければいけないようです。
18
18
 
19
19
 
20
20
 

1

日本語を修正

2021/03/25 13:05

投稿

nanikamado
nanikamado

スコア13

test CHANGED
File without changes
test CHANGED
@@ -36,7 +36,7 @@
36
36
 
37
37
 
38
38
 
39
- これらの条件を満たすGUIライブラリが、GtkとQtしか見つかりませんでした。QtのRustバインディングは更新が止まっていて、example以外にはドキュメントもほとんどなかったので、GUI初心者には厳しいと思い、Gtkにしました。
39
+ これらの条件を満たすGUIライブラリが、GtkとQtしか見つかりませんでした。QtのRustバインディングは更新が止まっていて、ドキュメントもexample以外にはほとんどなかったので、GUI初心者には厳しいと思い、Gtkにしました。
40
40
 
41
41
 
42
42