2015-07-06 2 views
1

У меня есть модель, как это:Python/PySide предел скорость обновления Model/View

class GeneralAssetIconModel(QtCore.QAbstractListModel): 
    def __init__(self, parent=None): 
     super(GeneralAssetIconModel, self).__init__(parent) 
     self._data = [] 

    def rowCount(self, parent): 
     return len(self._data) 

    def data(self, index, role): 
     if role == QtCore.Qt.DecorationRole: 
      taskModel = self._data[index.row()] 
      ext = taskModel.getData().obj['type']['ext'] 

      pix = QtGui.QPixmap(160, 160) 
      pix.load('Assets/thumbnail-default.jpg') 

      if ext == '.ma': 
       pass 
      if ext == '.psd': 
       pix = PhotoshopHelper.getLatestThumbnail(taskModel) 
      if ext == '.ai': 
       pix = IllustratorHelper.getLatestThumbnail(taskModel) 
      if ext == '.mra': 
       pix = MariHelper.getLatestThumbnail(taskModel) 
      if ext == '.indd': 
       pix = IndesignHelper.getLatestThumbnail(taskModel) 

Проблема у меня в том, что функция «getLatestThumbnail» всегда считывает данные миниатюрного изображения из файла сервера и пытается отобразить его в представлении, и эта операция выполняется довольно медленно. И когда у меня есть 30 или более предметов, отображаемых в списке, все становится очень медленным и медленным.

Есть ли способ ограничить количество раз, когда данные запроса запрашивают данные модели?

+2

Я предлагаю вам вместо этого изменить классы-помощники, чтобы они локально кэшировали эскизы. –

+0

Я думал то же самое, но ограничение обновления было бы легким выходом. Возможно, просто обновите его один раз при начальной загрузке предметов. Но я не знаю, как контролировать поведение. @three_pineapples – d3cr1pt0r

+0

Очень часто меняются эскизы? Если нет, вы можете хранить их локально и иметь способ их обновления по мере необходимости. Чтобы избежать какого-либо отставания, вы можете поместить этот метод обновления в отдельный поток. – Mel

ответ

0

Я успешно оптимизировал загрузку миниатюр, кэшируя все данные в самой модели. Возможно, это не лучший способ сделать это, но он работает очень быстро. Вот как выглядит модель сейчас.

class GeneralAssetIconModel(QtCore.QAbstractListModel): 
    def __init__(self, parent=None): 
     super(GeneralAssetIconModel, self).__init__(parent) 
     self._data = [] 
     self.cache = {} 

    def rowCount(self, parent): 
     return len(self._data) 

    def data(self, index, role): 
     index_row = index.row() 
     if index_row in self.cache and 'DecorationRole' in self.cache[index_row] and 'DisplayRole' in self.cache[index_row]: 
      if role == QtCore.Qt.DecorationRole: 
       return self.cache[index_row]['DecorationRole'] 
      if role == QtCore.Qt.DisplayRole: 
       return self.cache[index_row]['DisplayRole'] 
     else: 
      if index_row not in self.cache: 
       self.cache[index_row] = {} 
      if role == QtCore.Qt.DecorationRole: 
       taskModel = self._data[index_row] 
       ext = taskModel.getData().obj['type']['ext'] 

       pix = QtGui.QPixmap(160, 160) 
       pix.load('Assets/thumbnail-default.jpg') 

       if ext == '.psd': 
        pix = PhotoshopHelper.getLatestThumbnail(taskModel) 
       if ext == '.ai': 
        pix = IllustratorHelper.getLatestThumbnail(taskModel) 
       if ext == '.mra': 
        pix = MariHelper.getLatestThumbnail(taskModel) 
       if ext == '.indd': 
        pix = IndesignHelper.getLatestThumbnail(taskModel) 
       if ext == '.ma': 
        pass 

       self.cache[index_row]['DecorationRole'] = QtGui.QIcon(pix) 
       return QtGui.QIcon(pix) 
      if role == QtCore.Qt.DisplayRole: 
       self.cache[index_row]['DisplayRole'] = self._data[index_row].getName() 
       return self._data[index_row].getName()