Как создать полупрозрачный градиент?
В главный контейнер main_box я добавляю кнопку btn и цветной контейнер box.
В box добавляю два виджета:
back_picture- изображение, которое располагается в верхней части контейнера, полученное с помощью классаBackPicture. Кнопкаbtn, привязанная к методуremakeклассаMyWindow, меняет картинку вback_picture.- Надпись
label, которая указывает на то, чтоback_pictureне является единственным виджетом контейнераbox.
Окно приложения:
Сейчас мне нужно наложить на back_picture градиент с особыми характеристиками:
- Вертикальный
- Крайняя нижняя точка имеет цвет #2A303D и 100% непрозрачности
- Крайняя верхняя точка имеет цвет #2A303D и 50% непрозрачности
- Очень важно! Центр градиента не расположен посередине, т.е. нижняя и верхняя точки неравноправны. Центр градиента смещен в сторону верхней точки, значит, нижняя занимает доминирующее положение. Обозначил точку центра градиента красной стрелкой.
Нарисовал картинку, которая показывает разницу наглядно. Цифрой 1 обозначил градиент со смещенным центром(как мне надо), цифрой 2 обозначил градиент без смещенного центра(как мне НЕ надо):
Градиент с цифрой 1 является моей целью
Покажу цветом, как градиент может быть смещен в сторону какой-либо точки, чтобы было понятнее. В первом случае градиент смещен в сторону нижней точки, во втором случае - в сторону верхней точки:
Работая в illustrator'е я заметил, что png запоминает уровень прозрачности пикселя. Это натолкнуло меня на мысль, что картинку градиента можно просто сохранить и расположить над back_picture.
Картинка градиента:
Если открыть эту картинку в каком-нибудь графическом редакторе, полупрозрачные пиксели будут действительно полупрозрачными. Но, к моему большому разочарованию, в окне приложения градиент отображается сплошным квадратом цвета #2A303D:
Мне нужно как-то создать градиент с точно такими же характеристиками и расположить его ровно над back_picture(важно, чтобы не было видно стыков), сохранив возможность менять изображение в 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('picture3.jpg', 300, self.container)
self.back_picture.move(0, 0)
#self.gradient = BackPicture('gradient.png', 300, self.container)
#self.gradient.move(0, 0) НЕ РАБОТАЕТ
label = QtWidgets.QLabel('Text number 1')
label.setStyleSheet(qss)
box.addStretch(6)
box.addWidget(label, alignment = QtCore.Qt.AlignCenter)
box.addStretch(1)
def remake(self):
if self.index == 1:
self.back_picture.setPicture('picture2.png')
self.index = 2
else:
self.back_picture.setPicture('picture3.jpg')
self.index = 1
qss = '''QLabel {
color: white;
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_())
Ответы (1 шт):
Реализовать примерно такой градиент можно следующим образом(значения в таблице стиля лучше выставлять по своему усмотрению):
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('white.png', 300, self.container)
self.back_picture.move(0, 0)
gradient = QtWidgets.QLabel(self.container)
gradient.setFixedSize(300, 300)
gradient.setStyleSheet(gradient_qss)
gradient.move(0, 0)
label = QtWidgets.QLabel('Text')
label.setStyleSheet(label_qss)
box.addStretch(1)
box.addWidget(label, alignment = QtCore.Qt.AlignCenter)
box.addStretch(1)
def remake(self):
if self.index == 1:
self.back_picture.setPicture('picture1.png')
self.index = 2
else:
self.back_picture.setPicture('picture3.jpg')
self.index = 1
gradient_qss = '''QLabel {
background-color: qlineargradient(spread:pad,
x1:1, y1:1, x2:1, y2:0,
stop:0 rgb(42, 48, 61),
stop:0.05 rgb(42, 48, 61),
stop:0.1 rgb(42, 48, 61),
stop:0.15 rgba(42, 48, 61, 0.999),
stop:0.2 rgba(42, 48, 61, 0.998),
stop:0.25 rgba(42, 48, 61, 0.997),
stop:0.3 rgba(42, 48, 61, 0.996),
stop:0.35 rgba(42, 48, 61, 0.995),
stop:0.4 rgba(42, 48, 61, 0.99),
stop:0.45 rgba(42, 48, 61, 0.985),
stop:0.5 rgba(42, 48, 61, 0.98),
stop:0.55 rgba(42, 48, 61, 0.975),
stop:0.6 rgba(42, 48, 61, 0.97),
stop:0.65 rgba(42, 48, 61, 0.96),
stop:0.7 rgba(42, 48, 61, 0.95),
stop:0.75 rgba(42, 48, 61, 0.93),
stop:0.8 rgba(42, 48, 61, 0.9),
stop:0.85 rgba(42, 48, 61, 0.85),
stop:0.9 rgba(42, 48, 61, 0.8),
stop:0.95 rgba(42, 48, 61, 0.75),
stop:1 rgba(42, 48, 61, 0.7));
}'''
label_qss = '''QLabel {
color: white;
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_())





