I've a problem with pyqt5. I've create a windows with a scene that has a background image, re-implementing drawBackground. I've also a button that allow me to add a line in a position on the scene. The problem is that if i click the button to draw the line, then this line is drawn in a separate scene with it's own background, instead of into the scene i have. Seems like it create a new scene to draw the line on. Here is my code:
import sys
from PyQt5 import QtGui
from PyQt5.QtGui import QImage
from PyQt5.QtWidgets import (QMainWindow, QGraphicsView, QPushButton,
QHBoxLayout, QVBoxLayout, QWidget, QApplication, QGraphicsScene)
class GraphicsScene(QGraphicsScene):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self._image = QImage()
@property
def image(self):
return self._image
@image.setter
def image(self, img):
self._image = img
self.update()
def drawBackground(self, painter, rect):
if self.image.isNull():
super().drawBackground(painter, rect)
else:
painter.drawImage(rect, self._image)
class MainWindow(QWidget):
def __init__(self):
super().__init__()
self.title = "parcelDeliveryIta";
self.top = 100
self.left = 100
self.width = 1500
self.height = 900
self.initUI()
def initUI(self):
self.scene = GraphicsScene(self)
self.scene._image = QImage('Italy.png')
view = QGraphicsView(self.scene, self)
self.scene.setSceneRect(0, 0, view.width(), view.height())
addLine = QPushButton('AddLine')
addLine.clicked.connect(self.addLine)
hbox = QHBoxLayout(self)
hbox.addWidget(view)
vbox = QVBoxLayout(self)
vbox.addWidget(addLine)
hbox.addLayout(vbox)
self.setWindowTitle(self.title)
self.setGeometry(self.top, self.left, self.width, self.height)
self.setFixedSize(self.width, self.height)
self.setLayout(hbox)
self.show()
def addLine(self):
self.scene.addLine(0, 0, 100, 100)
if __name__ == "__main__":
app = QApplication(sys.argv)
window = MainWindow()
sys.exit(app.exec_())
and this is the result when clicking the button:
As it is possible to see, the line is drawn with its own backgroung, that is image I've setted as background to the scene (the image above is cropped to show better the line) Thanks for helping.
It seems that my previous solution is not suitable for your case since as the docs points out:
void QGraphicsScene::drawBackground(QPainter *painter, const QRectF &rect)
Draws the background of the scene using painter, before any items and the foreground are drawn. Reimplement this function to provide a custom background for the scene.All painting is done in scene coordinates. The rect parameter is the exposed rectangle.
If all you want is to define a color, texture, or gradient for the background, you can call setBackgroundBrush() instead.
See also drawForeground() and drawItems().
(emphasis mine)
That paint will also be used to paint the base of the items and therefore caused that behavior.
So you will have to resort to another solution, for example to use a QGraphicsPixmapItem as a base and readjust the size of the window with that information:
import sys
from PyQt5.QtGui import QPixmap
from PyQt5.QtWidgets import (
QGraphicsView,
QPushButton,
QHBoxLayout,
QVBoxLayout,
QWidget,
QApplication,
QGraphicsScene,
)
class GraphicsView(QGraphicsView):
def __init__(self, parent=None):
super().__init__(parent)
scene = QGraphicsScene(self)
self.setScene(scene)
self._pixmap_item = self.scene().addPixmap(QPixmap())
self._pixmap_item.setZValue(-1)
@property
def pixmap(self):
return self._pixmap_item.pixmap()
@pixmap.setter
def pixmap(self, pixmap):
self._pixmap_item.setPixmap(pixmap)
self.scene().setSceneRect(self._pixmap_item.boundingRect())
def resizeEvent(self, event):
if not self._pixmap_item.pixmap().isNull():
self.fitInView(self._pixmap_item)
super().resizeEvent(event)
class MainWindow(QWidget):
def __init__(self):
super().__init__()
self.title = "parcelDeliveryIta"
self.top = 100
self.left = 100
self.width = 1500
self.height = 900
self.initUI()
def initUI(self):
self.view = GraphicsView(self)
self.view.pixmap = QPixmap("Italy.png")
addLine = QPushButton("AddLine")
addLine.clicked.connect(self.addLine)
hbox = QHBoxLayout(self)
hbox.addWidget(self.view)
vbox = QVBoxLayout()
vbox.addWidget(addLine)
hbox.addLayout(vbox)
self.setWindowTitle(self.title)
self.setGeometry(self.top, self.left, self.width, self.height)
self.setFixedSize(self.width, self.height)
self.show()
def addLine(self):
self.view.scene().addLine(0, 0, 100, 100)
if __name__ == "__main__":
app = QApplication(sys.argv)
window = MainWindow()
sys.exit(app.exec_())