You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PyQt5求助:如何向QGraphicsScene添加元素及拼图块排列异常问题

解决QGraphicsScene中拼图块堆叠问题的方案

嘿,我懂你遇到的麻烦了——分割后的拼图块全都挤在左上角,没法按照原图的顺序排列对吧?这其实是个很常见的小问题:默认情况下,每个QGraphicsPixmapItem被添加到场景时,初始位置都是(0, 0),所以它们会直接堆叠在一起。我们只需要给每个拼图块设置对应的位置,就能让它们按原图顺序排列啦!

核心修改点

你需要在创建每个QGraphicsPixmapItem之后,调用setPos()方法,把该拼图块在原图中的对应坐标传递进去。具体来说:

  • 横向位置:i * x_side(i是当前列索引,x_side是单块拼图的宽度)
  • 纵向位置:j * y_side(j是当前行索引,y_side是单块拼图的高度)

另外还要注意一个细节:QPixmap.copy()的参数需要整数类型,所以我们最好把计算出来的x_side和y_side转成整数,避免潜在的问题。

修改后的完整代码

import sys
from vision import Ui_MainWindow
from PyQt5.QtWidgets import QMainWindow, QFileDialog, QGraphicsScene
from PyQt5 import QtWidgets, QtGui, QtCore
from PIL import Image

class MyWindow(QMainWindow, Ui_MainWindow):
    def __init__(self):
        super(MyWindow, self).__init__()
        self.setupUi(self)
        self.item = []
        self.if_opened = 0
        self.dim = 3
        # 初始化QGraphicsScene,这一步很重要!
        self.scene = QGraphicsScene()
        self.showView.setScene(self.scene)
        self.upset.clicked.connect(self.make_upset)
        # 初始化图片相关变量(根据你的打开逻辑补充赋值)
        self.image = None
        self.image_file = None

    def make_upset(self):
        if self.image is None or self.image_file is None:
            return
        self.scene.clear()
        pixmap = QtGui.QPixmap(self.image)
        # 转成整数,避免QPixmap.copy参数类型问题
        x_side = int(self.image_file.size[0] / self.dim)
        y_side = int(self.image_file.size[1] / self.dim)
        self.item.clear()
        for j in range(self.dim):
            for i in range(self.dim):
                # 裁剪对应区域的图片
                m = pixmap.copy(i * x_side, j * y_side, x_side, y_side)
                pix_item = QtWidgets.QGraphicsPixmapItem(m)
                # 设置拼图块的位置,对应原图的分割位置
                pix_item.setPos(i * x_side, j * y_side)
                self.item.append(pix_item)
                self.scene.addItem(pix_item)

if __name__ == '__main__':
    app = QtWidgets.QApplication(sys.argv)
    myShow = MyWindow()
    myShow.show()
    sys.exit(app.exec_())

额外说明

  1. 我在__init__里添加了self.scene的初始化代码,确保场景对象存在,否则添加item会报错。
  2. 循环里去掉了不必要的count变量,直接用列表append即可,代码更简洁。
  3. 如果你有打开本地图片的逻辑(比如通过QFileDialog选择图片),记得在打开图片后给self.image(图片路径)和self.image_file(PIL打开的图片对象)赋值,这样make_upset方法才能正常工作。

内容的提问来源于stack exchange,提问作者Eric_Seaser

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 08:27:32