質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.49%
Kivy

Kivyは、Pythonを用いたNUI開発のためのオープンソースフレームワーク。マルチタッチなど多くの入力に対応したNUIアプリなどを開発することができます。多くの環境で動作するクロスプラットフォームです。

OpenCV

OpenCV(オープンソースコンピュータービジョン)は、1999年にインテルが開発・公開したオープンソースのコンピュータビジョン向けのクロスプラットフォームライブラリです。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

1回答

972閲覧

Python Kivy で描いた領域を塗りつぶしたい

matsukosan

総合スコア5

Kivy

Kivyは、Pythonを用いたNUI開発のためのオープンソースフレームワーク。マルチタッチなど多くの入力に対応したNUIアプリなどを開発することができます。多くの環境で動作するクロスプラットフォームです。

OpenCV

OpenCV(オープンソースコンピュータービジョン)は、1999年にインテルが開発・公開したオープンソースのコンピュータビジョン向けのクロスプラットフォームライブラリです。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2020/01/19 11:31

編集2020/01/20 12:08

前提・実現したいこと

Python Kivyの勉強のため、kivy_garden.painterでお絵かきアプリを作ろうとしています。
公式exampleの通りに実行すれば線は描画できますが、DEMO動画
https://www.youtube.com/watch?v=gsqgfqunKkg
の「Fill」機能が実現できません。

発生している問題・エラーメッセージ

AttributeError: 'PainterWidget' object has no attribute 'add_area_graphics'

該当のソースコード

kivy_painter.py

Python

1 2from kivy.app import App 3from kivy.lang import Builder 4from kivy.uix.widget import Widget 5from kivy.uix.behaviors.focus import FocusBehavior 6from kivy_garden.painter import PaintCanvasBehavior, PaintShape 7from kivy.graphics.texture import Texture 8from kivy.graphics import Rectangle 9from kivy.uix.boxlayout import BoxLayout 10from kivy.uix.button import Button 11from kivy.uix.widget import Widget 12from kivy.uix.image import Image 13 14class PainterWidget(PaintCanvasBehavior, FocusBehavior, Widget, PaintShape): 15 def create_shape_with_touch(self, touch): 16 shape = super(PainterWidget, self).create_shape_with_touch(touch) 17 if shape is not None: 18 shape.add_shape_to_canvas(self) 19 return shape 20 21 def add_shape(self, shape): 22 if super(PainterWidget, self).add_shape(shape): 23 print(shape) 24 shape.add_shape_to_canvas(self) 25 return True 26 return False 27 28 29class MainScreen(BoxLayout): 30 def __init__(self, **kwargs): 31 super().__init__(**kwargs) 32 33 34class MyApp(App): 35 def build(self): 36 MS = MainScreen() 37 return MS 38 39 40if __name__ == '__main__': 41 Builder.load_file('kivy_painter.kv') 42 MyApp().run()

kivy_painter.kv

kivy

1#:kivy 1.11.1 2 3<MainScreen>: 4 BoxLayout: 5 orientation: 'vertical' 6 7 PainterWidget: 8 id: painter_widget 9 group: 'group_p' 10 draw_mode: mode.text or 'freeform' 11 locked: lock.state == 'down' 12 multiselect: multiselect.state == 'down' 13 canvas.before: 14 Color: 15 rgba: 0, 1, 1, 0 # unabled 16 Rectangle: 17 pos: self.pos 18 size: self.size 19 20 BoxLayout: 21 size_hint_y: None 22 height: "50dp" 23 spacing: '20dp' 24 Spinner: 25 id: mode 26 values: ['circle', 'ellipse', 'polygon', 'freeform', 'none'] 27 text: 'freeform' 28 ToggleButton: 29 id: lock 30 text: "Lock" 31 ToggleButton: 32 id: multiselect 33 text: "Multi-select" 34 Button: 35 text: 'clear' 36 on_release: painter_widget.canvas.clear() 37 Button: 38 text: 'fill' 39 on_release: painter_widget.add_area_graphics('group_p', painter_widget.canvas) 40

試したこと

https://kivy-garden.github.io/painter/flower.html#painter-widget
の add_area_graphics_to_canvas(name, canvas)
が該当すると考えましたが、
AttributeError: 'PainterWidget' object has no attribute 'add_area_graphics'
となってしまいました。

代案として、opencvのcv2.floodFillを検討しましたが、塗りつぶし開始地点を手動で指定せねばならず、自動で塗りつぶすアルゴリズムを考え付くことができませんでした。

kivy_garden.painter以外でも、描いた領域を塗りつぶす方法がありましたらご教授願いたいです。
よろしくお願いします。

補足情報(FW/ツールのバージョンなど)

Windows10
python==3.6.7
kivy==1.11.1
kivy-garden.painter==0.2.0

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

add_area_graphics_to_canvas(name, canvas)
が該当すると考えましたが、
AttributeError: 'PainterWidget' object has no attribute 'add_area_graphics'
となってしまいました。

add_area_graphics_to_canvasが該当すると考えたのに何故add_area_graphicsを呼ぼうとしたのですか?

methodの名前と持ち主を確かめると良いと思いますよ。

投稿2020/01/22 08:44

編集2020/01/24 13:21
gottadiveintopy

総合スコア736

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

matsukosan

2020/01/25 13:28

ご回答ありがとうございます。 ミスに気付きadd_area_graphics_to_canvasに書き換えましたが、今度は NotImplementedError となってしまいました。 super(PainterWidget, self). しろということだと考えましたが、 どの相手をsuperすればいいか理解できませんでした。 すみませんが、こちらのやり方を教えていただいても良いでしょうか?
gottadiveintopy

2020/01/27 13:46 編集

えっとNotImplementedErrorは上書きすべき関数をしていない時に起こるのですが、今回の場合kivy_garden.painter側のcodeの`add_area_graphics_to_canvas()`から起きているのでadd_area_graphics_to_canvas()という名前の関数を上書きしろと言っています。それで何故そう言われているかというとPainterWidgetがPaintShapeを継承しているからです。PaintShapeは図形を表す抽象classなのでその派生classは具体的な描画の手順を実装しないといけないわけです。じゃあそうすればいいのかというと違っていて、そもそもPaintWidgetがPaintCanvasBehaviorとPaintShapeを同時に継承しているのが間違いです。 PaintCanvasBehaviorは絵を描く対象であるキャンバスが継承すべき物で PaintShapeはキャンバスに描かれる各図形が継承すべき物 なので全くの別物です。PaintShapeはkivy_garden.painter側が用意していない類の図形を自分で用意したい時に継承する物なので今回はしなくていいと思います。後は公式のcodeを真似していくと良いと思いますよ。 https://github.com/kivy-garden/painter/blob/master/kivy_garden/painter/__init__.py#L2210 link先の 「if __name__ == '__main__':」より上がlibrary側の実装codeで、下がlibraryを使う側のcodeになっているので参考にしてみてください。 (コマンドラインで python -m kivy_garden.painter.__init__ と打てば実際に動かすこともできます。)
matsukosan

2020/01/30 09:19

実践できず遅くなってしまいました。 ご回答ありがとうございます! リンク先を参照し、各shapeにcolor groupを設定し、そのshapeにadd_area_graphics_to_canvasを適用することで着色できるとわかりました。 いつもQiitaの記事など参考にさせていただいています。 ありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.49%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問