Можно ли как-то кастомизировать QLineEdit не только с помощью css и без модификации метода paintEvent?
Я хочу кастомизировать QLineEdit:
- сделать закругленные углы;
- задать цвет заднего фона,
с чем справляется CSS.
Но насколько мне известно, в CSS нет анимации (речь о библиотеке PyQt5).
Возможно ли реализовать плавную смену цвета заднего фона на более светлый при наведении курсора мыши c помощью CSS?
Или же реализовать каким-то иным способом?
Ответы (2 шт):
Автор решения: S. Nick
→ Ссылка
Возможное решение выглядит примерно так:
import sys
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.Qt import *
class LineEdit(QLineEdit):
def __init__(self, text):
super().__init__(text)
self.setPlaceholderText('Please enter your username') # +
def _set_color(self, col):
self.setStyleSheet(f"""
QLineEdit {{ background-color: {col.name()}; }} """)
# !!! ^^ ^..........^ ^^ # <---- !!!
background = pyqtProperty(QColor, fset=_set_color) # <---- !!!
class Example(QWidget):
def __init__(self):
super().__init__()
self.button = QPushButton("Button", self)
self.button.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
self.button.clicked.connect(self.anim_start)
hbox = QHBoxLayout(self)
hbox.addWidget(self.button)
hbox.addSpacing(40)
self.lineEdit = LineEdit("LineEdit")
hbox.addWidget(self.lineEdit)
self.anim = QPropertyAnimation(self.lineEdit, b"background") # <---- !!!
self.anim.setDuration(1000)
self.anim.setStartValue(QColor('#3422A1')) #344FA1
self.anim.setEndValue(QColor('#3D84B8'))
self.lineEdit.installEventFilter(self)
def eventFilter(self, obj, event):
if self.lineEdit is obj:
if event.type() == event.Enter:
self.anim.start()
elif event.type() == event.Leave:
self.lineEdit.setStyleSheet('background-color: #344FA1;')
return super().eventFilter(obj, event)
def anim_start(self):
self.anim.start()
qss = """
QLineEdit {
font: 30pt "MS Shell Dlg 2";
background-color: #344FA1;
border-radius: 15px;
border: 2px solid rgb(55, 55, 55);
padding-left: 10px;
padding-right: 10px;
}
"""
if __name__ == "__main__":
app = QApplication(sys.argv)
# app.setStyle('Fusion')
app.setStyleSheet(qss)
w = Example()
w.resize(500, 200)
w.show()
sys.exit(app.exec_())
Автор решения: Lo_okiMan
→ Ссылка
Вот как сделал это я:
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QLineEdit
from PyQt5.QtCore import (QPropertyAnimation, pyqtProperty, QEasingCurve,
QParallelAnimationGroup, QSequentialAnimationGroup, pyqtSlot, pyqtSignal)
from PyQt5.QtGui import QColor
class LineEdit(QLineEdit):
""" """
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.setAcceptDrops(True)
self.createStandardContextMenu()
self._leave_background_color = QColor('#545454')
self._enter_background_color = QColor('#C7C7C7')
self._leave_color = QColor('white')
self._enter_color = QColor('black')
self._background_color = self._leave_background_color
self._color = self._leave_color
self.style_mask = ""\
"border: 1px solid %s;"\
"padding-left: 5px;"\
"border-radius: 4px;"\
"color: %s;"\
"background-color: %s;"\
self.setStyleSheet(self.style_mask % (self._background_color.name(),
self._color.name(), self._background_color.name()))
self.background_animation = QPropertyAnimation(self, b"backgroundColor", self)
self.background_animation.setEasingCurve(QEasingCurve.Linear)
self.background_animation.setDuration(450)
self.color_animation = QPropertyAnimation(self, b"color", self)
self.color_animation.setEasingCurve(QEasingCurve.Linear)
self.color_animation.setDuration(450)
self.animations_group = QParallelAnimationGroup()
self.animations_group.addAnimation(self.background_animation)
self.animations_group.addAnimation(self.color_animation)
def update(self):
""" """
self.setStyleSheet(self.style_mask % (self._background_color.name(),
self._color.name(), self._background_color.name()))
super().update()
@pyqtProperty(QColor)
def backgroundColor(self):
return self._background_color
@backgroundColor.setter
def backgroundColor(self, color: QColor):
self._background_color = color
self.update()
@pyqtProperty(QColor)
def enterBackgroundColor(self):
return self._enter_background_color
@enterBackgroundColor.setter
def enterBackgroundColor(self, color: QColor):
self._enter_background_color = color
self.update()
@pyqtProperty(QColor)
def leaveBackgroundColor(self):
return self._leave_background_color
@leaveBackgroundColor.setter
def leaveBackgroundColor(self, color: QColor):
self._leave_background_color = color
self.update()
@pyqtProperty(QColor)
def color(self):
return self._color
@color.setter
def color(self, color: QColor):
self._color = color
self.update()
@pyqtProperty(QColor)
def enterColor(self):
return self._enter_color
@enterColor.setter
def enterColor(self, color: QColor):
self._enter_color = color
self.update()
@pyqtProperty(QColor)
def leaveColor(self):
return self._leave_color
@leaveColor.setter
def leaveColor(self, color: QColor):
self._leave_color = color
self.update()
def setEnterBackgroundColor(self, color: QColor):
""" """
self._enter_background_color = color
def setLeaveBackgroundColor(self, color: QColor):
""" """
self._leave_background_color = color
def setEnterColor(self, color: QColor):
""" """
self._enter_color = color
def setLeaveColor(self, color: QColor):
""" """
self._leave_color = color
def enterEvent(self, event):
""" """
self.animations_group.stop()
self.background_animation.setStartValue(self._background_color)
self.background_animation.setEndValue(self._enter_background_color)
self.color_animation.setStartValue(self._color)
self.color_animation.setEndValue(self._enter_color)
self.animations_group.start()
def leaveEvent(self, event):
""" """
self.animations_group.stop()
self.background_animation.setStartValue(self._background_color)
self.background_animation.setEndValue(self._leave_background_color)
self.color_animation.setStartValue(self._color)
self.color_animation.setEndValue(self._leave_color)
self.animations_group.start()
class Example(QWidget):
def __init__(self):
super().__init__()
self.lineEdit = LineEdit(self)
self.lineEdit.move(20, 20)
if __name__ == "__main__":
app = QApplication(sys.argv)
ui = Example()
ui.resize(150, 50)
ui.show()
sys.exit(app.exec_())
