Reputation: 47
I am trying to code a simple image editor like paint.
I implemented drawing lines rectangles and ellipses.
what i want is to see an animation (a foreshadowing ?) of how the rectangle will look like, just like in paint when you draw a shape you can see what it actually looks like without really drawing on the canvas.
here is a shortened version of the code
class Canvas(QWidget):
def __init__(self):
super().__init__()
self.initUI()
self.initLogic()
def initUI(self):
self.image = QImage(self.size(), QImage.Format_RGB32)
self.image.fill(Qt.white)
def initLogic(self):
self.brushSize = 1
self.brushStyle = Qt.SolidLine
self.brushColor = QColor(0, 0, 0)
self.shapeMode = None
self.drawing = False
self.mousePointer = None
def mousePressEvent(self, event):
self.drawing = True
self.mousePointer = event.pos()
def mouseMoveEvent(self, event):
#if no pen mode set draw lines from event to event
if self.drawing:
painter = QPainter(self.image)
painter.setPen(QPen(self.brushColor,
self.brushSize,
self.brushStyle))
shape = None #i try later to assign the method Qpainter.draw<someShape> to this variable
# hoping it works like in tkinter.
if self.shapeMode == None:#free shape
painter.drawLine(self.mousePointer, event.pos())
self.mousePointer = event.pos()
else:
#previous x and previous y
ox, oy = self.mousePointer.x(), self.mousePointer.y()
#current x and current y
dx, dy = event.pos().x(), event.pos().y()
width, height = dx - ox, dy - oy
#self.shapeMode is a string corresponding to a QPainter method
#we get the corresponding method using getattr builtin function
drawMethod = getattr(painter, self.shapeMode)# = painter.someFunc this works fine
shape = drawMethod(ox, oy, width, height) #assigning the method call to a variable
self.update()
if shape != None:
painter.eraseRect(shape)
"""
if self.drawing and self.shapeMode == None:
painter = QPainter(self.image)
painter.setPen(QPen(self.brushColor,
self.brushSize,
self.brushStyle))
painter.drawLine(self.mousePointer, event.pos())
self.mousePointer = event.pos()
self.update()"""
#otherwise if pen mode set draw shape at event then delete until release
def mouseReleaseEvent(self, event):
if self.shapeMode != None:
painter = QPainter(self.image)
painter.setPen(QPen(self.brushColor,
self.brushSize,
self.brushStyle))
#previous x and previous y
ox, oy = self.mousePointer.x(), self.mousePointer.y()
#current x and current y
dx, dy = event.pos().x(), event.pos().y()
width, height = dx - ox, dy - oy
#self.shapeMode is a string corresponding to a QPainter methid
#we get the corresponding method using getattr builtin function
drawMethod = getattr(painter, self.shapeMode)# = painter.someFunc
shape = drawMethod(ox, oy, width, height)
self.update()
self.mousePointer = event.pos()
self.drawing = False
#TODO end registering the action
def paintEvent(self, event):
widgetPainter = QPainter(self)
widgetPainter.drawImage(self.rect(), self.image, self.rect())
the canvas keeps drawing rectangles as long as i hold the mouse, what i want is the rectangle to resize and only definitively be drawn after mouse release.
Upvotes: 1
Views: 1757
Reputation: 6112
You can achieve this by taking advantage of which paint device to pass to QPainter. During mouseMoveEvent
keep a reference to the points and sizes calculated so in paintEvent
you can draw onto the main widget. This way anything painted will only last until the next update. Then in mouseReleaseEvent
you can paint on the QImage to permanently draw the rectangle.
class Canvas(QWidget):
def __init__(self):
super().__init__()
self.initUI()
self.initLogic()
def initUI(self):
self.image = QImage(self.size(), QImage.Format_RGB32)
self.image.fill(Qt.white)
def initLogic(self):
self.brushSize = 1
self.brushStyle = Qt.SolidLine
self.brushColor = QColor(0, 0, 0)
self.shapeMode = 'drawRect'
self.temp_rect = QRect()
self.drawing = False
self.mousePointer = None
def mousePressEvent(self, event):
self.drawing = True
self.mousePointer = event.pos()
def mouseMoveEvent(self, event):
#if no pen mode set draw lines from event to event
if self.drawing:
painter = QPainter(self.image)
painter.setPen(QPen(self.brushColor,
self.brushSize,
self.brushStyle))
if self.shapeMode == None:#free shape
painter.drawLine(self.mousePointer, event.pos())
self.mousePointer = event.pos()
else:
#previous x and previous y
ox, oy = self.mousePointer.x(), self.mousePointer.y()
#current x and current y
dx, dy = event.pos().x(), event.pos().y()
width, height = dx - ox, dy - oy
self.temp_rect = QRect(ox, oy, width, height)
self.update()
def mouseReleaseEvent(self, event):
if self.shapeMode != None:
painter = QPainter(self.image)
painter.setPen(QPen(self.brushColor,
self.brushSize,
self.brushStyle))
#self.shapeMode is a string corresponding to a QPainter methid
#we get the corresponding method using getattr builtin function
drawMethod = getattr(painter, self.shapeMode)# = painter.someFunc
drawMethod(self.temp_rect)
self.update()
self.mousePointer = event.pos()
self.drawing = False
#TODO end registering the action
def paintEvent(self, event):
widgetPainter = QPainter(self)
widgetPainter.drawImage(self.rect(), self.image, self.rect())
if self.drawing:
drawMethod = getattr(widgetPainter, self.shapeMode)
drawMethod(self.temp_rect)
Outcome:
Upvotes: 1