2016/12/03(土) [n年前の日記]
#1 [python] PySideのQRubberBandの動作確認
PySideのQRubberBandの動作確認中。
_rubberband_test.py
テスト画像。 _tmp_bg.png
こんな感じになった。
動かしてみて分かったけれど、これはグラフィックツール等で使うタイプの選択範囲のソレじゃないなと。おそらく用途としては、エクスプローラ等でファイル選択する時に使う系のラバーバンド、ではないかと。グラフィックツール用のソレが欲しい場合は、自分で実装しないとダメっぽい。
_rubberband_test.py
u""" QRubberBandの動作確認. 動作確認環境 : Windows10 x64 + Python 2.7.12 + PySide 1.2.4 """ import sys from PySide.QtCore import * # NOQA from PySide.QtGui import * # NOQA class GView(QGraphicsView): """Graphics View.""" def __init__(self, *argv, **keywords): """init.""" super(GView, self).__init__(*argv, **keywords) scene = QGraphicsScene(self) self.setScene(scene) pm = QPixmap("./tmp_bg.png") pm_item = QGraphicsPixmapItem(pm) scene.addItem(pm_item) # ラバーバンドを生成 self.rband = QRubberBand(QRubberBand.Rectangle, self) self.start_pos = QPoint() def mousePressEvent(self, event): u"""マウスボタンが押された.""" if event.button() == Qt.LeftButton: # 左ボタンが押された self.start_pos = event.pos() # クリックした座標を記憶 rect = QRect(self.start_pos, QSize()) self.rband.setGeometry(rect) # ラバーバンドの範囲を設定 self.rband.show() # ラバーバンドを表示 p0 = self.mapToScene(self.start_pos) x0 = p0.x() y0 = p0.y() self.set_status("(%d, %d)" % (x0, y0)) elif event.button() == Qt.RightButton: # 右ボタンが押された self.rband.hide() # ラバーバンドを非表示に def mouseMoveEvent(self, event): u"""マウスカーソルが動いた.""" if not self.start_pos.isNull(): # マウスクリック後の状態 rect = QRect(self.start_pos, QPoint(event.pos())).normalized() self.rband.setGeometry(rect) # ラバーバンドの範囲を再設定 # ステータスバー相当に座標を表示 p0 = self.mapToScene(self.start_pos) x0 = p0.x() y0 = p0.y() p1 = self.mapToScene(event.pos()) x1 = p1.x() y1 = p1.y() dx = abs(x1 - x0) dy = abs(y1 - y0) self.set_status("(%d, %d) - (%d, %d) : (%d x %d)" % (x0, y0, x1, y1, dx, dy)) def mouseReleaseEvent(self, event): u"""マウスボタンが離された.""" if event.button() == Qt.LeftButton: self.start_pos = QPoint() def set_status(self, str): u"""ステータスバー相当のテキストを設定.""" self.parent().set_status(str) class MyWidget(QWidget): u"""メインウインドウ相当.""" def __init__(self, *argv, **keywords): """init.""" super(MyWidget, self).__init__(*argv, **keywords) self.gview = GView(self) self.lbl = QLabel("Ready", self) l = QVBoxLayout() l.addWidget(self.gview) l.addWidget(self.lbl) self.setLayout(l) def set_status(self, str): u"""ステータスバー相当にテキストを設定.""" self.lbl.setText(str) if __name__ == '__main__': app = QApplication(sys.argv) w = MyWidget() w.show() sys.exit(app.exec_())
テスト画像。 _tmp_bg.png
こんな感じになった。
動かしてみて分かったけれど、これはグラフィックツール等で使うタイプの選択範囲のソレじゃないなと。おそらく用途としては、エクスプローラ等でファイル選択する時に使う系のラバーバンド、ではないかと。グラフィックツール用のソレが欲しい場合は、自分で実装しないとダメっぽい。
◎ グラフィックツール用の選択範囲に求められる仕様。 :
グラフィックツール用の選択範囲に求められる仕様としては…。
蟻の行進(Marching ants)てのは、以下が参考になるかと。2D画像編集ツールを使ってる人なら「あー、ハイハイ。アレか」と分かるはず。
_Marching ants - Wikipedia
_Fun with marching ants - Banu Blog
実は意外と実装が面倒…のような気がする。
- 矩形の境界線だけ描いてあればいい。中は塗り潰しをしなくても構わない。
- 境界線は、蟻の行進(Marching ants)か、XOR表示が望ましい。
- 境界線の上にマウスカーソルを合わせてドラッグすると、境界線の位置を変更できたりするとありがたい。
蟻の行進(Marching ants)てのは、以下が参考になるかと。2D画像編集ツールを使ってる人なら「あー、ハイハイ。アレか」と分かるはず。
_Marching ants - Wikipedia
_Fun with marching ants - Banu Blog
実は意外と実装が面倒…のような気がする。
[ ツッコむ ]
#2 [cg_tools] 各種CGツールの選択範囲の境界線について
ふと気になったので確認してみて知ったのだけど。Windows10 のペイントの選択範囲って、只の点線なのですな。蟻の行進とかしていない。フツーはこれでも十分、だったりするのだろうか。
下地の色に応じて点線の色が変わってるのかと一瞬思ったけど、拡大表示して確認したら、点線は白と青の色で固定してある模様。下地が一色でベタ塗りされているなら、白か青のどちらかで、そこに境界線があると分かるだろう…と考えて、この仕様にしたのかもしれず。
ちなみに、Paint.NET の選択範囲を確認したら、こちらはきっちりと蟻の行進をしているようで。どういう処理をしているんだろう…。パターンで一部を塗り潰し、ではなくて、線として描いているのかな…。
ついでに、Photoshop Elements 8.0 と GIMP 2.8.18 の選択範囲の境界線を確認してみたら、こちらはパターンで塗り潰してるタイプに見えた。斜めの境界線ではちょっと見づらくなるソレというか。
実際に動いてるところを見たほうが分かりやすいのだろうか。試しにキャプチャしてみたり。
以下は、Paint.NET。
以下は、Photoshop Elements 8.0。
以下は、GIMP 2.8.18。
まあ、とりあえず、色々な見た目があるようで。
下地の色に応じて点線の色が変わってるのかと一瞬思ったけど、拡大表示して確認したら、点線は白と青の色で固定してある模様。下地が一色でベタ塗りされているなら、白か青のどちらかで、そこに境界線があると分かるだろう…と考えて、この仕様にしたのかもしれず。
ちなみに、Paint.NET の選択範囲を確認したら、こちらはきっちりと蟻の行進をしているようで。どういう処理をしているんだろう…。パターンで一部を塗り潰し、ではなくて、線として描いているのかな…。
ついでに、Photoshop Elements 8.0 と GIMP 2.8.18 の選択範囲の境界線を確認してみたら、こちらはパターンで塗り潰してるタイプに見えた。斜めの境界線ではちょっと見づらくなるソレというか。
実際に動いてるところを見たほうが分かりやすいのだろうか。試しにキャプチャしてみたり。
以下は、Paint.NET。
以下は、Photoshop Elements 8.0。
以下は、GIMP 2.8.18。
まあ、とりあえず、色々な見た目があるようで。
[ ツッコむ ]
以上、1 日分です。