在 pyQt4 中的图像上涂鸦

Scribble pad over an image in pyQt4

假设我想加载一张图片并在上面涂鸦。但是如果图像很大,那么它就无法放入图像查看器中。因此我想要一个滚动条。我该怎么做?

例如:假设图像是:

当我将它加载到我的程序中时,它变成:

现在我想把它放到滚动条小部件中(以便可以完全访问图像),最重要的是我想在上面做任何类型的绘图(涂鸦)。我如何使用 PyQt4 执行此操作?是否有可用的 python 代码?

如果您想放置带有 QScrollbar 的图像,可能的选择是使用 QScrollArea,但如果您表示要绘制,则正确的选择是使用 QGraphicsView因为它允许您添加项目。例如,要制作涂鸦,您可以使用 QGraphicsPathItem 和图像 QGraphicsPixmapItem,如下所示:

from PyQt4 import QtCore, QtGui

class ScribbleView(QtGui.QGraphicsView):
    def __init__(self, parent=None):
        super(ScribbleView, self).__init__(parent)
        self.setScene(QtGui.QGraphicsScene(self))
        self._image_item = QtGui.QGraphicsPixmapItem()
        self.scene().addItem(self._image_item)
        self.initial_path()

    def initial_path(self):
        self._path = QtGui.QPainterPath()
        pen = QtGui.QPen(QtGui.QColor("green"), 4, QtCore.Qt.SolidLine, QtCore.Qt.RoundCap)
        self._path_item = self.scene().addPath(self._path, pen)

    @QtCore.pyqtSlot()
    def load_image(self):
        filename = QtGui.QFileDialog.getOpenFileName(self, 
            "Open Image", QtCore.QDir.currentPath(), 
            "Image Files (*.png *.jpg *.bmp)")
        if filename:
            self._image_item.setPixmap(QtGui.QPixmap(filename))

    def mousePressEvent(self, event):
        if not self._image_item.pixmap().isNull():
            self._path.moveTo(self.mapToScene(event.pos()))
            self._path_item.setPath(self._path)
        super(ScribbleView, self).mousePressEvent(event)

    def mouseMoveEvent(self, event):
        if not self._image_item.pixmap().isNull():
            self._path.lineTo(self.mapToScene(event.pos()))
            self._path_item.setPath(self._path)
        super(ScribbleView, self).mousePressEvent(event)

    def mouseReleaseEvent(self, event):
        if not self._image_item.pixmap().isNull():
            self._path.lineTo(self.mapToScene(event.pos()))
            self._path_item.setPath(self._path)       
            self.initial_path()
        super(ScribbleView, self).mouseReleaseEvent(event)

class ScribbleWidget(QtGui.QMainWindow):
    def __init__(self, parent=None):
        super(ScribbleWidget, self).__init__(parent)
        view = ScribbleView()
        self.setCentralWidget(view)
        menubar = self.menuBar()
        file_menu = menubar.addMenu("&File")
        image_action = file_menu.addAction("Load Image")
        image_action.triggered.connect(view.load_image)

if __name__ == '__main__':
    import sys
    app = QtGui.QApplication(sys.argv)
    w = ScribbleWidget()
    w.resize(640, 480)
    w.show()
    sys.exit(app.exec_())