在尝试实现绘画时,我决定从形状开始 我的初始化:
db
我有一个活动,其中有一些用于绘制形状的功能
def __init__(self, parent=None):
self.modified = False
self.rectangle = False
self.ellipse = False
self.begin = QPoint()
self.end = QPoint()
self.myPenWidth = 1
self.myFigureColor = Qt.black
self.image = QImage()
在这里我们使用位于其中的功能图形: 我将它们发布在下面
def mousePressEvent(self, event):
if (event.button() == Qt.LeftButton) and self.rectangle:
self.draw_rectandle(event)
if (event.button() == Qt.LeftButton) and self.ellipse:
self.draw_ellipse(event)
和
def mouseMoveEvent(self, event):
if (event.buttons() & Qt.LeftButton) and self.rectangle:
self.end = event.pos()
self.update()
if (event.buttons() & Qt.LeftButton) and self.ellipse:
self.end = event.pos()
self.update()
另一个函数paintEvent:
def mouseReleaseEvent(self, event):
if (event.buttons() & Qt.LeftButton) and self.rectangle:
self.begin = event.pos()
self.end = event.pos()
if (event.buttons() & Qt.LeftButton) and self.ellipse:
self.begin = event.pos()
self.end = event.pos()
人物本身的功能:
def paintEvent(self, event):
painter = QPainter(self)
dirtyRect = event.rect()
painter.drawImage(dirtyRect, self.image, dirtyRect)
if self.rectangle == True:
painter.setPen(QPen(self.myFigureColor, self.myPenWidth,
Qt.SolidLine, Qt.RoundCap, Qt.RoundJoin))
painter.drawRect(QRect(self.begin, self.end))
if self.ellipse == True:
painter.setPen(QPen(self.myFigureColor, self.myPenWidth,
Qt.SolidLine, Qt.RoundCap, Qt.RoundJoin))
painter.drawEllipse(QRect(self.begin, self.end))
还有“伪绑定”
def draw_rectandle(self, event):
painter = QPainter(self.image)
painter.setPen(QPen(self.myFigureColor, self.myPenWidth,
Qt.SolidLine, Qt.RoundCap, Qt.RoundJoin))
painter.drawRect(QRect(self.begin, self.end))
self.begin = event.pos()
self.end = event.pos()
self.modified = True
self.update()
def draw_ellipse(self, event):
painter = QPainter(self.image)
painter.setPen(QPen(self.myFigureColor, self.myPenWidth,
Qt.SolidLine, Qt.RoundCap, Qt.RoundJoin))
painter.drawEllipse(QRect(self.begin, self.end))
self.begin = event.pos()
self.end = event.pos()
self.modified = True
self.update()
它们用于在按下形状按钮时更改功能标志。 如果需要,按钮本身看起来像:
动作:
def rectangleOn(self):
self.ellipse = False
self.rectangle = True
def ellipseOn(self):
self.rectangle = False
self.ellipse = True
带有按钮的工具栏:
self.rectangle = QAction(QIcon('Image/rectangle.png'), 'Rectangle', self)
self.rectangle.triggered.connect(self.scribbleArea.rectangleOn)
self.ellipse = QAction(QIcon('Image/Ellipse.png'), 'Ellipse', self)
self.ellipse.triggered.connect(self.scribbleArea.ellipseOn)
我认为不需要更改颜色和大小的功能。因此,虽然我不会发布。
现在,我将告诉您问题出在哪里。
在paintEvent中,我有一个显示形状的图形。也就是说,我们拉一下边缘,看看形状是如何变化的。但是从那以后它并没有保存在任何地方。
并且在mousePressEvent中已经绘制了矩形本身而没有拖动动画
似乎一切都很好,但是这里有一个错误
如您所见,矩形的图形进入mousePressEvent。这意味着该矩形仅在我开始绘制下一个矩形时出现。这已经是一个错误。但!如果我绘制几个矩形并开始绘制椭圆,则最后一个矩形将变为椭圆。
还有其他形状。
如果我开始画一条线,然后切换到一个椭圆并在另一个地方开始画椭圆,那么我画的线将立即变成非常窄的椭圆。
因此,我需要以某种方式从mousePressEvent中拉出此功能,以便在工具之间进行这种切换来绘制所需的形状。
如果您需要更多详细信息,请写с:
P.S。如果出现问题,我为我的英语致歉с:
答案 0 :(得分:2)
我无法复制,因为您将代码逐段显示,建议您始终显示一个统一的代码,以便我们可以轻松地执行想要帮助的代码。
您已经注意到,如果要保留数据,必须将其保存在图像中,并使用临时数据将其直接绘制在小部件中。我的解决方案的逻辑是从mousePressEvent
到mouseReleaseEvent
之前直接在小部件中绘制然后保存在图像中的瞬间,为此,我创建了一个名为AbstractScribbleArea
的类,该类实现了通用逻辑,如果您想为其他形状实现逻辑,则只应覆盖draw()
方法。
from PyQt5 import QtCore, QtGui, QtWidgets
class AbstractScribbleArea(QtWidgets.QWidget):
def __init__(self, parent=None):
super(AbstractScribbleArea, self).__init__(parent)
self._start = QtCore.QPoint()
self._end = QtCore.QPoint()
self._pixmap = QtGui.QPixmap()
self._shape = ""
self._color = QtGui.QColor("black")
self._pen_width = 1
self._pen = QtGui.QPen(self._color, self._pen_width,
QtCore.Qt.SolidLine, QtCore.Qt.RoundCap, QtCore.Qt.RoundJoin)
def mousePressEvent(self, event):
if event.buttons() & QtCore.Qt.LeftButton:
self._start = event.pos()
self._end = event.pos()
self.update()
super(AbstractScribbleArea, self).mousePressEvent(event)
def mouseMoveEvent(self, event):
if event.buttons() & QtCore.Qt.LeftButton:
self._end = event.pos()
self.update()
super(AbstractScribbleArea, self).mouseMoveEvent(event)
def mouseReleaseEvent(self, event):
# draw on image
painter = QtGui.QPainter(self._pixmap)
painter.setPen(self._pen)
self.draw(painter, self._start, self._end, True)
self._start = QtCore.QPoint()
self._end = QtCore.QPoint()
self.update()
super(AbstractScribbleArea, self).mouseReleaseEvent(event)
def paintEvent(self, event):
painter = QtGui.QPainter(self)
painter.drawPixmap(self.rect(), self._pixmap, self.rect())
painter.setPen(self._pen)
self.draw(painter, self._start, self._end, False)
def resizeEvent(self, event):
w = self.width() if self.width() > self._pixmap.width() else self._pixmap.width()
h = self.height() if self.height() > self._pixmap.height() else self._pixmap.height()
s = QtCore.QSize(w, h)
if s != self._pixmap.size():
pixmap = QtGui.QPixmap(self._pixmap)
self._pixmap = QtGui.QPixmap(s)
painter = QtGui.QPainter(self._pixmap)
painter.fillRect(QtCore.QRect(0, 0, w, h), QtCore.Qt.white)
painter.drawPixmap(pixmap.rect(), pixmap)
super(AbstractScribbleArea, self).resizeEvent(event)
def draw(self, painter, start, end, is_released):
raise NotImplementedError
def sizeHint(self):
return QtCore.QSize(640, 480)
def set_pen_width(self, width):
self._pen.setWidth(width)
def set_pen_color(self, color):
self._pen.setColor(QtGui.QColor(color))
def set_shape(self, shape):
self._shape =shape
def shape(self):
return self._shape
class ScribbleArea(AbstractScribbleArea):
def draw(self, painter, start, end, is_released):
if start.isNull() or end.isNull():
return
if self.shape() == "rectangle":
self.draw_rectangle(painter, start, end)
elif self.shape() == "ellipse":
self.draw_ellipse(painter, start, end)
def draw_rectangle(self, painter, start, end):
rect = QtCore.QRect(start, end)
painter.drawRect(rect)
def draw_ellipse(self, painter, start, end):
rect = QtCore.QRect(start, end)
painter.drawEllipse(rect)
@QtCore.pyqtSlot()
def rectangleOn(self):
self.set_shape("rectangle")
@QtCore.pyqtSlot()
def ellipseOn(self):
self.set_shape("ellipse")
class MainWindow(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
self.scribbleArea = ScribbleArea()
self.scribbleArea.set_pen_width(10)
self.scribbleArea.set_pen_color("red")
self.setCentralWidget(self.scribbleArea)
self.rectangle = QtWidgets.QAction(QtGui.QIcon('Image/rectangle.png'), 'Rectangle', self)
self.rectangle.triggered.connect(self.scribbleArea.rectangleOn)
self.ellipse = QtWidgets.QAction(QtGui.QIcon('Image/Ellipse.png'), 'Ellipse', self)
self.ellipse.triggered.connect(self.scribbleArea.ellipseOn)
toolbar = self.addToolBar('Tools')
toolbar.addAction(self.rectangle)
toolbar.addAction(self.ellipse)
if __name__ == '__main__':
import sys
app = QtWidgets.QApplication(sys.argv)
w = MainWindow()
w.show()
sys.exit(app.exec_())