QLabel не перерисовывает растровое изображение - PullRequest
0 голосов
/ 25 июня 2018

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

Если я удаляю return True из последней строки метода eventFilter, он работает. Это также вызовет множество жалоб на то, что eventFilter хочет получить логическое возвращение.

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

Спасибо.

Пример последовательности изображений, используемых в __name__ == '__main__': https://drive.google.com/open?id=1_kMf0bVZ5jMKdCQXzmOk_34nwwHOyXqz

# -*- coding: utf-8 -*-
import sys
from os.path import dirname, realpath, join
from PySide.QtGui import (QApplication, QVBoxLayout, QLabel, QPixmap,
    QWidget)
from PySide import QtCore

class PlayTurntable(QWidget):
    def __init__(self, images, mouse_threshold=50, parent=None):
        super(PlayTurntable, self).__init__(parent)

        self.label = QLabel()
        self.label.setFixedWidth(300)
        self.label.setFixedHeight(200)
        layout = QVBoxLayout()
        layout.addWidget(self.label)
        self.setLayout(layout)

        # init variables
        self.tracking = False
        self.mouse_start = 0
        self.mouse_threshold = mouse_threshold
        self.images = images
        self.image_index = 0
        self.pic = QPixmap(self.images[self.image_index])
        self.label.setPixmap(self.pic.scaled(300, 200, QtCore.Qt.KeepAspectRatio))
        self.installEventFilter(self)

    def eventFilter(self, obj, event):
        if event.type() == event.MouseButtonPress:
            if event.button() == QtCore.Qt.LeftButton:
                self.mouse_start = event.x()
                self.tracking = True
                event.accept()
        if event.type() == event.MouseButtonRelease:
            if event.button() == QtCore.Qt.LeftButton:
                self.tracking = False
                event.accept()
        if event.type() == event.MouseMove:
            if self.tracking:
                mouse_x = event.x()
                distance = self.mouse_start - mouse_x
                if abs(distance) >= self.mouse_threshold:
                    self.mouse_start = mouse_x
                    if distance > 0:
                        self.frame_step(1)
                    else:
                        self.frame_step(-1)
                event.accept()
        return True

    def frame_step(self, amount):
        self.image_index += amount
        if self.image_index >= len(self.images):
            self.image_index = 0
        elif self.image_index < 0:
            self.image_index = len(self.images) - 1
        print 'switching to: %s' % self.images[self.image_index]

        self.pic.load(self.images[self.image_index])
        self.label.setPixmap(
            self.pic.scaled(300, 200, QtCore.Qt.KeepAspectRatio))
        self.label.repaint()


if __name__=='__main__':
    current_path = dirname(realpath(__file__))
    images = ['turn1.jpg', 'turn2.jpg', 'turn3.jpg', 'turn4.jpg']
    for index, value in enumerate(images):
        images[index] = join(current_path, value)

    app = QApplication(sys.argv)
    PT = PlayTurntable(images)
    PT.show()
    sys.exit(app.exec_())

1 Ответ

0 голосов
/ 25 июня 2018

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

# -*- coding: utf-8 -*-
import sys
from os.path import dirname, realpath, join
from PySide.QtGui import (QApplication, QVBoxLayout, QLabel, QPixmap,
    QWidget)
from PySide.QtCore import Qt

class PlayTurntable(QWidget):
    def __init__(self, images, mouse_threshold=50, parent=None):
        super(PlayTurntable, self).__init__(parent)

        self.label = QLabel()
        self.label.setFixedSize(300, 200)

        layout = QVBoxLayout(self)
        layout.addWidget(self.label)

        # init variables
        self.tracking = False
        self.mouse_start = 0
        self.mouse_threshold = mouse_threshold
        self.images = images
        self.image_index = 0
        self.pic = QPixmap(self.images[self.image_index])
        self.label.setPixmap(self.pic.scaled(300, 200, Qt.KeepAspectRatio))
        self.installEventFilter(self)

    def eventFilter(self, obj, event):
        if event.type() == event.MouseButtonPress:
            if event.button() == Qt.LeftButton:
                self.mouse_start = event.x()
                self.tracking = True
        elif event.type() == event.MouseButtonRelease:
            if event.button() == Qt.LeftButton:
                self.tracking = False
        elif event.type() == event.MouseMove:
            if self.tracking:
                mouse_x = event.x()
                distance = self.mouse_start - mouse_x
                if abs(distance) >= self.mouse_threshold:
                    self.mouse_start = mouse_x
                    if distance > 0:
                        self.frame_step(1)
                    else:
                        self.frame_step(-1)
        return QWidget.eventFilter(self, obj, event)

    def frame_step(self, amount):
        self.image_index += amount
        self.image_indes = (self.image_index + amount) % len(self.images)
        print('switching to: %s' % self.images[self.image_index])

        self.pic.load(self.images[self.image_index])
        self.label.setPixmap(self.pic.scaled(300, 200, Qt.KeepAspectRatio))

if __name__=='__main__':
    current_path = dirname(realpath(__file__))
    images = ['turn1.jpg', 'turn2.jpg', 'turn3.jpg', 'turn4.jpg']
    for index, value in enumerate(images):
        images[index] = join(current_path, value)

    app = QApplication(sys.argv)
    PT = PlayTurntable(images)
    PT.show()
    sys.exit(app.exec_())
...