Как размыть изображение?

В вертикальный контейнер main_box я помещаю кнопку btn и цветной контейнер box.

В box помещаю back_picture и label1.

Кнопку btn привязал к методу remake, который меняет картинку в back_picture.

Сейчас мне нужно размыть изображение в back_picture, оставив возможность менять картинку.

Мне показалось, что это будет очень просто, поэтому открыл документацию, чтобы найти нужный метод. Как я понял, за размытие отвечает класс QGraphicsBlurEffect. О нем я слышу впервые, поэтому не знаю, где он находится. На сайте документации увидел следующее:

введите сюда описание изображения

https://doc.qt.io/qt-5/qgraphicsblureffect.html

Тогда я подумал, что данный класс находится в классе QtWidgets. Попытка импортировать его привела к ошибке. На этом остановился, так как не знаю, что делать.

Также заметил метод setBlurRadius. Я бы хотел его задействовать, чтобы выставить свое значение(20px)

Пожалуйста, помогите мне размыть изображение в self.back_picture

from PyQt5 import QtCore, QtWidgets, QtGui

class BackPicture(QtWidgets.QLabel):
    def __init__(self, picture, x, *args, **kwargs):
        super(BackPicture, self).__init__(*args, **kwargs)
        self.setFixedSize(x, x)
        self.x = x
        self.setPicture(picture)

    def setPicture(self, picture):
        self.setPixmap(QtGui.QPixmap(picture).scaled(self.x, self.x, QtCore.Qt.KeepAspectRatio))


class MyWindow(QtWidgets.QWidget):
    def __init__(self, parent = None):
        super().__init__(parent)
        self.index = 1

        btn = QtWidgets.QPushButton('Remake', clicked = self.remake)

        self.container = QtWidgets.QWidget()
        self.container.setStyleSheet('background: #2A303D;')
        self.container.setMinimumHeight(300)
        self.container.setFixedWidth(300)

        main_box = QtWidgets.QHBoxLayout(self)
        main_box.addWidget(btn)        
        main_box.addWidget(self.container)

        box = QtWidgets.QVBoxLayout(self.container)
        box.setContentsMargins(0, 0, 0, 0)

        self.back_picture = BackPicture('picture1.png', 300, self.container)
        self.back_picture.move(0, 0)

        label1 = QtWidgets.QLabel('Text number 1')
        label1.setStyleSheet(qss)
        box.addWidget(label1, alignment = QtCore.Qt.AlignCenter)

    def remake(self):
        if self.index == 1:
            self.back_picture.setPicture('picture2.png') 
            self.index = 2
        else:
            self.back_picture.setPicture('picture1.png') 
            self.index = 1


qss = '''QLabel {
             color: red;
             font: bold 16px;
             background: transparent;
         }'''

if __name__ == '__main__':
    import sys
    app = QtWidgets.QApplication(sys.argv)
    window = MyWindow()
    window.setWindowTitle(' ')
    window.show()
    sys.exit(app.exec_())

UPD:

Данный эффект почему-то размывает рамки изображения. Т.е. граница картинки перестает быть четкой:

введите сюда описание изображения

Я бы хотел оставить рамки изображения четкими:

введите сюда описание изображения

Можно ли это сделать?


Ответы (1 шт):

Автор решения: S. Nick

Попробуйте так:

from PyQt5 import QtCore, QtWidgets, QtGui

class BackPicture(QtWidgets.QLabel):
    def __init__(self, picture, x, *args, **kwargs):
        super(BackPicture, self).__init__(*args, **kwargs)
        self.setFixedSize(x, x)
        self.x = x
        self.setPicture(picture)

    def setPicture(self, picture):
        self.setPixmap(QtGui.QPixmap(picture).scaled(self.x, self.x, QtCore.Qt.KeepAspectRatio))


