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

質問編集履歴

5

サンプルコードへ補足

2021/03/25 21:15

投稿

nanikamado
nanikamado

スコア13

title CHANGED
File without changes
body CHANGED
@@ -25,8 +25,10 @@
25
25
  flamegraphで各関数の実行にかかっている時間を調べると、次のようになりました。rectangleとfillにかなりの時間がかかっています。
26
26
  ![flamegraph](b59b0411514c9874b07402731735d54b.png)
27
27
 
28
- Pythonによるサンプルも追記します。@katsukoさんが書いてくださったサンプルコードを少し書き換えたものです。私が書いているRustのコードを全部載せても良いのですが、@katsukoさんのPythonによるコードがとても簡潔で、こちらを使った方が分かりやすいと思ったので、このようにしました。実行するとかくついているのが分かると思います。
28
+ Pythonによるサンプルも追記します。@katsukoさんが書いてくださったサンプルコードを少し書き換えたものです。私が書いているRustのコードを全部載せても良いのですが、@katsukoさんのPythonによるコードがとても簡潔で、こちらを使った方が分かりやすいと思ったので、このようにしました。
29
29
 
30
+ 簡単にするために、このサンプルでは点を1つ打つごとに全ピクセルを描画し直していますが、Rustで書いているものでは更新があった場所だけ描画しています。なので点を打つのはもっと速いです。ですが、ウインドウをリサイズした時にはこのサンプルと同じように全ピクセルを描画し直しています。リサイズ時の重さは同じくらいです。
31
+
30
32
  ```python
31
33
  # coding: utf-8
32
34
 

4

Markdownの修正

2021/03/25 21:15

投稿

nanikamado
nanikamado

スコア13

title CHANGED
File without changes
body CHANGED
@@ -23,7 +23,7 @@
23
23
 
24
24
  ### 追記
25
25
  flamegraphで各関数の実行にかかっている時間を調べると、次のようになりました。rectangleとfillにかなりの時間がかかっています。
26
- ![![flamegraph](b59b0411514c9874b07402731735d54b.png)](6d2ed4da3229d39efb9be244db0126ad.png)
26
+ ![flamegraph](b59b0411514c9874b07402731735d54b.png)
27
27
 
28
28
  Pythonによるサンプルも追記します。@katsukoさんが書いてくださったサンプルコードを少し書き換えたものです。私が書いているRustのコードを全部載せても良いのですが、@katsukoさんのPythonによるコードがとても簡潔で、こちらを使った方が分かりやすいと思ったので、このようにしました。実行するとかくついているのが分かると思います。
29
29
 

3

サンプルコードを追記

2021/03/25 19:04

投稿

nanikamado
nanikamado

スコア13

title CHANGED
File without changes
body CHANGED
@@ -19,4 +19,101 @@
19
19
 
20
20
  これらの条件を満たすGUIライブラリが、GtkとQtしか見つかりませんでした。QtのRustバインディングは更新が止まっていて、ドキュメントもexample以外にはほとんどなかったので、GUI初心者には厳しいと思い、Gtkにしました。
21
21
 
22
- もしGTKの`GLArea`にOpenGLで描画する以外におすすめの方法があれば、それも教えてほしいです。
22
+ もしGTKの`GLArea`にOpenGLで描画する以外におすすめの方法があれば、それも教えてほしいです。
23
+
24
+ ### 追記
25
+ flamegraphで各関数の実行にかかっている時間を調べると、次のようになりました。rectangleとfillにかなりの時間がかかっています。
26
+ ![![flamegraph](b59b0411514c9874b07402731735d54b.png)](6d2ed4da3229d39efb9be244db0126ad.png)
27
+
28
+ Pythonによるサンプルも追記します。@katsukoさんが書いてくださったサンプルコードを少し書き換えたものです。私が書いているRustのコードを全部載せても良いのですが、@katsukoさんのPythonによるコードがとても簡潔で、こちらを使った方が分かりやすいと思ったので、このようにしました。実行するとかくついているのが分かると思います。
29
+
30
+ ```python
31
+ # coding: utf-8
32
+
33
+ import cairo
34
+ import gi
35
+ gi.require_version('Gtk', '3.0')
36
+ from gi.repository import Gtk, Gdk
37
+
38
+ class App(Gtk.Application):
39
+ def __init__(self, **kwargs):
40
+ super().__init__(**kwargs)
41
+ self.points = []
42
+ self.canvas = [[(1, 1, 1)] * 300 for _ in range(400)]
43
+ self.dragging = False
44
+
45
+ def do_activate(self):
46
+ window = Gtk.Window(application=self, default_width=400, default_height=300)
47
+ drawing_area = Gtk.DrawingArea(visible=True)
48
+ drawing_area.add_events(Gdk.EventMask.BUTTON_PRESS_MASK | Gdk.EventMask.POINTER_MOTION_MASK | Gdk.EventMask.BUTTON_RELEASE_MASK)
49
+ drawing_area.connect('draw', self.on_draw)
50
+ drawing_area.connect('button-press-event', self.on_button_press_event)
51
+ drawing_area.connect('motion-notify-event', self.on_motion_notify_event)
52
+ drawing_area.connect('button-release-event', self.on_button_release_event)
53
+ window.add(drawing_area)
54
+ window.present()
55
+
56
+ def on_draw(self, widget, cr):
57
+ cr.save()
58
+
59
+ #self.draw1(cr)
60
+ #self.draw2(cr)
61
+ self.draw3(cr)
62
+
63
+ cr.restore()
64
+
65
+ def draw1(self, cr):
66
+ cr.set_source_rgb(0, 0, 0)
67
+ for x, y in self.points:
68
+ cr.rectangle(x, y, 1, 1)
69
+ cr.fill()
70
+
71
+ def draw2(self, cr):
72
+ cr.set_source_rgb(0, 0, 0)
73
+ for x, y in self.points:
74
+ cr.rectangle(x, y, 1, 1)
75
+ cr.fill()
76
+
77
+ def draw3(self, cr):
78
+ for x, v in enumerate(self.canvas):
79
+ for y, color in enumerate(v):
80
+ cr.set_source_rgb(*color)
81
+ cr.rectangle(x, y, 1, 1)
82
+ cr.fill()
83
+
84
+ def on_button_press_event(self, widget, ev):
85
+ if ev.type == Gdk.EventType.BUTTON_PRESS and ev.button == Gdk.BUTTON_PRIMARY:
86
+ self.points += [(int(ev.x), int(ev.y))]
87
+ for x in range(int(ev.x), int(ev.x)+5):
88
+ for y in range(int(ev.y),int(ev.y)+5):
89
+ try:
90
+ self.canvas[x][y] = (1, 0, 0)
91
+ except:
92
+ pass
93
+ widget.queue_draw()
94
+ self.dragging = True
95
+ return True
96
+ return False
97
+
98
+ def on_motion_notify_event(self, widget, ev):
99
+ if self.dragging:
100
+ self.points += [(int(ev.x), int(ev.y))]
101
+ for x in range(int(ev.x), int(ev.x)+5):
102
+ for y in range(int(ev.y),int(ev.y)+5):
103
+ try:
104
+ self.canvas[x][y] = (1, 0, 0)
105
+ except:
106
+ pass
107
+ widget.queue_draw()
108
+ return True
109
+ return False
110
+
111
+ def on_button_release_event(self, widget, ev):
112
+ if ev.type == Gdk.EventType.BUTTON_RELEASE and ev.button == Gdk.BUTTON_PRIMARY:
113
+ self.dragging = False
114
+ return True
115
+ return False
116
+
117
+ if __name__ == '__main__':
118
+ App().run()
119
+ ```

2

日本語を修正

2021/03/25 19:03

投稿

nanikamado
nanikamado

スコア13

title CHANGED
File without changes
body CHANGED
@@ -6,7 +6,7 @@
6
6
 
7
7
  Rustでお絵かきソフトを作ろうとしています。
8
8
 
9
- Gtk-rsでGUIをつくり、入力イベントからビットマップを作って、それをGTKの`DrawingArea`に表示させようと考えました。`DrawingArea`にはcairoを使って書き込むことになるのですが、どうやらcairoには1ピクセルを描画する関数は無いようで、`cairo::Context::rectangle()`と`cairo::Context::fill()`を使うか、`cairo::Context::move_to()`と`cairo::Context::stroke()`を使うかしなければいけないようです。
9
+ まずGtk-rsでGUIをつくり、入力イベントを元に画像を作って、それをGTKの`DrawingArea`に表示させてみました。`DrawingArea`にはcairoを使って書き込むことになるのですが、どうやらcairoには1ピクセルを描画する関数は無いようで、`cairo::Context::rectangle()`と`cairo::Context::fill()`を使うか、`cairo::Context::move_to()`と`cairo::Context::stroke()`を使うかしなければいけないようです。
10
10
 
11
11
  `cairo::Context::rectangle()`と`cairo::Context::fill()`を使って書いてみたのですが、これらはかなり遅いです。細い線などを描く場合は問題なさそうなのですが、ウインドウをリサイズして全体を描画し直したりする場合はかくつきます。
12
12
 

1

日本語を修正

2021/03/25 13:05

投稿

nanikamado
nanikamado

スコア13

title CHANGED
File without changes
body CHANGED
@@ -17,6 +17,6 @@
17
17
  - ペンタブから筆圧の情報を渡してくれる
18
18
  - Rustから使える
19
19
 
20
- これらの条件を満たすGUIライブラリが、GtkとQtしか見つかりませんでした。QtのRustバインディングは更新が止まっていて、example以外にはドキュメントもほとんどなかったので、GUI初心者には厳しいと思い、Gtkにしました。
20
+ これらの条件を満たすGUIライブラリが、GtkとQtしか見つかりませんでした。QtのRustバインディングは更新が止まっていて、ドキュメントもexample以外にはほとんどなかったので、GUI初心者には厳しいと思い、Gtkにしました。
21
21
 
22
22
  もしGTKの`GLArea`にOpenGLで描画する以外におすすめの方法があれば、それも教えてほしいです。