1#!/usr/bin/env python 2 3 4############################################################################# 5## 6## Copyright (C) 2013 Riverbank Computing Limited 7## Copyright (C) 2010 Darryl Wallace <wallacdj@gmail.com>. 8## Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). 9## All rights reserved. 10## 11## This file is part of the examples of PyQt. 12## 13## $QT_BEGIN_LICENSE:BSD$ 14## You may use this file under the terms of the BSD license as follows: 15## 16## "Redistribution and use in source and binary forms, with or without 17## modification, are permitted provided that the following conditions are 18## met: 19## * Redistributions of source code must retain the above copyright 20## notice, this list of conditions and the following disclaimer. 21## * Redistributions in binary form must reproduce the above copyright 22## notice, this list of conditions and the following disclaimer in 23## the documentation and/or other materials provided with the 24## distribution. 25## * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor 26## the names of its contributors may be used to endorse or promote 27## products derived from this software without specific prior written 28## permission. 29## 30## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 31## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 32## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 33## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 34## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 35## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 36## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 37## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 38## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 39## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 40## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." 41## $QT_END_LICENSE$ 42## 43############################################################################# 44 45 46from PyQt5.QtCore import (pyqtSignal, QAbstractListModel, QDir, QLibraryInfo, 47 QModelIndex, Qt) 48from PyQt5.QtWidgets import (QApplication, QGridLayout, QLabel, QLineEdit, 49 QListView, QSizePolicy, QTextBrowser, QWidget) 50 51 52class FileListModel(QAbstractListModel): 53 numberPopulated = pyqtSignal(int) 54 55 def __init__(self, parent=None): 56 super(FileListModel, self).__init__(parent) 57 58 self.fileCount = 0 59 self.fileList = [] 60 61 def rowCount(self, parent=QModelIndex()): 62 return self.fileCount 63 64 def data(self, index, role=Qt.DisplayRole): 65 if not index.isValid(): 66 return None 67 68 if index.row() >= len(self.fileList) or index.row() < 0: 69 return None 70 71 if role == Qt.DisplayRole: 72 return self.fileList[index.row()] 73 74 if role == Qt.BackgroundRole: 75 batch = (index.row() // 100) % 2 76 if batch == 0: 77 return QApplication.palette().base() 78 79 return QApplication.palette().alternateBase() 80 81 return None 82 83 def canFetchMore(self, index): 84 return self.fileCount < len(self.fileList) 85 86 def fetchMore(self, index): 87 remainder = len(self.fileList) - self.fileCount 88 itemsToFetch = min(100, remainder) 89 90 self.beginInsertRows(QModelIndex(), self.fileCount, 91 self.fileCount + itemsToFetch) 92 93 self.fileCount += itemsToFetch 94 95 self.endInsertRows() 96 97 self.numberPopulated.emit(itemsToFetch) 98 99 def setDirPath(self, path): 100 dir = QDir(path) 101 102 self.beginResetModel() 103 self.fileList = dir.entryList() 104 self.fileCount = 0 105 self.endResetModel() 106 107 108class Window(QWidget): 109 def __init__(self, parent=None): 110 super(Window, self).__init__(parent) 111 112 model = FileListModel(self) 113 model.setDirPath(QLibraryInfo.location(QLibraryInfo.PrefixPath)) 114 115 label = QLabel("Directory") 116 lineEdit = QLineEdit() 117 label.setBuddy(lineEdit) 118 119 view = QListView() 120 view.setModel(model) 121 122 self.logViewer = QTextBrowser() 123 self.logViewer.setSizePolicy(QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred)) 124 125 lineEdit.textChanged.connect(model.setDirPath) 126 lineEdit.textChanged.connect(self.logViewer.clear) 127 model.numberPopulated.connect(self.updateLog) 128 129 layout = QGridLayout() 130 layout.addWidget(label, 0, 0) 131 layout.addWidget(lineEdit, 0, 1) 132 layout.addWidget(view, 1, 0, 1, 2) 133 layout.addWidget(self.logViewer, 2, 0, 1, 2) 134 135 self.setLayout(layout) 136 self.setWindowTitle("Fetch More Example") 137 138 def updateLog(self, number): 139 self.logViewer.append("%d items added." % number) 140 141 142if __name__ == '__main__': 143 144 import sys 145 146 app = QApplication(sys.argv) 147 148 window = Window() 149 window.show() 150 151 sys.exit(app.exec_()) 152