ベクタパス作成ツール 1 version 2

2019/07/17 21:43 by yamasyuh68
  :追加された部分   :削除された部分
(差分が大きい場合、文字単位では表示しません)
hogehoge

- ベクタパス作成ツール

```
import sys , os , pickle
from PyQt5.QtWidgets import QApplication, QWidget,QMessageBox
from PyQt5.QtWidgets import QApplication, QWidget,QMessageBox,QMenu,QAction
from PyQt5.QtCore import QPointF ,QRectF ,Qt
from PyQt5.QtGui import QPainterPath ,QPainter ,QPen
from PyQt5.QtGui import QPainterPath ,QPainter ,QPen,QCursor

class makepath(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) # Tolerance in detecting point
        self.pselected = -1             # selected point
        self.pmove = 0                  # move flag
        self.draw=0                     # selected start point
        self.drawp=0                    # selected start point
        self.isclosed=0                 # closed flag

        self.setContextMenuPolicy(Qt.CustomContextMenu)
        self.customContextMenuRequested.connect( self.custommenu )

        self.show()

    self custommenu(self):
    def custommenu(self):
        menu=QMenu(self)
        action = QAction('Add Point', self)
        action.triggered.connect(self.addpoint)
        menu.addAction(action)

        action = QAction('Close Path', self)
        action.triggered.connect(self.closepath)
        menu.addAction(action)
        action = QAction('Open Path', self)
        action.triggered.connect(self.openpath)
        menu.addAction(action)

        action = QAction('Save Path', self)
        action.triggered.connect(self.topickle)
        menu.addAction(action)
        action = QAction('Load Path', self)
        action.triggered.connect(self.frompickle)
        menu.addAction(action)



        menu.exec_(QCursor.pos ())   

    def addpoint(self,e): # ctrl + click
        p = QPointF( (e.pos.x() - self.plist[-1].x())/3 , (e.posy() - self.plist[-1].y())/3 )
    def addpoint(self): # ctrl + click
        e=self.mapFromGlobal( QCursor.pos() )
        p = QPointF( (e.x() - self.plist[-1].x())/3 , (e.y() - self.plist[-1].y())/3 )
        self.plist.append( self.plist[-1] + p ) 
        self.plist.append( self.plist[-1] + p ) 
        self.plist.append( self.plist[-1] + p )  # new start point
        self.update()

    def closepath(self):
        reply = QMessageBox.question(self, 'Confirm'," Set End Point To Start Point",
            QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
        if reply == QMessageBox.Yes:
            self.plist[-1] - self.plist[0]
            self.isclosed=1      # set close flag
            sel.update()
        self.plist[-1] = self.plist[0]
        self.isclosed=1      # set close flag
        self.update()
    def openpath(self):
        # message
        pass
        self.isclosed=0      # set close flag

    def topickle(self):
        fname=os.path.join(os.path.dirname(__file__) , 'hoge')
        with open( file, 'wb') as f :
        with open( fname, 'wb') as f :
            pickle.dump( self.plist ,f)
    def frompickle(self):
        pass
        fname=os.path.join(os.path.dirname(__file__) , 'hoge')
        with open( fname, 'rb') as f :
            self.plist=pickle.load( f)
        self.update()

    def mouseMoveEvent(self ,e):
        if self.pmove :  # Dorag ing
            if self.isclosed and self.pselected==0 :
                self.plist[-1]=e.pos()
            if e. modifiers().__eq__(Qt.ShiftModifier): # shift
                if self.drawp > self.pselected :
                    self.plist[self.drawp+1]=self.plist[self.drawp]+(self.plist[self.drawp]-self.plist[self.pselected])
                elif self.drawp < self.pselected :
                    self.plist[self.drawp-1]=self.plist[self.drawp]+(self.plist[self.drawp]-self.plist[self.pselected])
                else:
                    self.plist[self.drawp+1] += ( e.pos() - self.plist[self.pselected])
                    self.plist[self.drawp-1] += ( e.pos() - self.plist[self.pselected])
            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.selected = i
                    self.drawp = int( (i+1) / 3 )  # selected start point
                    self.pselected = i
                    self.drawp = int( (i+1) / 3 )*3  # selected start point
                    self.update()
                    self.setWindowTitle('dawp {} selected {}'.format(self.drawp,self.pselected))
                    break

    def mousePressEvent(self ,e):
        if Qt.KeyboardModifiers  == Qt.ControlModifier :  # ctrl Qt.ShiftModifierQt.AltModifier
            self.addpoint( e )
        if e. modifiers().__eq__(Qt.ControlModifier): # ctrl 
            self.addpoint()
        elif self.pselected != -1 :
            self.pmove = True

    def mouseReleaseEvent(self ,e):
        self.pmove = False
        self.pselected = -1

    def paintEvent (self,e):
        # 与えられたパラメータでパスを作成した後でパスをドローする→ mousemove に移したい
        path = QPainterPath( self.plist[0] )
        for i in range (1, len(self.plist) ,3):
            path.cubicTo( self.plist[i] , self.plist[i+1] , self.plist[i+2] )

        painter= QPainter()
        painter.begin(self) 

        painter.setPen( QPen( Qt.black , 2, style=Qt.SolidLine ) )
        painter.drawPath(path)
        for i in range( 0 , len(self.plist)-3 , 3 )              # draw all start point
        for i in range( 0 , len(self.plist)-3 , 3 ) :             # draw all start point
            painter.drawRect( QRectF(QPointF(self.plist[i]-self.a) , 
                QPointF(self.plist[i] + self.a) ))

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

        # draw selected points and sub-line

        painter.setPen( QPen( Qt.red , 2, style=Qt.DotLine ) )
        painter.drawRect( QRectF(QPointF(self.plist[self.draw]-self.a) , 
            QPointF(self.plist[self.draw] + self.a) ))
        painter.drawRect( QRectF(QPointF(self.plist[self.drawp]-self.a) , 
            QPointF(self.plist[self.drawp] + self.a) ))

        if self.drawp==0:
            painter.drawLine( self.plist[self.draw] , self.plist[self.draw+1] ) 
            painter.drawRect( QRectF(QPointF(self.plist[self.draw+1]-self.a) , 
                QPointF(self.plist[self.draw+1] + self.a) ))
            painter.drawLine( self.plist[self.drawp] , self.plist[self.drawp+1] ) 
            painter.drawRect( QRectF(QPointF(self.plist[self.drawp+1]-self.a) , 
                QPointF(self.plist[self.drawp+1] + self.a) ))
            painter.drawLine( self.plist[-1] , self.plist[-2] )
            painter.drawRect( QRectF(QPointF(self.plist[self.draw-2]-self.a) , 
                QPointF(self.plist[self.draw-2] + self.a) ))
            painter.drawRect( QRectF(QPointF(self.plist[self.drawp-2]-self.a) , 
                QPointF(self.plist[self.drawp-2] + self.a) ))
        elif self.drawp== len(self.plist)-1 :
            painter.drawLine( self.plist[self.draw] , self.plist[self.draw-1] )   #  sub
            painter.drawRect( QRectF(QPointF(self.plist[self.draw-1]-self.a) , 
                QPointF(self.plist[self.draw-1] + self.a) ))
            painter.drawLine( self.plist[self.drawp] , self.plist[self.drawp-1] )   #  sub
            painter.drawRect( QRectF(QPointF(self.plist[self.drawp-1]-self.a) , 
                QPointF(self.plist[self.drawp-1] + self.a) ))
        else :
            painter.drawLine( self.plist[self.draw] , self.plist[self.draw-1] )  
            painter.drawLine( self.plist[self.draw] , self.plist[self.draw+1] )  
            painter.drawRect( QRectF(QPointF(self.plist[self.draw+1]-self.a) , 
                QPointF(self.plist[self.draw+1] + self.a) ))
            painter.drawRect( QRectF(QPointF(self.plist[self.draw-1]-self.a) , 
                QPointF(self.plist[self.draw-1] + self.a) ))
            painter.drawLine( self.plist[self.drawp] , self.plist[self.drawp-1] )  
            painter.drawLine( self.plist[self.drawp] , self.plist[self.drawp+1] )  
            painter.drawRect( QRectF(QPointF(self.plist[self.drawp+1]-self.a) , 
                QPointF(self.plist[self.drawp+1] + self.a) ))
            painter.drawRect( QRectF(QPointF(self.plist[self.drawp-1]-self.a) , 
                QPointF(self.plist[self.drawp-1] + self.a) ))

        if self.pselected != -1 :
            painter.setPen( QPen( Qt.blue , 2, style=Qt.DotLine ) )
            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 = makepath()
    sys.exit(app.exec_())
```      
  • ベクタパス作成ツール
