QListWidget выбор замедляет приложение? - PullRequest
0 голосов
/ 14 февраля 2020

Я пишу приложение, в котором QListWidget используется для отображения превью gifs с помощью QMovie. Все работает нормально, но есть замедление, пока я нажимаю кнопку sh и снова заполняю ListWidget. Я думал, что вызов QListWidget.clear() удалит объекты из памяти, но я не уверен, что это действительно происходит. Может быть, есть более эффективный способ сделать это, но я не мог найти что-нибудь еще в другом месте. Вот некоторый код (я не могу дать файлы gif, но любой gif должен работать):

from PySide2 import QtCore, QtGui, QtWidgets
from PySide2.QtCore import *
from PySide2.QtGui import *
from PySide2.QtWidgets import *
import os, glob

class gifPreviewWidget(QWidget):
    def __init__(self, gifPath, parent=None):
        super(gifPreviewWidget, self).__init__(parent)
        label = QLabel()
        label.setScaledContents(True)
        movie = QMovie(gifPath)
        movie.setSpeed(100)
        label.setMovie(movie)
        movie.start()
        nameLabel = QLabel(os.path.split(gifPath)[1].split('.')[0])
        layout = QVBoxLayout()
        layout.addWidget(label)
        print(gifPath)
        self.setLayout(layout)

class gifDelegate(QItemDelegate):
    def __init__(self, parent=None, *args):
        QItemDelegate.__init__(self, parent, *args)

    def paint(self, painter, option, index):
        painter.save()

        # set background color
        painter.setPen(QPen(Qt.NoPen))

        # set selection color
        if option.state & QStyle.State_Selected:
            painter.setBrush(QBrush(Qt.blue))
        else:
            painter.setBrush(QBrush(Qt.NoBrush))
        painter.drawRect(option.rect)
        painter.restore()

class MainUiClass(QtWidgets.QWidget):
    def __init__(self, parent=None):
        super(MainUiClass, self).__init__(parent)
        self.layout=QVBoxLayout()
        self.gifDelegate = gifDelegate()
        self.previewListWidget = QListWidget()
        self.previewListWidget.setViewMode(QtWidgets.QListView.IconMode)
        self.previewListWidget.setResizeMode(QListWidget.Adjust)
        self.previewListWidget.setSelectionMode(QAbstractItemView.ExtendedSelection)
        self.previewListWidget.setMovement(QListView.Static)
        self.previewListWidget.setSpacing(1)
        self.previewListWidget.setItemDelegate(self.gifDelegate)

        self.pushButton = QPushButton('change gif dir')
        self.layout.addWidget(self.previewListWidget)
        self.layout.addWidget(self.pushButton)
        self.setLayout(self.layout)
        self.pushButton.clicked.connect(self.onCategoryClick)

    def onCategoryClick(self):
        filePath = '/PATH/TO/LOTS/OF/GIFS'
        print(filePath+'/*.gif')
        glob.glob(filePath+'/*.gif')
        if glob.glob(filePath+'/*.gif') != []:
            print('ok')
            gifList = glob.glob(filePath+'/*.gif')
            self.previewListWidget.clear()

            for gif in gifList:
                item=QListWidgetItem(self.previewListWidget)
                itemWidget = gifPreviewWidget(gif)
                item.setSizeHint(itemWidget.sizeHint())
                self.previewListWidget.addItem(item)
                self.previewListWidget.setItemWidget(item,itemWidget)

if __name__ == '__main__':
    w = MainUiClass()
    w.show()
    sys.exit(app.exec_())

При частом нажатии кнопки приложение начинает сильно замедляться.

1 Ответ

0 голосов
/ 14 февраля 2020

Обычно вам не нужно явно останавливать QMovie, когда вы собираетесь его удалить в любом случае. Но здесь он не удаляется , потому что он не останавливается (он все еще играет).

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

Решение: остановите mov ie, когда элемент будет удален. Добавить

class gifPreviewWidget(QWidget):
    def __del__(self):
        self.movie.stop()
...