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_())
额外说明
- 我在
__init__里添加了self.scene的初始化代码,确保场景对象存在,否则添加item会报错。 - 循环里去掉了不必要的
count变量,直接用列表append即可,代码更简洁。 - 如果你有打开本地图片的逻辑(比如通过QFileDialog选择图片),记得在打开图片后给
self.image(图片路径)和self.image_file(PIL打开的图片对象)赋值,这样make_upset方法才能正常工作。
内容的提问来源于stack exchange,提问作者Eric_Seaser
相关产品推荐
相关产品推荐

