I’m trying to develop some image viewer in the same vein as KDE’s Gwenview, but with some very specific features for my actual application. I’ll be using python 3.8 and PyQt5.
The question is: is there already any widget for browsing files in icon-mode, showing thumbnails of images, or would I have to implement that whole jazz from the scratch?
Hi @Rafael_Lago welcome to the forum, sorry for the delay in replying
Unfortunately, there isn’t a ready-to-go widget for this, but it’s fairly straightforward to implement. See a quick example below, which is used the model view framework to render thumbnails for image files in a folder. Here we’re using a table view to layout the items, and a custom delegate to draw the thumbnails (you can add anything else you like).
from collections import namedtuple
from PyQt5.QtCore import QAbstractTableModel, Qt, QSize
from PyQt5.QtGui import QImage, QPixmap
from PyQt5.QtWidgets import QApplication, QMainWindow, QTableView, QStyledItemDelegate
# Create a custom namedtuple class to hold our data.
preview = namedtuple("preview", "id title image")
NUMBER_OF_COLUMNS = 4
CELL_PADDING = 20 # all sides
def paint(self, painter, option, index):
# data is our preview object
data = index.model().data(index, Qt.DisplayRole)
if data is None:
width = option.rect.width() - CELL_PADDING * 2
height = option.rect.height() - CELL_PADDING * 2
# option.rect holds the area we are painting on the widget (our table cell)
# scale our pixmap to fit
scaled = data.image.scaled(
# Position in the middle of the area.
x = CELL_PADDING + (width - scaled.width()) / 2
y = CELL_PADDING + (height - scaled.height()) / 2
painter.drawImage(option.rect.x() + x, option.rect.y() + y, scaled)
def sizeHint(self, option, index):
# All items the same size.
return QSize(300, 200)
def __init__(self, todos=None):
# .data holds our data for display, as a list of Preview objects.
self.previews = 
def data(self, index, role):
data = self.previews[index.row() * 4 + index.column() ]
# Incomplete last row.
if role == Qt.DisplayRole:
return data # Pass the data to our delegate to draw.
if role == Qt.ToolTipRole:
def columnCount(self, index):
def rowCount(self, index):
n_items = len(self.previews)
return math.ceil(n_items / NUMBER_OF_COLUMNS)
self.view = QTableView()
delegate = PreviewDelegate()
self.model = PreviewModel()
# Add a bunch of images.
for n, fn in enumerate(glob.glob("*.jpg")):
image = QImage(fn)
item = preview(n, fn, image)
app = QApplication(sys.argv)
window = MainWindow()
If you drop this file in any folder containing jpeg files (extension “*.jpg”) they’ll be shown in a list.
Thank you very much! I was actually trying to develop it using QTableView, but I am not very familiar with this part of Qt5 (yet). Your code is very helpful!
So, I extended the concept, but using QFilesystemModel and QListView in IconMode with a given gridSize:
modUI.py: import sys, mathimport PyQt5.QtCore as QtCoreimport PyQt5.QtWidgets as QtWid - Pastebin.com
main.py: import sysfrom PyQt5.QtWidgets import QApplication, QMainWindowfrom modUI im - Pastebin.com
One of the remaining problems is that the position of the icons is not updated when I resize the window, which gives some funny results (see attached image).
I assume I have to connect some signal to some slot (i.e. resize of window to QListView.update?) but I’m not very familiar with Qt at this point to know which signal to what. Can anyone shed some light?
EDIT#1: nevermind, I just found about setResizeMode(QtWidgets.QListView.Adjust)