Я решил написать интереса ради файл-менеджер на PyQt. Для отображения содержимого каталогов выбрал QListWidget. Все бы хорошо, да не могу написать эффективный алгоритм ассоциации определенному типу файлов определенной иконки.
Процесс я представляю так:
1. Получаю список файлов в директории средствами модуля os
2. Создаю цикл for и в нем:
a) Для каждого элемента списка определяю его MIME-тип
b) По MIME-типу определяю иконку и назначаю ее соответствующему файлу.
Но все это ОЧЕНЬ медленно работает при большом количестве файлов в каком-либо каталоге. Например, для отображения содержимого /usr/bin (около 2,5 тысяч файлов) уходит 16 секунд, а если без определения типа файла, то меньше секунды. Причем тормозит не отрисовка элементов компонента QListWidget, а именно определение MIME-типа.
Подскажите пожалуйста, где можно упростить, оптимизировать мой корявый код или подскажите, как можно иначе реализовать ассоциацию иконки файлу?
Вот листинги соответствующих функций:
list_print: функция, отображающая содержимое каталога:
def list_print(self, path_): # функция, отображающая содержимое каталога
items_ = pyfileman.sorted_list(path_) # список, содержащий упорядоченный перечень имен файлов в директории, указанной в переменной path_
for j in items_: # создаю цикл для перебора списка
mime_ = mime.get_mime(j) #определяю тип файла
mime_icon_path = mime.get_mime_icon(mime_, os.getcwd(), j) # указываю путь к иконке, соответствующей этому типу
icon = QtGui.QIcon(mime_icon_path) # создаю иконку
i = QtGui.QListWidgetItem(icon, j, self.listwidget) # создаю элемент списка с иконкой и именем файла
self.listwidget.addItem(i) # добавляю его в QListWidget.
import mimetypes
def get_mime(file): #Функция, определяющая MIME-тип файла, путь к которому указан в переменной file
mimetypes.init()
ext = u'.%s' % file.split('.')[-1]
try:
mime = mimetypes.types_map[ext]
except:
mime = False
return mime
def get_mime_icon(mime, path): # функция, назначающая иконку файлу. mime - MIME-тип, path - путь к файлу
mimetype = str(mime)
if mimetype == 'application/pdf': #если тип PDF
return '/.media/mime_icons/pdf.png' # то возвращаем путь к соответствующей иконке
elif mimetype.startswith('image'):
return '/.media/mime_icons/image.png'
elif mimetype.startswith('audio'):
return '/.media/mime_icons/audio-x-generic.png'
elif mimetype.find('application/x-font-ttf') != -1:
return '/.media/mime_icons/font_truetype.png'
.......
.......
else:
return '/.media/mime_icons/unknown.png'