ベクタパス作成ツール 3 version 13
:追加された部分
:削除された部分
(差分が大きい場合、文字単位では表示しません)
PyQt でベクターオブジェクトパス作成ツールを作る 3
# 動作の構想 pselected = -2 pmoving = -1
190719
# 動作の構想
マウスオーバーでパスを青、ポイントも描画
if pselected==-1
ポイント位置にマウスが来たらポイントを赤くしてコントロールを二本描画
違うポイントに移るまでその状態を維持
if pselected >= 0 <--- pselected が -1 -2 になっても現在値を維持する
- マウスオーバーでパスを青、ポイントも描画、ただしコントロールポイントは描画しない
pselected : -1
- ポイント位置にマウスが来たらポイントを赤くしてコントロールを二本描画
違うポイントに移るまでその状態を維持
pselected >= 0 <--- pselected が -1 -2 になっても現在値を維持する
±1 でも現在値を維持する
ポイント位置でクリックでポイント選択
- ポイント位置でクリックでポイント選択
クリックした位置のヒット判定が0以上なら pmoving=それ
変数は二つ必要になる
# サブクラス
ポイントのrectは CP 含めて全て作成する
本体の描画ルーチンから呼ばれたら全て渡す
本体の描画ルーチンで判断して CP 以外を描画する
ヒット判定も全てのポイントで行う
閉じたパスを実装
フラグを持つ、閉じた場合で0が移動したら-1も同じ座標とする
- QPainterPath オブジェクトの派生クラスを作る
- ポイントのrectを CP 含めて全て作成する
本体の描画ルーチンからはクラスメンバとして参照させる
本体の描画ルーチンで判断して CP 以外を描画する
ヒット判定はメソッドとして呼び出す
- 閉じたパスを実装
フラグを持つ、閉じた場合で0が移動したら終点も同じ座標とする
- ポイント移動メソッドは既にあるが独自に実装して、コントロールポイントを含めた平行移動やシンメトリ移動を実装する
```
def init
self.pmoving=-1
def mouseMoveEvent(self ,e):
if self.pmoving == -1 : # not Dragging
l = self.path.contains_m( e.pos() ) <------------判定メソッド
if self.pselected >= 0 : # point selecting
if l >= self.pselected-1 and l <= self.pselected+1 :
return # same point -- ignore
else :
self.pselected = l # reselect point
else:
if self.pselected == l : # case of -1 -2 , same--ignore
return
else :
self.pselected = l
else : # dragging
self.path.movepoint( self.pmoving ,e.pos(), e.modifiers().__eq__(Qt.ShiftModifier)):
self.update()
def mousePressEvent(self ,e):
if self.pselected <= -1 :
return
l = self.path.contains_m( e.pos() ) <------------判定メソッド
if l >= 0 :
self.pmoving = l
def mouseReleaseEvent(self ,e):
self.pmoving = -1
if self.path.contains_m( e.pos() ) == -2 :
self.pselected = -2 # release selected mode
```
- hoge
```
class mypath
def init
self.closed=0
def setclosed(self,flag):
self.colsed=flag
def index(p):
max=self.elementCount()
if self.closed : #####書き直しだ
if p==-1:
return -2
elif p==max:
return 1
else :
reurn p
p = p if p < max else p-max
return p
else:
if p < 0 :
return 0
elif p > max -1
return max -1
else :
rturn p
## ポイントの矩形はメンバなので関数で返す必要は無く直接参照させる
def movepoint(self, p , pos , flag ): # flag : true-->sync
if flag :
lam = lambda q: QPointF(self.elementAt(q).x , self.elementAt(q).y )
type1,type2 = self.elementAt(p).type ,self.elementAt(p-1).type
if type1==2 : # cp symmetry first
self.movepoint( p-2 , lam(p-1) + lam(p-1) - pos ,0) # (p-1) + pos->(p-1)
elif type1==3 and type2==2 : # cp symmetry second
self.movepoint( p+2 , lam(p+1) + lam(p+1) - pos ,0) # (p+1) + pos->(p+1)
else : # point parerell
self.movepoint( p+1 , lam(p+1) - lam(p) + pos , 0) # (p+1) + p->pos
self.movepoint( p-1 , lam(p-1) - lam(p) + pos , 0) # (p-1) + p->pos
in self.closed:
if p==0:
self.setElementPositionAt( self.index(p-2) , pos.x() , pos.y() )
self.setElementPositionAt( p , pos.x() , pos.y() )
#####ここにrect計算を書く
```
void QPainterPath::translate(qreal dx, qreal dy)
パス内のすべての要素を(dx、dy)だけ平行移動します。
---
--> [PyQt でベクターオブジェクト作成ツールを作る # もくじ ](https://mimemo.io/m/3Rx1XoR367le95E)
190719
動作の構想
- マウスオーバーでパスを青、ポイントも描画、ただしコントロールポイントは描画しない
pselected : -1 - ポイント位置にマウスが来たらポイントを赤くしてコントロールを二本描画
違うポイントに移るまでその状態を維持
pselected >= 0 <--- pselected が -1 -2 になっても現在値を維持する
±1 でも現在値を維持する - ポイント位置でクリックでポイント選択
クリックした位置のヒット判定が0以上なら pmoving=それ
変数は二つ必要になる
サブクラス
- QPainterPath オブジェクトの派生クラスを作る
- ポイントのrectを CP 含めて全て作成する
本体の描画ルーチンからはクラスメンバとして参照させる
本体の描画ルーチンで判断して CP 以外を描画する
ヒット判定はメソッドとして呼び出す - 閉じたパスを実装
フラグを持つ、閉じた場合で0が移動したら終点も同じ座標とする - ポイント移動メソッドは既にあるが独自に実装して、コントロールポイントを含めた平行移動やシンメトリ移動を実装する
def init
self.pmoving=-1
def mouseMoveEvent(self ,e):
if self.pmoving == -1 : # not Dragging
l = self.path.contains_m( e.pos() ) <------------判定メソッド
if self.pselected >= 0 : # point selecting
if l >= self.pselected-1 and l <= self.pselected+1 :
return # same point -- ignore
else :
self.pselected = l # reselect point
else:
if self.pselected == l : # case of -1 -2 , same--ignore
return
else :
self.pselected = l
else : # dragging
self.path.movepoint( self.pmoving ,e.pos(), e.modifiers().__eq__(Qt.ShiftModifier)):
self.update()
def mousePressEvent(self ,e):
if self.pselected <= -1 :
return
l = self.path.contains_m( e.pos() ) <------------判定メソッド
if l >= 0 :
self.pmoving = l
def mouseReleaseEvent(self ,e):
self.pmoving = -1
if self.path.contains_m( e.pos() ) == -2 :
self.pselected = -2 # release selected mode
- hoge
class mypath
def init
self.closed=0
def setclosed(self,flag):
self.colsed=flag
def index(p):
max=self.elementCount()
if self.closed : #####書き直しだ
if p==-1:
return -2
elif p==max:
return 1
else :
reurn p
p = p if p < max else p-max
return p
else:
if p < 0 :
return 0
elif p > max -1
return max -1
else :
rturn p
## ポイントの矩形はメンバなので関数で返す必要は無く直接参照させる
def movepoint(self, p , pos , flag ): # flag : true-->sync
if flag :
lam = lambda q: QPointF(self.elementAt(q).x , self.elementAt(q).y )
type1,type2 = self.elementAt(p).type ,self.elementAt(p-1).type
if type1==2 : # cp symmetry first
self.movepoint( p-2 , lam(p-1) + lam(p-1) - pos ,0) # (p-1) + pos->(p-1)
elif type1==3 and type2==2 : # cp symmetry second
self.movepoint( p+2 , lam(p+1) + lam(p+1) - pos ,0) # (p+1) + pos->(p+1)
else : # point parerell
self.movepoint( p+1 , lam(p+1) - lam(p) + pos , 0) # (p+1) + p->pos
self.movepoint( p-1 , lam(p-1) - lam(p) + pos , 0) # (p-1) + p->pos
in self.closed:
if p==0:
self.setElementPositionAt( self.index(p-2) , pos.x() , pos.y() )
self.setElementPositionAt( p , pos.x() , pos.y() )
#####ここにrect計算を書く
void QPainterPath::translate(qreal dx, qreal dy)
パス内のすべての要素を(dx、dy)だけ平行移動します。