我在pyqt5上遇到了一个问题。我创建了一个有背景图片的场景的窗口,重新实现了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_())
这是点击按钮后的结果。
正如可以看到的,线条是用自己的背景画的,也就是我设置为场景背景的图片(上面的图片是裁剪过的,可以更好地显示线条),谢谢你的帮助。
void QGraphicsScene::drawBackground(QPainter *painter, const QRectF &rect)
使用painter绘制场景的背景。 前任何项目 和前景的绘制。重新实现这个功能,为场景提供一个自定义的背景。所有的绘制都是在场景坐标中进行的。rect参数是暴露的矩形。
如果你只想为背景定义一个颜色、纹理或渐变,你可以调用setBackgroundBrush()来代替。
也请参考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_())