Aquarius_Girl
Aquarius_Girl

Reputation: 22906

How to draw on QGraphicsView from QMainWindow

Current design shown below of QgraphicsView and QMainWindow class is an example of the design I have in a different software.

I had to add scrollbars to the QGraphicsView. The original software has all mouse events handled in QMainWindow.

Questions: What is the way to draw on QGraphicsView through QMainWindow?

import sys

from PyQt4 import QtGui
from PyQt4 import QtCore

class Window(QtGui.QGraphicsView):

  def __init__(self, parent=None):

        QtGui.QGraphicsView.__init__(self, parent)
        self.scene = QtGui.QGraphicsScene(self)
        self.scene.setBackgroundBrush(QtGui.QBrush(QtCore.Qt.darkGray, QtCore.Qt.SolidPattern))
        self.setScene(self.scene)

        #self.setDragMode(QtGui.QGraphicsView.ScrollHandDrag)
        self.setTransformationAnchor(QtGui.QGraphicsView.AnchorUnderMouse)
        #self.viewport().setCursor(QtCore.Qt.CrossCursor)
        self.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOn)
        self.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOn)

        print "sdsads"


  def mousePressEvent(self, ev):
        item = QtGui.QGraphicsTextItem("")
        item.setPos(ev.x(), ev.y())
        self.scene.addItem(item)

        print "ev.x() ", ev.x()


class CityscapesLabelTool(QtGui.QMainWindow):
    def __init__(self, parent=None):

        QtGui.QMainWindow.__init__(self, parent)
        centralwidget = Window()
        self.setCentralWidget(centralwidget) 

        centralwidget.scene.addPixmap(QtGui.QPixmap("exit.png"))



app = QtGui.QApplication(sys.argv)
GUI = CityscapesLabelTool()
GUI.show()
sys.exit(app.exec_())

Upvotes: 1

Views: 2238

Answers (1)

eyllanesc
eyllanesc

Reputation: 243887

In a QGraphicsView it is normal to add items to the scene, for example in case you want to draw a polygon you must use QGraphicsPolygonItem, also if you want to get correct points you must use QGraphicsScene instead of QGraphicsView.

In the following example you can indicate the polygon points by left clicking and finish the drawing with the right click.

import sys

from PyQt4 import QtCore, QtGui

class GraphicsScene(QtGui.QGraphicsScene):
    def __init__(self, *args, **kwargs):
        QtGui.QGraphicsScene.__init__(self, *args, **kwargs)
        self.polygon = None

    def mousePressEvent(self, ev):
        if ev.button() == QtCore.Qt.RightButton:
            self.polygon << ev.scenePos()
            item = QtGui.QGraphicsPolygonItem(self.polygon)
            item.setPen(QtGui.QPen(QtCore.Qt.red))
            item.setBrush(QtGui.QBrush(QtCore.Qt.red))
            self.addItem(item)
            # or
            # self.addPolygon(self.polygon, QtGui.QPen(QtCore.Qt.red), QtGui.QBrush(QtCore.Qt.red))
            self.polygon = None

        else:
            if self.polygon is None:
                self.polygon = QtGui.QPolygonF()
            self.polygon << ev.scenePos()

class Window(QtGui.QGraphicsView):
    def __init__(self, parent=None):
        QtGui.QGraphicsView.__init__(self, parent)
        self.scene =GraphicsScene(QtCore.QRectF(0, 0, 640, 480), self)
        self.scene.setBackgroundBrush(QtGui.QBrush(QtCore.Qt.darkGray, QtCore.Qt.SolidPattern))
        self.setScene(self.scene)
        #self.setDragMode(QtGui.QGraphicsView.ScrollHandDrag)
        self.setTransformationAnchor(QtGui.QGraphicsView.AnchorUnderMouse)
        #self.viewport().setCursor(QtCore.Qt.CrossCursor)
        self.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOn)
        self.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOn)


class CityscapesLabelTool(QtGui.QMainWindow):
    def __init__(self, parent=None):

        QtGui.QMainWindow.__init__(self, parent)
        centralwidget = Window()
        self.setCentralWidget(centralwidget) 

        centralwidget.scene.addPixmap(QtGui.QPixmap("exit.png"))


app = QtGui.QApplication(sys.argv)
GUI = CityscapesLabelTool()
GUI.show()
sys.exit(app.exec_())

Output:

enter image description here


You have an XY problem, where you are looking for the solution for a solution of the main problem without knowing that it is the correct one, according to what you comment your main problem is to add QScrollBar to the QMainWindow, and in that element you want to make drawings, so for that it is not necessary to use a QGraphicsView but a QScrollArea.

import sys

from PyQt4 import QtCore, QtGui


class Window(QtGui.QWidget):
    def __init__(self, parent=None):
        QtGui.QWidget.__init__(self, parent)
        self.polygon = None
        self.setFixedSize(640, 480)
        self.pixmap = None

    def mousePressEvent(self, ev):
        if self.polygon is None:
            self.polygon = QtGui.QPolygon()
        self.polygon << ev.pos()
        self.update()

    def paintEvent(self, ev):
        painter = QtGui.QPainter(self)
        painter.fillRect(self.rect(), QtGui.QBrush(QtCore.Qt.darkGray, QtCore.Qt.SolidPattern))
        painter.drawPixmap(QtCore.QPoint(0, 0), QtGui.QPixmap("exit.png"))
        if self.polygon is not None:
            painter.setPen(QtCore.Qt.blue)
            painter.drawPolyline(self.polygon)



class CityscapesLabelTool(QtGui.QMainWindow):
    def __init__(self, parent=None):

        QtGui.QMainWindow.__init__(self, parent)
        scroll = QtGui.QScrollArea()

        scroll.setBackgroundRole(QtGui.QPalette.Dark)
        scroll.setWidget(Window())
        scroll.setWidgetResizable(True)
        self.setCentralWidget(scroll)



app = QtGui.QApplication(sys.argv)
GUI = CityscapesLabelTool()
GUI.show()
sys.exit(app.exec_())

enter image description here

Upvotes: 1

Related Questions