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

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

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

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

Q&A

解決済

2回答

8235閲覧

wxPythonにおける、wx.StaticBitmapとwx.PaintDCの使い分け

退会済みユーザー

退会済みユーザー

総合スコア0

Python

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

0グッド

3クリップ

投稿2017/05/12 15:23

###前提・実現したいこと
wyPythonを使って、画像や動画などを表示させ、その横にテキストボックスをくっつけて(または画像にstringをかぶせるなどの方法で)動くGUIを作っています。

###実現する方法
いろいろ調べていくうちに、GUI上にイメージを表示させる方法として以下の二つがあることが分かりました。

  • wx.StaticBitmapを使う方法
  • wx.PaintDCを使う方法

現在使っている方法は、wx.StaticBitmapを使う方法です。こちらの方が行数が少なくて済むので読みやすいのかな?と私は思っています。

参考)はてな上の、white_wheelsさんのコード例

###教えて頂きたいこと
画像を表示させる方法が2つ(以上?)ある中で、これらをどのように使い分けるのが良いのでしょうか?それぞれのメリット・デメリットがあれば教えて頂きたいです。

###補足情報(言語/FW/ツール等のバージョンなど)
Win10(64bit)
Python 3.5.3(64bit)
wxPython 4.0.0a1 (Phoenix)

// 一応、日本語と英語でこの内容をgoogle検索しましたが、使い分けの部分がよくわかりませんでした。

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

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

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

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

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

guest

回答2

0

ベストアンサー

特に困っていなければ、 wx.StaticBitmap を使えば良いと思います。もしも、 wx.StaticBitmap の機能で満足できない点があったり、複雑な描画制御を行いたくなった場合には wx.PaintDC の利用を検討してください。

TL;DR

wx.StaticBitmap

  • 画像を表示する機能を持ったコントロール (ウィンドウの一種) であり、他のコントロールと同じように扱うことができる
  • wx.Bitmap を渡すだけで描画してくれるので使いやすいが、細かい制御は効かない

wx.PaintDC

  • デバイスコンテキストという、ウィンドウ内部に実際にグラフィックを描画するためのローレベルな API である
  • 単体で使うことは出来ず、まず描画対象のウィンドウを用意し、そこからデバイスコンテキストを取得して使う
  • ローレベルなためコード量は増えるし、簡単には扱えないが、自由度は高い

両者の違い

wxPython は wxWidgets のラッパーなので、「あるクラスはどういう機能を持ち、何の目的で存在するのか?」という疑問を持った場合は、 wxWidgets のクラスリファレンスを参照するのが良いと思います。今回は wx.StaticBitmapwx.PaintDC ですから、以下のドキュメントが該当します。

上記 URL でそれぞれのクラスの継承ツリーをご覧いただくと、ぱっと見でも両者は全く違った存在であることが分かります。 wxStaticBitmap は見慣れた wxWindow / wxControl の系譜に属する コントロール (ウィンドウの一種) であるのに対し、 wxPaintDCwxDC という (恐らくは) あまり見慣れないクラスから継承されていて、 ウィンドウですらない、何か別の存在 であることが分かります。

少なくとも、単純に「画像を表示させる機能が 2 つある」 わけではない ということです。

では、具体的にどう違うのかというと、まず分かりやすい wxStaticBitmap の方は 「画像を表示する機能」をまとめたコントロールの一種 です。コントロールというのは、ボタン (wxButton) や入力ボックス (wxTextCtrl) ような良く使う機能を再利用可能なウィンドウとしてまとめたもので、その一つに「画像を表示する」機能が wxStaticBitmap として用意されているということです。ボタンなどと同様に、ぺたぺた貼り付けるだけで動いてくれますから使いやすいですし、基本的にはこちらを使えば良いと思います。

一方で、 wxPaintDC の「DC」とは、 デバイスコンテキスト と呼ばれる概念を指しています。このデバイスコンテキストとは何かについては、一応 wxWidgets のドキュメント にも記載はあるのですが、簡単に言えば 「ペン・塗りつぶし・テキストなどのツールを使って、自由にグラフィックを描くことのできるキャンバス」 のようなものと表現できると思います。イメージとしては、お絵かきソフト (Windows のペイント等) が近いですね。

