This commit is contained in:
2025-06-07 23:43:57 +08:00
parent 12a583295d
commit 2e29f7a1f7
7 changed files with 3245 additions and 392 deletions

View File

@@ -1,7 +1,7 @@
from PyQt5.QtWidgets import (QWidget, QVBoxLayout, QHBoxLayout, QLabel,
QLineEdit, QPushButton, QFrame, QCheckBox,
QSpacerItem, QSizePolicy)
from PyQt5.QtCore import Qt, pyqtSignal, QPropertyAnimation, QEasingCurve, QPoint, QSize
from PyQt5.QtCore import Qt, pyqtSignal, QPropertyAnimation, QEasingCurve, QPoint, QSize, QTimer, QPointF
from PyQt5.QtGui import QPixmap, QPainter, QLinearGradient, QColor, QIcon, QFont, QBrush
@@ -12,6 +12,15 @@ class LoginPage(QWidget):
super().__init__()
self.init_ui()
self.setup_animations()
self.gradient_angle = 0
self.particle_timer = QTimer(self)
self.particle_timer.timeout.connect(self.update_particles)
self.particle_timer.start(100) # 更新粒子位置的定时器
self.particles = self.create_particles()
# 添加回车键提交支持
self.username_input.returnPressed.connect(self.handle_login)
self.password_input.returnPressed.connect(self.handle_login)
def init_ui(self):
self.setObjectName("loginPage")
@@ -24,9 +33,87 @@ class LoginPage(QWidget):
self.setLayout(main_layout)
# 左侧装饰区 - 添加玻璃态效果
left_frame = QFrame()
left_frame.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
left_frame.setObjectName("leftDecor")
self.left_frame = QWidget() # 改为QWidget以便自定义绘制
self.left_frame.setObjectName("leftDecor")
self.left_frame.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
# 在左侧装饰区添加艺术字体和版本信息
left_layout = QVBoxLayout(self.left_frame)
left_layout.setContentsMargins(40, 40, 40, 40)
left_layout.addStretch()
# 艺术字体标题
title_container = QFrame()
title_container.setObjectName("titleContainer")
title_container.setStyleSheet("background-color: rgba(0, 0, 0, 0.2); border-radius: 15px;")
title_layout = QVBoxLayout(title_container)
title_layout.setContentsMargins(30, 30, 30, 30)
app_title = QLabel("奶酪云工具箱")
app_title.setObjectName("appTitle")
app_title.setAlignment(Qt.AlignCenter)
app_title.setStyleSheet("""
#appTitle {
font-size: 56px;
font-weight: bold;
color: white;
font-family: 'SimHei', 'Microsoft YaHei', sans-serif;
text-shadow: 0 0 10px rgba(255, 255, 255, 0.5),
0 0 20px rgba(99, 102, 241, 0.8),
0 0 30px rgba(99, 102, 241, 0.6),
0 0 40px rgba(99, 102, 241, 0.4);
letter-spacing: 5px;
}
""")
subtitle = QLabel("高效 · 安全 · 云端协作")
subtitle.setObjectName("subtitle")
subtitle.setAlignment(Qt.AlignCenter)
subtitle.setStyleSheet("""
#subtitle {
font-size: 18px;
color: rgba(255, 255, 255, 0.85);
letter-spacing: 3px;
margin-top: 10px;
}
""")
title_layout.addWidget(app_title)
title_layout.addWidget(subtitle)
# 版本信息
version_info = QWidget()
version_layout = QVBoxLayout(version_info)
version_layout.setAlignment(Qt.AlignBottom | Qt.AlignCenter)
version_label = QLabel("版本 0.0.1")
version_label.setObjectName("versionLabel")
version_label.setAlignment(Qt.AlignCenter)
version_label.setStyleSheet("""
#versionLabel {
color: rgba(255, 255, 255, 0.7);
font-size: 14px;
}
""")
author_label = QLabel("作者:年糕崽崽")
author_label.setObjectName("authorLabel")
author_label.setAlignment(Qt.AlignCenter)
author_label.setStyleSheet("""
#authorLabel {
color: rgba(255, 255, 255, 0.7);
font-size: 14px;
margin-top: 5px;
}
""")
version_layout.addWidget(version_label)
version_layout.addWidget(author_label)
# 添加到左侧布局
left_layout.addWidget(title_container)
left_layout.addStretch()
left_layout.addWidget(version_info)
# 右侧登录区 - 深色背景
right_frame = QFrame()
@@ -40,7 +127,7 @@ class LoginPage(QWidget):
}
""")
main_layout.addWidget(left_frame, 3)
main_layout.addWidget(self.left_frame, 3)
main_layout.addWidget(right_frame, 1)
# 右侧登录区布局
@@ -363,6 +450,42 @@ class LoginPage(QWidget):
self.password_anim.setDuration(300)
self.password_anim.setEasingCurve(QEasingCurve.OutQuad)
def create_particles(self):
particles = []
for _ in range(30): # 创建30个粒子
size = 2 + 5 * (0.5) # 随机大小
x = 50 + 700 * (0.5) # 随机X位置
y = 50 + 500 * (0.5) # 随机Y位置
speed_x = -1 + 2 * (0.5) # X方向速度
speed_y = -1 + 2 * (0.5) # Y方向速度
color = QColor( # 随机蓝色调
int(100 + 155 * (0.5)),
int(180 + 75 * (0.5)),
int(255 - 50 * (0.5)),
int(50 + 100 * (0.5))
)
particles.append({
'x': x, 'y': y,
'size': size,
'speed_x': speed_x, 'speed_y': speed_y,
'color': color
})
return particles
def update_particles(self):
for p in self.particles:
# 更新粒子位置
p['x'] += p['speed_x']
p['y'] += p['speed_y']
# 边界反弹
if p['x'] <= 0 or p['x'] >= self.width():
p['speed_x'] *= -1
if p['y'] <= 0 or p['y'] >= self.height():
p['speed_y'] *= -1
self.left_frame.update() # 触发重绘
def toggle_password_visibility(self):
if self.password_input.echoMode() == QLineEdit.Password:
self.password_input.setEchoMode(QLineEdit.Normal)
@@ -441,7 +564,6 @@ class LoginPage(QWidget):
self.password_input.parent().setStyleSheet("#inputFrame { border: 1px solid #fc8181; }")
# 2秒后恢复
from PyQt5.QtCore import QTimer
QTimer.singleShot(2000, self.reset_styles)
def reset_styles(self):
@@ -479,4 +601,41 @@ class LoginPage(QWidget):
painter.setBrush(QColor(6, 78, 59, 60))
painter.drawEllipse(QPoint(250, 300), 50, 50)
super().paintEvent(event)
super().paintEvent(event)
# 专门绘制左侧装饰区域的粒子效果
if self.left_frame.isVisible():
# 保存当前绘画状态
painter.save()
# 将绘画区域限制在左侧框架内
painter.translate(self.left_frame.pos())
painter.setClipRect(self.left_frame.rect())
# 绘制动态粒子
for p in self.particles:
painter.setBrush(QBrush(p['color']))
painter.setPen(Qt.NoPen)
painter.drawEllipse(QPointF(p['x'], p['y']), p['size'], p['size'])
# 绘制发光的光斑背景
gradient = QLinearGradient(0, 0, self.width(), self.height())
gradient.setColorAt(0, QColor(99, 102, 241, 20)) # 紫色
gradient.setColorAt(0.5, QColor(79, 70, 229, 40)) # 更亮的紫色
gradient.setColorAt(1, QColor(49, 46, 129, 20)) # 深紫色
painter.setBrush(QBrush(gradient))
painter.drawRect(0, 0, self.left_frame.width(), self.left_frame.height())
painter.restore()
# 使用示例
if __name__ == "__main__":
from PyQt5.QtWidgets import QApplication
import sys
app = QApplication(sys.argv)
login_page = LoginPage()
login_page.login_success.connect(lambda username: print(f"登录成功: {username}"))
login_page.show()
sys.exit(app.exec_())