My tool loops through a few thousand images and loads thumbnails of the images into my listview as seen below. However my application freezes until all the images are processed. I was wondering if there was a way i could populate the listview with images as they have been loaded, preventing the UI from freezing and letting the user go about using the application while the images are populated?
This is all done us python and pyside.
Code:
import os
import sys
from PySide import QtGui, QtCore
class Example(QtGui.QMainWindow):
def __init__(self):
super(Example, self).__init__()
self.resize(800, 400)
self.setWindowTitle('Image Viewer')
self.image_dir = "C:/Users/JokerMartini-Asus/Desktop/textures/thumbs"
self.ui_image_viewer = QtGui.QListView()
self.ui_image_viewer.setViewMode(QtGui.QListView.IconMode)
self.ui_image_viewer.setResizeMode(QtGui.QListView.Adjust)
self.ui_image_viewer.setEditTriggers(QtGui.QAbstractItemView.NoEditTriggers)
self.ui_image_viewer.setIconSize(QtCore.QSize(300,300))
self.ui_image_viewer.setMovement(QtGui.QListView.Static)
self.ui_image_viewer.setModel(QtGui.QStandardItemModel())
for img in os.listdir(self.image_dir):
img_path = os.path.join(self.image_dir, img)
pixmap = QtGui.QPixmap(img_path)
name = os.path.splitext(os.path.basename(img_path))[0]
item = QtGui.QStandardItem(QtGui.QIcon(pixmap), name)
self.ui_image_viewer.model().appendRow(item)
# Layout
grid = QtGui.QVBoxLayout()
grid.setContentsMargins(10,10,10,10)
grid.addWidget(self.ui_image_viewer)
main_widget = QtGui.QWidget()
main_widget.setLayout(grid)
self.setCentralWidget(main_widget)
self.show()
def main():
app = QtGui.QApplication(sys.argv)
ex = Example()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
The process that generates an overload, is the creation of the QPixmap, so if we distribute that load over time we can improve the response, we can do this through a QTimer.
Another solution would be to load the image when necessary, that is to say when the scrollbar is moved, but for that we must overwrite the method data of the model, also we must create a new role to store the path of the image, but analyzing the logic of data for QStandardItemModel I have found that called the SizeHintRole role, and it calls the role DecorationRole, generating the same error, so what we should do is put a predefined size so that it avoids the call to DecorationRole, and thus avoid the overload: