190701
Qtのパス操作で、path.cubicTo を使えばベジェが書けるのは知ってたけど、自分で数字を与えて希望通りの曲線になるはずも無く、現実には使えてなかった
ふとマウスでグリグリするアイデアを思いついたので早速試してみたら意外と簡単にできたので公開してみます
こんな感じ、各ポイントをマウスで自由に移動できます
コードです
環境はPython 3.72 と PyQt 5.12です
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) # Tolerance in detecting point
self.pselected = -1 # selectedpoint
self.pmove = 0 # move flag
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
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_())
→ 戻る