近期在学习Qt的使用,为了便于学习吸收,便用模仿QQ界面为练手巩固项目。复刻QQ用户与密码输入框下划线渐变动效时,使用了两种方法来实现,记录下。
效果对比
界面的下划线效果全部使用重写paitEvent,Enter/Leave,focusIn/focusOut方法实现,未使用qss。
代码复现
工具
Qt Designer,Pycharm
PySide2 --5.15
注意点
重写方法时,注意要在方法中继承父类的方法,以免出现光标丢失等问题。
super(ClassNmae, self).focusInEvent(event)
代码
方法一:
使用QPropertyAnimation,自定义属性动效实现;
方法二:
使用QTimeLine,时间线实现。
两种方法中,个人建议使用QTimeLine,如果有更好的建议或实现方法的,欢迎评论区交流学习,感谢!
QPropertyAnimation新建一个percent属性(属性名称自定)
self._percent = 0
self.animation = QPropertyAnimation(self, b'percent')
self.animation.setTargetObject(self)
self.animation.setDuration(300)
self.animation.setStartValue(0)
self.animation.setEndValue(1)
# 自定义一个percent属性
@Property(float)
def percent(self):
return self._percent
@percent.setter
def percent(self, percent):
self._percent = percent
self.update()
重写paitEvent
self.flag = False
def paitEvent(self, event):
super().paitEvent(event)
p = QPaiter(self)
p.setPen(QPen(QColor(18, 183, 245), 2)
if self.flag: # 加一个条件判断,以实现焦点out时,直线消失
p.drawLine(QPoint(x1, y1), QPoint(x2*self._percent, y2))
最后再将触发条件写入
def focusInEvent(self, event):
super().focusInEvent(event)
self.flag = True
self.animation.start()
self.update()
def focusOutEvent(self, event):
super().focusOutEvent(event)
self.flag = False
self._percent = 0
QTimeLine
# 创建一个时间线
self.timeline = QTimeLine(300, self)
self.timeline.valueChanged.connect(self.draw_line)
def draw_line(self, val):
self.end_point = self.line_f.pointAt(val)
self.ani_line = QLineF(QPointF(x1, y1), self.end_point)
self.update()
重写paitEvent
self.flag = False
def paitEvent(self, event):
super().paitEvent(event)
p = QPaiter(self)
p.setPen(QPen(QColor(18, 183, 245), 2)
self.line_f = QLineF(QPointF(x1, y1), QPointF(x2, y2)
if self.ani_line and self.flag: p.drawLine(self.anima_line)
最后再将触发条件写入
def focusInEvent(self, event):
super().focusInEvent(event)
self.flag = True
self.timeline.setDirection(QTimeLine.Forward)
self.timeline.start()
def focusOutEvent(self, event):
super().focusOutEvent(event)
self.flag = False
# 也可以在失去焦点事件中加一个线条消失的动画(注意self.flag的状态)
# self.timeline.setDirection(QTimeLine.BackWard)
# self.timeline.start()