PyQt でベジェ曲線を描画してマウスでグリグリする version 12

2019/07/02 21:25 by yamasyuh68
  :追加された部分   :削除された部分
(差分が大きい場合、文字単位では表示しません)
ベジェ描画の実験
https://live.staticflickr.com/65535/48179115881_a41a1d2f6e_z.jpg


一から学ぶベジェ曲線
https://postd.cc/bezier-curves/
このサイト素晴らしい、動画を埋め込むのでは無い、動くページの素晴らしさだな
ペイントの基本
https://qiita.com/kenasman/items/87c12f3a8b63f5948153

・ウイジェットを一つ作って(500-500)そこに直接書く
・まずキューブを一つ書く、端点は四つ、これをマウスでグリグリする
・端点を中心に誤差aでマウスで選択してドラッグできるようにする
 通常は黒い■、マウスオーバーで赤い■にしてマウスプレスで選択、ドラッグ
 ドラッグ中はリアルタイムで描画

```
# =====================
import sys
from PyQt5.QtWidgets import QApplication, QWidget
from PyQt5.QtCore import QPointF ,QRectF
from PyQt5.QtGui import QPainterPath ,QPainter 
from PyQt5.QtCore import QPointF ,QRectF ,Qt
from PyQt5.QtGui import QPainterPath ,QPainter ,QPen

class App(QWidget):

    def __init__(self):
        super().__init__()
        self.setWindowTitle('hogetta')
        self.setGeometry( 500, 50 , 500 , 500 )
        self.setMouseTracking (True)  # <----------------*****
        self.plist=[]
        self.plist.append( QPointF(10,250) )  # start point
        self.plist.append( QPointF(100,100) )  #
        self.plist.append( QPointF(300,200) )  #
        self.plist.append( QPointF(490,250) )  #
        self.a = QPointF(4,4)
        self.pselected = -1             # selectedpoint
        self.pmove = 0                  # should move
        self.show()

if __name__ == "__main__":
    app = QApplication(sys.argv)
    ex = App()
    sys.exit(app.exec_())
    def mouseMoveEvent(self ,e):
        if self.pmove :  # Dorag ing
            self.plist[self.pselected] = e.pos()
            self.update()
        else:            # non Dorag ing
            self.pselected = -1
            rc = QRectF ( e.pos() - self.a , e.pos() + self.a )
            for i, l in  enumerate( self.plist ) :
                if rc.contains(  l ) :
                    self.pselected = i
                    # self.setWindowTitle('HIT  {}'.format(str(i)))
                    self.update()
                    break
    def mousePressEvent(self ,e):
        if self.pselected != -1 :
            self.pmove = True
            # print('True')
    def mouseReleaseEvent(self ,e):
        self.pmove = False
        self.pselected = -1

# =======================
def init
    def paintEvent (self,e):
        # パスを設定した後でパスをドローする
        path = QPainterPath( self.plist[0] )
        path.cubicTo( self.plist[1] , self.plist[2] , self.plist[3] )

self.plist=[]
self.plist.append( QPointF(10,250) )  # start point
self.plist.append( QPointF(100,100) )  #
self.plist.append( QPointF(300,200) )  #
self.plist.append( QPointF(490,250) )  #
self.a = QPointf(2,2)
self.pselected = -1             # selectedpoint
self.pmove = 0                  # should move
self.draw()
        painter= QPainter()
        painter.begin(self) 
        painter.setPen( QPen( Qt.black , 2, style=Qt.SolidLine ) )
        painter.drawPath(path)

# ========================
def keyPressEvent( self ,e):
 if e.                     # not shift return 
        painter.setPen( QPen( Qt.red , 2, style=Qt.DotLine ) )
        painter.drawLine( self.plist[0] , self.plist[1] ) # sub
        painter.drawLine( self.plist[2] , self.plist[3] ) # sub

 setPen(black);
 for l in   self.plist :
  DrawRect(l._sub_(a) , l._add_( a) ) # <---- ???
        if self.pselected != -1:
            painter.drawRect( QRectF(QPointF(self.plist[self.pselected]-self.a) ,
                QPointF(self.plist[self.pselected]+self.a) ))

# ========================
def mouseMoveEvent(self ,e):
        painter.end() 

 setPen(red);
 if self.pmove :  # Dorag ing
  self.plist[self.selected] = e.pos()
  self.draw()
  # self.update()
 else:            # non Dorag ing
  self.pselected = -1
  rc = QRectF ( e.pos() - self.a , e.pos() + self.a )
  for i, l in  enumerate( self.plist ) :
   if rc.contains( rc , l , False) :
    self.pselected = i
    self.drawpoint(QRectF( l-self.a , l+self.a ) ,1 )
    break

def drawpoint(self,rc,flag): # 0:black 1:red
 paint=QPainter(self)
 if flag :
  paint.setPen( Qt.red )
 else :
  paint.setPen( Qt.black )
 paint.drawRect( rc )
 # self.update() # <----------?

# ========================
def mousePressEvent(self ,e):
 if self.pselected != -1 :
  self.pmove = True
def mouseReleaseEvent(self ,e):
 self.pmove = False
 self.pselected = -1
# ========================
def draw(self):
if __name__ == "__main__":
    app = QApplication(sys.argv)
    ex = App()
    sys.exit(app.exec_())

 # パスを設定した後でパスをドローする

 # path = QPainterPath()
 # path.moveTo( plist[0] );
 path = QPainterPath( plist[0] )
 path.cubicTo( plist[1] , plist[2] , plist[3] )

 painter= QPainter(self) ;
 painter.setPen( QPen( Qt.black , 1, style=Qt.SolidLine ) )
 painter.drawPath(path)

 painter.setPen( QPen( Qt.red , 1, style=Qt.DotLine ) )
 painter.drawLine( plist[0] , plist[1] ) # sub
 painter.drawLine( plist[2] , plist[3] ) # sub

# ===================
```

      

