问题描述
但是在实现的过程中,遇到了一个我不太清楚的事情。
工作铅笔实现代码:
import sys
from PyQt5.QtCore import QPoint, QRect, QSize, Qt
from PyQt5.QtGui import QPainter, QPen, QIcon, QPixmap, QColor
from PyQt5.QtWidgets import (QAction, QApplication, QMainWindow,QWidget)
class AbstractScribbleArea(QWidget):
def __init__(self, parent=None):
super(AbstractScribbleArea, self).__init__(parent)
self.modified = False
self._begin = QPoint()
self._end = QPoint()
self._lastPoint = QPoint()
self._pixmap = QPixmap()
self._shape = ""
self.myPenWidth = 10
self.myPenColor = QColor("black")
def mousePressEvent(self, event):
if event.buttons() & Qt.LeftButton:
self._begin = event.pos()
self._end = event.pos()
self.update()
super(AbstractScribbleArea, self).mousePressEvent(event)
def mouseMoveEvent(self, event):
if event.buttons() & Qt.LeftButton:
self._end = event.pos()
self.update()
super(AbstractScribbleArea, self).mouseMoveEvent(event)
def mouseReleaseEvent(self, event):
# draw on image
painter = QPainter(self._pixmap)
if self._shape == 'pencil':
painter.setPen(QPen(self.myPenColor, self.myPenWidth,
Qt.SolidLine, Qt.RoundCap, Qt.RoundJoin))
self.draw(painter, self._begin, self._end, True)
self._begin = QPoint()
self._end = QPoint()
self.update()
super(AbstractScribbleArea, self).mouseReleaseEvent(event)
def paintEvent(self, event):
painter = QPainter(self)
painter.drawPixmap(self.rect(), self._pixmap, self.rect())
if self._shape == 'pencil':
painter.setPen(QPen(self.myPenColor, self.myPenWidth,
Qt.SolidLine, Qt.RoundCap, Qt.RoundJoin))
self.draw(painter, self._begin, 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 = QSize(w, h)
if s != self._pixmap.size():
pixmap = QPixmap(self._pixmap)
self._pixmap = QPixmap(s)
painter = QPainter(self._pixmap)
painter.fillRect(QRect(0, 0, w, h), Qt.white)
painter.drawPixmap(pixmap.rect(), pixmap)
super(AbstractScribbleArea, self).resizeEvent(event)
def draw(self, painter, _begin, _end, is_released):
raise NotImplementedError
def sizeHint(self):
return QSize(640, 480)
def set_shape(self, shape):
self._shape = shape
def shape(self):
return self._shape
class ScribbleArea(AbstractScribbleArea):
def draw(self, painter, _begin, _end, is_released):
if _begin.isNull() or _end.isNull():
return
elif self.shape() == "pencil":
self.drawPencil(painter, _begin, _end)
def drawPencil(self, painter, _begin, _end):
self.modified = True
painter.drawPoint(_begin.x(), _end.y())
def pencilOn(self):
self.set_shape("pencil")
class MainWindow(QMainWindow):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
self.scribbleArea = ScribbleArea()
self.setCentralWidget(self.scribbleArea)
self.pen = QAction(QIcon('Image/pen.png'), 'Карандаш', self)
self.pen.triggered.connect(self.scribbleArea.pencilOn)
toolbar = self.addToolBar('Инструменты')
toolbar.addAction(self.pen)
def main():
app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
问题在于,此时绘制了一个可以沿轴移动的点。 但这不是我在等待的。 我假设不是_begin.x(), _end.y() 需要使用event.x(), event.y()。
但这行不通,因为在 draw 函数中,我无法将参数传递给“event”。
当我尝试做类似的事情时,该函数用 = 请求事件
def draw(self, painter, _begin, _end, is_released):
if _begin.isNull() or _end.isNull():
return
elif self.shape() == "pencil":
self.drawPencil(painter, event= #????)
def drawPencil(self, painter, _begin, _end):
self.modified = True
painter.drawPoint(event.x(), event.y())
我真的不明白需要传递给事件的内容才能使函数正常工作。
铅笔函数还有一种实现:
def draw_pencil(self, event):
painter.drawLine(self.lastPoint, event.pos())
self.modified = True
self._lastPoint = event.pos()
self.update()
1楼
好像没看懂图形的绘制逻辑的解决方案,在一个图形的情况下,拖动鼠标之前的图形要擦除,释放鼠标时必须在永久内存中绘制,在本例中为QPixmap
。
但是在铅笔的情况下就不同了,因为它在拖动时必须在永久内存中绘制,所以实现的类对它不起作用,所以我们必须在新的类中实现它,记住在编程中你有要订购,每个班级必须有特定的任务。
from PyQt5 import QtCore, QtGui, QtWidgets
class AbstractShapeScribbleArea(QtWidgets.QWidget):
def __init__(self, parent=None):
super(AbstractShapeScribbleArea, 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(AbstractShapeScribbleArea, self).mousePressEvent(event)
def mouseMoveEvent(self, event):
if event.buttons() & QtCore.Qt.LeftButton:
self._end = event.pos()
self.update()
super(AbstractShapeScribbleArea, self).mouseMoveEvent(event)
def mouseReleaseEvent(self, event):
painter = QtGui.QPainter(self._pixmap)
painter.setPen(self._pen)
self.draw_shape(painter, self._start, self._end, True)
self._start = QtCore.QPoint()
self._end = QtCore.QPoint()
self.update()
super(AbstractShapeScribbleArea, 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_shape(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(AbstractShapeScribbleArea, self).resizeEvent(event)
def draw_shape(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(AbstractShapeScribbleArea):
def draw_shape(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 mousePressEvent(self, event):
if self.shape() == "pencil" and event.buttons() & QtCore.Qt.LeftButton:
setattr(self, "pencil_start", event.pos())
self.draw_pencil(event.pos(), event.pos())
else:
super(ScribbleArea, self).mousePressEvent(event)
def mouseMoveEvent(self, event):
if self.shape() == "pencil" and event.buttons() & QtCore.Qt.LeftButton:
pencil_start = getattr(self, "pencil_start")
self.draw_pencil(pencil_start, event.pos())
setattr(self, "pencil_start", event.pos())
else:
super(ScribbleArea, self).mouseMoveEvent(event)
def mouseReleaseEvent(self, event):
if self.shape() == "pencil":
delattr(self, "pencil_start")
else:
super(ScribbleArea, self).mouseReleaseEvent(event)
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)
def draw_pencil(self, start, end):
painter = QtGui.QPainter(self._pixmap)
painter.setPen(self._pen)
painter.drawLine(start, end)
self.update()
@QtCore.pyqtSlot()
def rectangleOn(self):
self.set_shape("rectangle")
@QtCore.pyqtSlot()
def ellipseOn(self):
self.set_shape("ellipse")
@QtCore.pyqtSlot()
def pencilOn(self):
self.set_shape("pencil")
class MainWindow(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
scribbleArea = ScribbleArea()
self.setCentralWidget(scribbleArea)
rectangle = QtWidgets.QAction(QtGui.QIcon('Image/rectangle.png'), 'Rectangle', self)
rectangle.triggered.connect(scribbleArea.rectangleOn)
ellipse = QtWidgets.QAction(QtGui.QIcon('Image/Ellipse.png'), 'Ellipse', self)
ellipse.triggered.connect(scribbleArea.ellipseOn)
pen = QtWidgets.QAction(QtGui.QIcon('Image/pen.png'), 'Pencil', self)
pen.triggered.connect(scribbleArea.pencilOn)
toolbar = self.addToolBar('Tools')
toolbar.addAction(rectangle)
toolbar.addAction(ellipse)
toolbar.addAction(pen)
if __name__ == '__main__':
import sys
app = QtWidgets.QApplication(sys.argv)
w = MainWindow()
w.show()
sys.exit(app.exec_())