QGraphicsRectItem 设置图像崩溃

QGraphicsRectItem set image crashes

我正在研究如何将地图图像设置为 QGraphicsScene 对象中的 QGraphicsRectItem 对象,但我在 PyQT5 中完全崩溃了。

密码是:

import sys
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
import smopy
from PIL.ImageQt import ImageQt


class MapWidget(QGraphicsRectItem):

    def __init__(self, parent=None):
        super(MapWidget, self).__init__(parent)

        self.setRect(0.0, 0.0, 800, 600)
        self.setFlags(self.ItemIsSelectable | self.ItemIsMovable)
        self.image = None

        # get map
        map = smopy.Map((42., -1., 53., 3.), z=11, tilesize=48)
        img = ImageQt(map.img)
        self.image = QPixmap.fromImage(img)

    def paint(self, painter, option, widget=None):
        painter.drawPixmap(QPoint(0, 0), self.image)


class Window(QDialog):

    def __init__(self):
        super(Window, self).__init__()

        self.layout = QVBoxLayout(self)

        self.view = QGraphicsView()

        self.scene = QGraphicsScene()

        self.view.setScene(self.scene)

        self.layout.addWidget(self.view)

        self.map = MapWidget()

        self.scene.addItem(self.map)

        self.resize(1200, 800)


if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = Window()
    window.show()
    sys.exit(app.exec_())

输出信息为:

Process finished with exit code 139 (interrupted by signal 11: SIGSEGV)

与其将其转换为 PIL,不如将其转换为 numpy 并加载到 QImage。另一方面,最好使用 QGraphicsPixmapItem,因为它可以正确重绘。

import sys
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
import smopy


class MapWidget(QGraphicsPixmapItem):
    def __init__(self, parent=None):
        super(MapWidget, self).__init__(parent)
        self.setFlags(self.ItemIsSelectable | self.ItemIsMovable)

        # get map
        map = smopy.Map((42., -1., 53., 3.), z=11, tilesize=48)
        numpy_image= map.to_numpy()
        img = QImage(numpy_image.data, *numpy_image.shape[1::-1], QImage.Format_RGB888)
        self.setPixmap(QPixmap.fromImage(img))

class Window(QDialog):
    def __init__(self):
        super(Window, self).__init__()

        self.layout = QVBoxLayout(self)
        self.view = QGraphicsView()
        self.scene = QGraphicsScene()
        self.view.setScene(self.scene)

        self.layout.addWidget(self.view)

        self.map = MapWidget()
        self.scene.addItem(self.map)
        self.resize(1200, 800)


if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = Window()
    window.show()
    sys.exit(app.exec_())