[PyQt] Dont understand QListView behavior after filling the QStandardItemModel is finished

Gottfried Müller gottfried.mueller at gmx.de
Sat May 11 16:02:03 BST 2019


Hello,

in the following example a QStandardItemModel (assigned to QListView) is 
filled with a procedure. There are two cases filling the model (menu) 
and display the content.

The first case displays the the content of the model directly. In the 
second case a sleep command is following the filling function. In the 
second case the content appears when the sleep time ended.

But in both cases the content of QStatusBar (counter of generated items) 
appears directly after the filling process of the model is ready.

Why appears the the QListView content in the second case so late? Does 
an action exist to force the display of the items before the sleep event?

Note: You can exchange the sleep command with any procedure which needs 
a longer time. The behavior is the same.

Gottfried


#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import sys
import random
from time import sleep

from PyQt5.QtWidgets import (
     QApplication, QWidget, QPushButton, QListView, QVBoxLayout, 
QStatusBar, QMenu,
)
from PyQt5.QtGui import QPixmap, QIcon, QStandardItemModel, QStandardItem
from PyQt5.QtCore import Qt, QSize

ICON_SIZE = QSize(32, 32)

class MainWindow(QWidget):

     def __init__(self, parent=None):
         super().__init__(parent)
         btn = QPushButton("Generate list view items", parent=self)
         btn.setMenu(self.makeMenu())
         pm = QPixmap(ICON_SIZE)
         pm.fill(Qt.green)
         self.infoLine = QStatusBar(self)
         self.icon = QIcon(pm)
         self.view = QListView(parent=self)
         self.view.setModel(QStandardItemModel(self))
         self.view.setIconSize(ICON_SIZE)
         self.view.setViewMode(QListView.IconMode)
         layout = QVBoxLayout()
         layout.addWidget(btn)
         layout.addWidget(self.infoLine)
         layout.addWidget(self.view)
         self.setLayout(layout)
         return

     def makeMenu(self):
         menu = QMenu(self)
         iconsOnly = menu.addAction("Generate icons only")
         iconsOnly.triggered.connect(self.iconsOnly)
         postProcessing = menu.addAction("Generate icons and post 
processing")
         postProcessing.triggered.connect(self.postProcessing)
         return menu

     def iconsOnly(self):
         self.generateItems()
         return

     def postProcessing(self):
         self.generateItems()
         sleep(4)
         return

     def generateItems(self):
         cnt = random.randint(16, 32)
         model = self.view.model()
         model.clear()
         for _ in range(cnt):
             item = QStandardItem()
             item.setIcon(self.icon)
             model.appendRow(item)
         self.infoLine.showMessage("icons: {}".format(cnt))
         QApplication.sendPostedEvents()
         return

def main():
     app = QApplication(sys.argv)
     mainWindow = MainWindow()
     mainWindow.show()
     return app.exec_()

if __name__ == "__main__":
     main()



More information about the PyQt mailing list