import sys , os , pickle
from PyQt5.QtWidgets import QApplication, QWidget,QMessageBox,QMenu,QAction
from PyQt5.QtCore import QPointF ,QRectF ,Qt
from PyQt5.QtGui import QPainterPath ,QPainter ,QPen,QCursor

class makepath(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) # Tolerance in detecting point
        self.pselected = -1             # selected point
        self.pmove = 0                  # move flag
        self.drawp=0                    # selected start point
        self.isclosed=0                 # closed flag

        self.setContextMenuPolicy(Qt.CustomContextMenu)
        self.customContextMenuRequested.connect( self.custommenu )

        self.show()

    def custommenu(self):
        menu=QMenu(self)
        action = QAction('Add Point', self)
        action.triggered.connect(self.addpoint)
        menu.addAction(action)

        action = QAction('Close Path', self)
        action.triggered.connect(self.closepath)
        menu.addAction(action)
        action = QAction('Open Path', self)
        action.triggered.connect(self.openpath)
        menu.addAction(action)

        action = QAction('Save Path', self)
        action.triggered.connect(self.topickle)
        menu.addAction(action)
        action = QAction('Load Path', self)
        action.triggered.connect(self.frompickle)
        menu.addAction(action)



        menu.exec_(QCursor.pos ())   

    def addpoint(self): # ctrl + click
        e=self.mapFromGlobal( QCursor.pos() )
        p = QPointF( (e.x() - self.plist[-1].x())/3 , (e.y() - self.plist[-1].y())/3 )
        self.plist.append( self.plist[-1] + p ) 
        self.plist.append( self.plist[-1] + p ) 
        self.plist.append( self.plist[-1] + p )  # new start point
        self.update()

    def closepath(self):
        self.plist[-1] = self.plist[0]
        self.isclosed=1      # set close flag
        self.update()
    def openpath(self):
        self.isclosed=0      # set close flag

    def topickle(self):
        fname=os.path.join(os.path.dirname(__file__) , 'hoge')
        with open( fname, 'wb') as f :
            pickle.dump( self.plist ,f)
    def frompickle(self):
        fname=os.path.join(os.path.dirname(__file__) , 'hoge')
        with open( fname, 'rb') as f :
            self.plist=pickle.load( f)
        self.update()

    def mouseMoveEvent(self ,e):
        if self.pmove :  # Dorag ing
            if self.isclosed and self.pselected==0 :
                self.plist[-1]=e.pos()
            if e. modifiers().__eq__(Qt.ShiftModifier): # shift
                if self.drawp > self.pselected :
                    self.plist[self.drawp+1]=self.plist[self.drawp]+(self.plist[self.drawp]-self.plist[self.pselected])
                elif self.drawp < self.pselected :
                    self.plist[self.drawp-1]=self.plist[self.drawp]+(self.plist[self.drawp]-self.plist[self.pselected])
                else:
                    self.plist[self.drawp+1] += ( e.pos() - self.plist[self.pselected])
                    self.plist[self.drawp-1] += ( e.pos() - self.plist[self.pselected])
            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.drawp = int( (i+1) / 3 )*3  # selected start point
                    self.update()
                    self.setWindowTitle('dawp {} selected {}'.format(self.drawp,self.pselected))
                    break

    def mousePressEvent(self ,e):
        if e. modifiers().__eq__(Qt.ControlModifier): # ctrl 
            self.addpoint()
        elif self.pselected != -1 :
            self.pmove = True

    def mouseReleaseEvent(self ,e):
        self.pmove = False
        self.pselected = -1

    def paintEvent (self,e):
        # 与えられたパラメータでパスを作成した後でパスをドローする→ mousemove に移したい
        path = QPainterPath( self.plist[0] )
        for i in range (1, len(self.plist) ,3):
            path.cubicTo( self.plist[i] , self.plist[i+1] , self.plist[i+2] )

        painter= QPainter()
        painter.begin(self) 

        painter.setPen( QPen( Qt.black , 2, style=Qt.SolidLine ) )
        painter.drawPath(path)
        for i in range( 0 , len(self.plist)-3 , 3 ) :             # draw all start point
            painter.drawRect( QRectF(QPointF(self.plist[i]-self.a) , 
                QPointF(self.plist[i] + self.a) ))

        painter.setPen( QPen( Qt.red , 2, style=Qt.DotLine ) )
        painter.drawRect( QRectF(QPointF(self.plist[self.drawp]-self.a) , 
            QPointF(self.plist[self.drawp] + self.a) ))

        if self.drawp==0:
            painter.drawLine( self.plist[self.drawp] , self.plist[self.drawp+1] ) 
            painter.drawRect( QRectF(QPointF(self.plist[self.drawp+1]-self.a) , 
                QPointF(self.plist[self.drawp+1] + self.a) ))
            painter.drawLine( self.plist[-1] , self.plist[-2] )
            painter.drawRect( QRectF(QPointF(self.plist[self.drawp-2]-self.a) , 
                QPointF(self.plist[self.drawp-2] + self.a) ))
        elif self.drawp== len(self.plist)-1 :
            painter.drawLine( self.plist[self.drawp] , self.plist[self.drawp-1] )   #  sub
            painter.drawRect( QRectF(QPointF(self.plist[self.drawp-1]-self.a) , 
                QPointF(self.plist[self.drawp-1] + self.a) ))
        else :
            painter.drawLine( self.plist[self.drawp] , self.plist[self.drawp-1] )  
            painter.drawLine( self.plist[self.drawp] , self.plist[self.drawp+1] )  
            painter.drawRect( QRectF(QPointF(self.plist[self.drawp+1]-self.a) , 
                QPointF(self.plist[self.drawp+1] + self.a) ))
            painter.drawRect( QRectF(QPointF(self.plist[self.drawp-1]-self.a) , 
                QPointF(self.plist[self.drawp-1] + self.a) ))

        if self.pselected != -1 :
            painter.setPen( QPen( Qt.blue , 2, style=Qt.DotLine ) )
            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 = makepath()
    sys.exit(app.exec_())