Issue
I'm creating a file browser with PyQt6. This is what I'm thinking of doing right now:
from PyQt6 import QtWidgets as qtw
from PyQt6 import QtGui as qtg
class FileBrowserWidget(qtw.QScrollArea):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.current_items = []
self.main_widget = qtw.QWidget()
self.main_widget.setLayout(qtw.QVBoxLayout())
self.setWidget(self.main_widget)
def add_file(self, thumbnail: qtg.QPixmap, description: str):
item = qtw.QWidget()
item.setLayout(qtw.QHBoxLayout())
file_thumbnail_label = qtw.QLabel()
file_thumbnail_label.setPixmap(thumbnail)
file_description_label = qtw.QLabel(description)
item.layout().addWidget(file_thumbnail_label)
item.layout().addWidget(file_description_label)
self.current_items.append(item)
Note that this is just a rough sketch of the widget. All the code does is display a (thumbnail, description)
pair for files inside a directory in a scrollable window. I also plan to implement pagination for it, with at least 25 rows (files) per page.
My questions are:
- Is this the way to do it or is there some other better way to go about creating a file browser?
- How would I go about implementing pagination to the file browser?
EDIT:
- My apologies, it's not just any file browser, it's an image file browser.
- Example image of what I'm thinking of creating:
Solution
A basic possibility is to use a QListWidget, with some customized settings and precautions when adding items:
- the
iconSize()
must be big enough to show the thumbnails; - a bigger font for the view
- the
sizeHint()
of each item must be specified in order to always respect the same row height and provide text elision; - the image must be scaled and "enlarged" to the icon size in order to keep vertical alignment of the text, otherwise images that have different widths will show the text starting at different positions;
class ImageListView(QtWidgets.QWidget):
def __init__(self):
super().__init__()
self.view = QtWidgets.QListWidget()
self.view.setIconSize(QtCore.QSize(64, 64))
bigFont = self.font()
bigFont.setPointSize(24)
self.view.setFont(bigFont)
self.addButton = QtWidgets.QPushButton('Add image(s)')
layout = QtWidgets.QVBoxLayout(self)
layout.addWidget(self.view)
layout.addWidget(self.addButton)
self.addButton.clicked.connect(self.addImage)
def addImage(self):
paths, _ = QtWidgets.QFileDialog.getOpenFileNames(self,
'Select image(s)', '', 'Images (*.png *.jpg *.jpeg)')
size = self.view.iconSize()
for path in paths:
source = QtGui.QPixmap(path)
if source.isNull():
continue
if source.width() > size.width() or source.height() > size.height():
source = source.scaled(size, QtCore.Qt.KeepAspectRatio,
QtCore.Qt.SmoothTransformation)
# create an empty squared image to keep vertical alignment
square = QtGui.QPixmap(size)
square.fill(QtCore.Qt.transparent)
qp = QtGui.QPainter(square)
rect = source.rect()
rect.moveCenter(square.rect().center())
qp.drawPixmap(rect, source)
qp.end()
name = QtCore.QFileInfo(path).baseName()
item = QtWidgets.QListWidgetItem(name)
item.setIcon(QtGui.QIcon(square))
item.setToolTip(path)
item.setSizeHint(size)
self.view.addItem(item)
For more advanced customization, you can still use a QListWidget, but you also need to set a custom item delegate and override its paint()
method.
Answered By - musicamante
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.