一から学ぶベジェ曲線
https://postd.cc/bezier-curves/
このサイト素晴らしい、動画を埋め込むのでは無い、動くページの素晴らしさだな
ペイントの基本
https://qiita.com/kenasman/items/87c12f3a8b63f5948153

・ウイジェットを一つ作って(500-500)そこに直接書く
・まずキューブを一つ書く、端点は四つ、これをマウスでグリグリする
・端点を中心に誤差aでマウスで選択してドラッグできるようにする
 通常は黒い■、マウスオーバーで赤い■にしてマウスプレスで選択、ドラッグ
 ドラッグ中はリアルタイムで描画

import sys
from PyQt5.QtWidgets import QApplication, QWidget
from PyQt5.QtCore import QPointF ,QRectF ,Qt
from PyQt5.QtGui import QPainterPath ,QPainter ,QPen

class App(QWidget):

    def __init__(self):
        super().__init__()
        self.setWindowTitle('hogetta')
        self.setGeometry( 500, 50 , 500 , 500 )
        self.setMouseTracking (True)  # <----------------*****
        self.plist=[]
        self.plist.append( QPointF(10,250) )  # start point
        self.plist.append( QPointF(100,100) )  #
        self.plist.append( QPointF(300,200) )  #
        self.plist.append( QPointF(490,250) )  #
        self.a = QPointF(4,4)
        self.pselected = -1             # selectedpoint
        self.pmove = 0                  # should move
        self.show()

    def mouseMoveEvent(self ,e):
        if self.pmove :  # Dorag ing
            self.plist[self.pselected] = e.pos()
            self.update()
        else:            # non Dorag ing
            self.pselected = -1
            rc = QRectF ( e.pos() - self.a , e.pos() + self.a )
            for i, l in  enumerate( self.plist ) :
                if rc.contains(  l ) :
                    self.pselected = i
                    # self.setWindowTitle('HIT  {}'.format(str(i)))
                    self.update()
                    break
    def mousePressEvent(self ,e):
        if self.pselected != -1 :
            self.pmove = True
            # print('True')
    def mouseReleaseEvent(self ,e):
        self.pmove = False
        self.pselected = -1

    def paintEvent (self,e):
        # パスを設定した後でパスをドローする
        path = QPainterPath( self.plist[0] )
        path.cubicTo( self.plist[1] , self.plist[2] , self.plist[3] )

        painter= QPainter()
        painter.begin(self) 
        painter.setPen( QPen( Qt.black , 2, style=Qt.SolidLine ) )
        painter.drawPath(path)

        painter.setPen( QPen( Qt.red , 2, style=Qt.DotLine ) )
        painter.drawLine( self.plist[0] , self.plist[1] ) # sub
        painter.drawLine( self.plist[2] , self.plist[3] ) # sub

        if self.pselected != -1:
            painter.drawRect( QRectF(QPointF(self.plist[self.pselected]-self.a) ,
                QPointF(self.plist[self.pselected]+self.a) ))

        painter.end() 



if __name__ == "__main__":
    app = QApplication(sys.argv)
    ex = App()
    sys.exit(app.exec_())