これだけでは何のための存在かわかりづらいと思いますが、実のところデバイスコンテキストというのは、 ウィンドウが実際に自らの姿を描くために使っている、ローレベルな内部 API です。御存じの通り、ウィンドウというのはボタンやタイトルバー等、その種類や部分によってさまざまな "姿" をしています。そこで GUI 環境を提供するコアシステムは、デバイスコンテキストという「なんでも描けるキャンバスとツールのセット」を共通の API として各ウィンドウに提供し、ウィンドウ側はその API を使って自分の姿を描く仕組みになっています。ボタンがクリックされるとへこんだり、 wxStaticBitmap が画像を表示したり、そういったコントロールの振る舞いも、全てはそれらのコントロールが 予め実装された通りにデバイスコンテキストへと描画を行った結果 だということです。
(※ wxWidgets はクロスプラットフォームなライブラリなので、実際のプラットフォームによっては、デバイスコンテキストに相当する概念の有無や動作などが厳密には異なる場合があります)

さて、そんなローレベルな API なので、本当にやろうと思えば何でもできます。例えば、ご呈示の URL に掲載されているサンプルコードでは、 wxStaticBitmap が内部でやっているのと同じデバイスコンテキスト操作を、自分で実装する ことで画像を表示しています。さらにやろうと思えば、複数の画像を重ねたり、画像の上にテキストや図形を表示することも可能でしょう。そういう複雑な描画が行いたい場合は、 wxStaticBitmap の機能では足りませんから、直接 wxPaintDC を使って自分で描画する必要があります。

ただし、「なんでもできるローレベルな API」は、「ローレベル故に使うのが大変」です。提供される操作は単純なものばかりなので、複雑なことをやるためには単純に手数が多くかかります。デバイスコンテキストはウィンドウに対して与えられるものですから、そのウィンドウを確保する必要もあります。また、描画のタイミングについても、GUI システムと協調して行うよう気を使わなければなりません。このあたりの面倒さが、仰るような「 wxPaintDC を使う方法は、wxStaticBitmap よりもコード行数が長くなる」あたりに表れていると言えると思いますので、必要が無ければ基本的には使わない、という方針で行くことをオススメします。

参考: wxStaticBitmap と wxPaintDC の関係

ちなみに、先ほど「 wxStaticBitmap が画像を表示するのにも、内部では wxPaintDC が使われている」と述べましたが、このことは次のような wxWidgets のソースコードを見ると確認できます。

wxGenericStaticBitmap::OnPaint

wxGenericStaticBitmap というのは、 wxStaticBitmap 相当の機能がプラットフォームでネイティブに提供されていない場合に使われる wxStaticBitmap の実装です。この OnPaint() イベントハンドラにて、実際に wxPaintDC を取得してから、 wxPaintDC.DrawBitmap によって wxBitmap を描画している様子が見て取れると思います。

投稿2017/05/13 19:42

argparse

総合スコア1017

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

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

退会済みユーザー

退会済みユーザー

2017/05/14 00:07

argparse様 大変詳しい説明をありがとうございました。 wxPythonがwxWidgets のラッパーということすら知らずに使っていましたので、頂いたご回答からPython側から見えないところで何が起きているのか見ることができました。比べるのがナンセンスなくらいに両者が違っているために、今まで誰も質問してこなかった内容だった、と今更ながら感じています。 今作ろうとしているものはwxStaticBitmapで動いていますが、今後を見据えてwx.PaintDCに切り替えていきたいと思います。今後ともよろしくお願いいたします。
guest

0

自己解決、と呼べるほどすっきりする回答ではありませんが、それらしい情報がありましたので載せます。

Alpha channel付きPNG画像を表示したい人のへの回答@Robin Dunnさん

方法メリットデメリット
wx.StaticBitmapデフォルトの背景で画像を表示するには一番シンプル凝った背景の画像を用意できない
wx.PaintDC画像の後ろに何かしらの背景を仕込む場合やアルファチャンネル付きで処理したい場合はこっちwx.StaticBitmapよりコードが長くなる

//まだまだ解決しきった感が感じられませんので、もしツッコミがをお持ちの方がいましたらコメントお願いします。

投稿2017/05/13 13:37

編集2017/05/13 13:40
退会済みユーザー

退会済みユーザー

総合スコア0

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問