pyqt5 рисование линий с помощью кнопки на QGraphicsScene - PullRequest
1 голос
/ 04 мая 2020

У меня проблема с pyqt5. Я создал windows со сценой с фоновым изображением, повторно реализуя drawBackground. У меня также есть кнопка, которая позволяет мне добавить линию в позицию на сцене. Проблема в том, что если я нажимаю кнопку, чтобы нарисовать линию, то эта линия рисуется в отдельной сцене с собственным фоном, а не в сцене, которая у меня есть. Похоже, это создает новую сцену, чтобы нарисовать линию. Вот мой код:

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_())

, и это результат нажатия кнопки:

enter image description here

Как это возможно видите, линия нарисована с помощью собственного фона, то есть изображения, которое я установил в качестве фона для сцены (изображение выше обрезано, чтобы лучше показать линию) Спасибо за помощь.

1 Ответ

0 голосов
/ 05 мая 2020

Объяснение:

Похоже, что мое предыдущее решение не подходит для вашего случая, так как документы указывают:

void QGraphicsScene :: drawBackground (QPainter * painter, const QRectF & rect)

Dr aws фон сцены с использованием живописца,
перед любыми элементами и передний план нарисован. Переопределите эту функцию, чтобы обеспечить пользовательский фон для сцены.

Все рисование выполняется в координатах сцены. Параметр rect - это открытый прямоугольник.

Если все, что вам нужно, это определить цвет, текстуру или градиент фона, вы можете вместо этого вызвать setBackgroundBru sh ().

См. также drawForeground () и drawItems ().

(выделено мной)

Эта краска также будет использоваться для рисования основы элементов и, следовательно, вызывает такое поведение.


Решение:

Поэтому вам придется прибегнуть к другому решению, например, использовать QGraphicsPixmapItem в качестве основы и перенастроить размер окна с помощью этой информации:

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_())
...