class MyWindow(QtWidgets.QWidget):
    def __init__(self, parent = None):
        super().__init__(parent)
        self.index = 1

        btn = QtWidgets.QPushButton('Remake', clicked = self.remake)

        self.container = QtWidgets.QWidget()
        self.container.setStyleSheet('background: #2A303D;')
        self.container.setMinimumHeight(300)
        self.container.setFixedWidth(300)

        main_box = QtWidgets.QHBoxLayout(self)
        main_box.addWidget(btn)        
        main_box.addWidget(self.container)

        box = QtWidgets.QVBoxLayout(self.container)
        box.setContentsMargins(0, 0, 0, 0)

        self.back_picture = BackPicture('im.png', 300, self.container)
        self.back_picture.move(0, 0)

        blur_effect = QtWidgets.QGraphicsBlurEffect(blurRadius=20)          # +++
        self.back_picture.setGraphicsEffect(blur_effect)                    # +++

        label1 = QtWidgets.QLabel('Text number 1')
        label1.setStyleSheet(qss)
        box.addWidget(label1, alignment = QtCore.Qt.AlignCenter)

    def remake(self):
        if self.index == 1:
            self.back_picture.setPicture('background.png') 
            self.index = 2
        else:
            self.back_picture.setPicture('300_300.png') 
            self.index = 1


qss = '''QLabel {
             color: red;
             font: bold 16px;
             background: transparent;
         }'''

if __name__ == '__main__':
    import sys
    app = QtWidgets.QApplication(sys.argv)
    window = MyWindow()
    window.setWindowTitle(' ')
    window.show()
    sys.exit(app.exec_())

введите сюда описание изображения


Update

Данный эффект почему-то размывает рамки изображения. Т.е. граница картинки перестает быть четкой:

Я не совсем понимаю какого эффекта вы хотите, но попробуйте так:

from PyQt5 import QtCore, QtWidgets, QtGui

class BackPicture(QtWidgets.QLabel):
    def __init__(self, picture, x, *args, **kwargs):
        super(BackPicture, self).__init__(*args, **kwargs)
        self.setFixedSize(x, x)
        self.x = x
        self.setPicture(picture)

    def setPicture(self, picture):
        self.setPixmap(QtGui.QPixmap(picture).scaled(self.x, self.x, QtCore.Qt.KeepAspectRatio))


class MyWindow(QtWidgets.QWidget):
    def __init__(self, parent = None):
        super().__init__(parent)
        self.index = 1

        btn = QtWidgets.QPushButton('Remake', clicked = self.remake)

        self.container = QtWidgets.QWidget()
        self.container.setStyleSheet('background: #2A303D;')
        self.container.setMinimumHeight(300)
        self.container.setFixedWidth(300)

        main_box = QtWidgets.QHBoxLayout(self)
        main_box.addWidget(btn)        
        main_box.addWidget(self.container)

        box = QtWidgets.QVBoxLayout(self.container)
        box.setContentsMargins(0, 0, 0, 0)

        self.back_picture = BackPicture('im.png', 290, self.container)      # 300  -> 290  new !!!
        self.back_picture.move(5, 5)                                        # 5, 5         new !!!   

        blur_effect = QtWidgets.QGraphicsBlurEffect(blurRadius=5)           # 5            new !!!
        self.back_picture.setGraphicsEffect(blur_effect)                    # 

        label1 = QtWidgets.QLabel('Text number 1')
        label1.setStyleSheet(qss)
        box.addWidget(label1, alignment = QtCore.Qt.AlignCenter)

    def remake(self):
        if self.index == 1:
            self.back_picture.setPicture('background.png') 
            self.index = 2
        else:
            self.back_picture.setPicture('300_300.png') 
            self.index = 1


qss = '''
QLabel {
    color: red;
    font: bold 16px;
    background: transparent;
}
'''

if __name__ == '__main__':
    import sys
    app = QtWidgets.QApplication(sys.argv)
    window = MyWindow()
    window.setWindowTitle(' ')
    window.show()
    sys.exit(app.exec_())

введите сюда описание изображения

→ Ссылка