使用PYQT4向Scribble应用程序添加工具

2024-04-23 14:01:45 发布

您现在位置:Python中文网/ 问答频道 /正文

我正试图写一个应用程序,作为微软绘画或其他简单的图形编辑器的作品。我的目标是提供这样的功能:不同的工具(画线,图形等),可以改变颜色,宽度,大小和撤消/重做功能。我认为最简单的方法是创建用于绘制和查看对象的分离类。不幸的是,它工作不正常。这是我的密码:

import sys
from PyQt4 import QtGui, QtCore

class Example(QtGui.QWidget):    
    def __init__(self):
        super(Example, self).__init__()
        self.update()

        self.view = View(self)
        self.action = Action(self.view.scene)

        self.UI()

    def UI(self):
        self.setGeometry(300,300,300,300)

        self.setWindowTitle('Pen styles')
        self.undo = QtGui.QPushButton("undo", self)
        self.undo.clicked.connect(self.action.undoStack.undo)
        self.redo = QtGui.QPushButton("redo", self)
        self.redo.clicked.connect(self.action.undoStack.redo)
        self.redo.move(0,50)
        self.tool = QtGui.QPushButton("tool", self)
        self.tool.setCheckable(True)
        self.tool.clicked[bool].connect(self.new)
        self.tool.move(0,100)

        layout = QtGui.QVBoxLayout()
        layout.addWidget(self.view)
        self.setLayout(layout)

        self.show()

    def new(self):    
        pass


class Action(QtGui.QGraphicsScene):    
    def __init__(self, scene):    
        QtGui.QGraphicsScene.__init__(self)

        self.undoStack = QtGui.QUndoStack(self)

        self.scene = scene
        self.scene.addLine(0,0,150,150)

        self.undoStack = QtGui.QUndoStack(self)

    def mousePressEvent(self, event):
        if event.button() == QtCore.Qt.LeftButton:
            self.start = event.pos()
            self.scene.addLine(0,0,150,250)

    def mouseReleaseEvent(self, event):
        start = QtCore.QPointF(self.mapToScene(self.start))
        end = QtCore.QPointF(self.mapToScene(event.pos()))
        self.drawing(start, end)

    def drawing(self, start, end):
        self.line = QtGui.QGraphicsLineItem(QtCore.QLineF(start, end))
        self.line.setPen(QtGui.QPen(QtCore.Qt.blue,3,
                QtCore.Qt.SolidLine, QtCore.Qt.RoundCap, QtCore.Qt.RoundJoin))

        self.scene.addLine(0,0,150,300)
        command = Draw(self.line, self.scene)
        self.undoStack.push(command)


class Draw(QtGui.QUndoCommand):
    def __init__(self, line, scene):
        QtGui.QUndoCommand.__init__(self)

        self.line = line
        self.scene = scene

    def redo(self):
        self.scene.addItem(self.line)

    def undo(self):
        self.scene.removeItem(self.line)


class View(QtGui.QGraphicsView):    
    def __init__(self, parent):    
        QtGui.QGraphicsView.__init__(self, parent)    

        self.scene = QtGui.QGraphicsScene()
        self.action = Action(self.scene)
        self.setScene(self.scene)
        self.setSceneRect(QtCore.QRectF(self.viewport().rect()))


def main():
    app = QtGui.QApplication(sys.argv)
    ex = Example()

    sys.exit(app.exec_())


if __name__ == '__main__':
    main()

我的问题是我不能用我的鼠标画任何东西。如果集体诉讼和观点结合起来,一切都很好,但当我把它们放在一边时,什么也没有发生(也没有错误)。我进行这种分离的原因是,我很简单地想添加另一个具有其他功能的类(绘制省略号、矩形…),并用Action类交换它们。我在场景中添加了line(在Actioninit中),它被正确地绘制了,但是MouseEvents根本不起作用所有的。那个按钮“工具”是用来改变绘图工具。你知道吗

这种方式,在我看来,是最好的方式来实现能力涂鸦与不同的工具在同一画布(场景)。我的路不好,所以我请求帮助。我能做些什么来修复这个代码,让它按我的意愿工作?错误在哪里?或者整个方法都错了,应该换一种方法?我使用pyqt4和python3.4。你知道吗


Tags: 工具selfeventinitdeflinetoolscene
1条回答
网友
1楼 · 发布于 2024-04-23 14:01:45

当前代码有两个在View.__init__内创建的QGraphicsScene实例。一个是标准的QGraphicsScene,另一个是您的子类Action。但是您的视图只能附加到一个场景,因此其中一个场景是多余的,不能正常工作。您已经将它附加到QGraphicsScene,因此Action对象是不起作用的对象。你知道吗

相反,您应该去掉单调乏味的QGraphicsScene,只实例化Action类。在对view.setScene()的调用中使用实例化的Action对象。类似地,在Action类中,不需要传入另一个场景。只需使用它自己(因此用Action类中的self替换self.scene的所有实例)

相关问题 更多 >