I want to create a grid of buttons with images. The image on each button is a piece from a bigger image which is cutted into pieces - so the button grid can be seen as tiles of the original image (the code i used to put a image on the button is from here).
To cut the image (image=QPixmap(path_to_image)
) into pieces i used the methodimage.copy(x, y, width, height)
in a for loop.
At first i thought that the code works fine. A more precise check shows that the image pieces have overlapping parts.
Here my code which was tested with an GIF-Image:
import os
import sys
from PyQt5.QtCore import QSize
from PyQt5.QtGui import QPixmap, QIcon
from PyQt5.QtWidgets import \
QWidget, QApplication, \
QGridLayout, \
QLabel, QPushButton
def cut_image_into_tiles(image, rows=4, cols=4) -> dict:
if isinstance(image, str) and os.path.exists(image):
image = QPixmap(image)
elif not isinstance(image, QPixmap):
raise ValueError("image must be str or QPixmap object")
# Dim of the tile
tw = int(image.size().width() / cols)
th = int(image.size().height() / rows)
# prepare return value
tiles = {"width": tw, "height": th}
for r in range(rows):
for c in range(cols):
tile = image.copy(c * th, r * tw, tw, th)
# args: x, y, width, height
# https://doc.qt.io/qt-5/qpixmap.html#copy-1
tiles[(r, c)] = tile
return tiles
def create_pixmapbutton(pixmap, width=0, height=0) -> QPushButton:
if isinstance(pixmap, QPixmap):
button = QPushButton()
if width > 0 and height > 0:
button.setIconSize(QSize(width, height))
else:
button.setIconSize(pixmap.size())
button.setIcon(QIcon(pixmap))
return button
def run_viewer(imagepath, rows=4, cols=4):
# ImageCutter.run_viewer(imagepath)
app = QApplication(sys.argv)
image = QPixmap(imagepath)
tiles = cut_image_into_tiles(image=image, rows=rows, cols=cols)
tilewidth = tiles["width"]
tileheight = tiles["height"]
# get dict tiles (keys:=(row, col) or width or height)
viewer = QWidget()
layout = QGridLayout()
viewer.setLayout(layout)
viewer.setWindowTitle("ImageCutter Viewer")
lbl = QLabel()
lbl.setPixmap(image)
layout.addWidget(lbl, 0, 0, rows, cols)
for r in range(rows):
for c in range(cols):
btn = create_pixmapbutton(
tiles[r, c], width=tilewidth, height=tileheight)
btninfo = "buttonsize={}x{}".format(tilewidth, tileheight)
btn.setToolTip(btninfo)
# logger.debug(" create button [{}]".format(btninfo))
layout.addWidget(btn, r, cols + c)
viewer.show()
sys.exit(app.exec_())
I tested the code with run_viewer(path_to_a_gif_image, rows=3, cols=3)