Files
Projects/toolbox/codes/ui/overlay_page/overlay_ui.py
2025-09-28 18:21:48 +08:00

221 lines
8.4 KiB
Python

import sys
from PySide6.QtWidgets import QWidget, QApplication, QSizePolicy, QVBoxLayout, QLabel, QFrame, QHBoxLayout, QLineEdit, QMessageBox
from PySide6.QtGui import QPixmap, QPainter, QFontDatabase, QFont, QBrush, QColor
from PySide6.QtCore import Qt, QPoint, QDateTime, Signal, QTimer
from zhdate import ZhDate
from codes.common import clibs
from codes.common.signal_bus import signal_bus
class LunarClockLabel(QLabel):
def __init__(self, parent=None):
super().__init__(parent)
self.setMinimumWidth(350)
timer = QTimer(self)
timer.timeout.connect(self.update_time)
timer.start(1000)
self.update_time()
def update_time(self):
dt = QDateTime.currentDateTime()
g = dt.date()
z = ZhDate.today()
week = "一二三四五六日"[g.dayOfWeek() - 1]
text = f"{g.year()}{g.month()}{g.day()}{z.chinese()[5:]} 星期{week} {dt.toString('hh:mm:ss')}"
self.setText(text)
class DoubleClickLabel(QLabel):
doubleClicked = Signal()
def mouseDoubleClickEvent(self, event):
super().mouseDoubleClickEvent(event)
self.doubleClicked.emit()
class WidgetWithBg(QWidget):
def __init__(self, parent=None):
super().__init__(parent)
self.predos()
self.init_ui()
self.setup_slot()
def predos(self):
font_id = QFontDatabase.addApplicationFont(f"{clibs.base_path}/assets/media/font/OldEnglishTextMT/OldEnglishTextMT.ttf")
family = QFontDatabase.applicationFontFamilies(font_id)[0]
self.lb_font = QFont(family, 28, QFont.Weight.Medium)
self.background_pixmap = QPixmap(clibs.bg)
def init_ui(self):
layout_v = QVBoxLayout()
# 最上层的空白区
self.lb_empty_up = QLabel(self)
layout_v.addWidget(self.lb_empty_up)
# 头像区
self.lb_avatar = DoubleClickLabel(self)
self.lb_avatar.setAlignment(Qt.AlignmentFlag.AlignCenter)
avatar = QPixmap(clibs.avatar)
avatar = self.circle_pixmap(avatar, 200)
self.lb_avatar.setPixmap(avatar)
self.lb_avatar.setScaledContents(True)
self.lb_avatar.setFixedSize(144, 144)
layout_v.addWidget(self.lb_avatar, alignment=Qt.AlignmentFlag.AlignCenter)
# 艺术字区
self.lb_name = QLabel(self)
self.lb_name.setAlignment(Qt.AlignmentFlag.AlignCenter)
self.lb_name.setText("Manford Fan · Code Create Life")
self.lb_name.setStyleSheet("color: rgba(255,255,255,255);")
self.lb_name.setFont(self.lb_font)
layout_v.addWidget(self.lb_name)
# 时间区-左横线
layout_h = QHBoxLayout()
self.line_left = QFrame(self)
self.line_left.setFrameShape(QFrame.Shape.HLine)
self.line_left.setFrameShadow(QFrame.Shadow.Plain)
self.line_left.setStyleSheet("""
QFrame {
border: none;
background-color: rgba(255, 255, 255, 40);
}
""")
policy = QSizePolicy(QSizePolicy.Policy.Preferred, QSizePolicy.Policy.Fixed)
self.line_left.setSizePolicy(policy)
self.line_left.setLineWidth(1)
self.line_left.setFixedWidth(100)
# 时间区-右横线
self.line_right = QFrame(self)
self.line_right.setFrameShape(QFrame.Shape.HLine)
self.line_right.setFrameShadow(QFrame.Shadow.Plain)
self.line_right.setStyleSheet("""
QFrame {
border: none;
background-color: rgba(255, 255, 255, 40);
}
""")
policy = QSizePolicy(QSizePolicy.Policy.Preferred, QSizePolicy.Policy.Fixed)
self.line_right.setSizePolicy(policy)
self.line_right.setLineWidth(1)
self.line_right.setFixedWidth(100)
# 时间区-时间
self.lb_time = LunarClockLabel(self)
self.lb_time.setAlignment(Qt.AlignmentFlag.AlignCenter)
self.lb_time.setStyleSheet("color: rgba(255,255,255,255);")
self.lb_time.setFont(QFont("Consolas", 12, QFont.Weight.Bold))
layout_h.addStretch(1)
layout_h.addWidget(self.line_left)
layout_h.addWidget(self.lb_time)
layout_h.addWidget(self.line_right)
layout_h.addStretch(1)
layout_v.addLayout(layout_h)
self.lb_proverb = QLabel(self)
self.lb_proverb.setAlignment(Qt.AlignmentFlag.AlignCenter)
self.lb_proverb.setText(clibs.proverb)
self.lb_proverb.setStyleSheet("color: rgba(255,255,255,255);")
self.lb_proverb.setFont(QFont("Consolas", 14, QFont.Weight.Bold))
layout_v.addWidget(self.lb_proverb)
self.le_password = QLineEdit(self)
self.le_password.setEchoMode(QLineEdit.EchoMode.Password)
self.le_password.setFont(QFont("Consolas", 12, QFont.Weight.Normal))
self.le_password.setMinimumWidth(300)
self.le_password.setFixedHeight(30)
layout_v.addWidget(self.le_password, alignment=Qt.AlignmentFlag.AlignCenter)
self.hide_le_password()
self.lb_empty_down = QLabel(self)
layout_v.addWidget(self.lb_empty_down)
layout_v.setStretch(0, 2) # empty up
layout_v.setStretch(1, 2) # avatar
layout_v.setStretch(2, 1) # name
layout_v.setStretch(3, 2) # time
layout_v.setStretch(4, 1) # proverb
layout_v.setStretch(5, 1) # password
layout_v.setStretch(6, 2) # empty down
self.setLayout(layout_v)
def setup_slot(self):
self.lb_avatar.doubleClicked.connect(self.toggle_auth_show)
self.le_password.returnPressed.connect(self.validate_password)
signal_bus.home_overlay_auth.connect(self.toggle_auth_show)
# self.sc_caL = QShortcut(QKeySequence("Esc"), self)
# self.sc_caL.activated.connect(self.toggle_auth_show)
# self.sc_caS = QShortcut(QKeySequence("Ctrl+Alt+M"), self)
# self.sc_caS.activated.connect(signal_bus.ho_full_screen.emit)
def toggle_auth_show(self):
if self.le_is_visible:
self.hide_le_password()
else:
self.show_le_password()
def show_le_password(self):
self.le_is_visible = True
self.le_password.clear()
self.le_password.setPlaceholderText("Password")
self.le_password.setStyleSheet("border:none; border-radius: 5px;")
self.le_password.setDisabled(False)
self.le_password.setFocus()
def hide_le_password(self):
self.le_is_visible = False
self.le_password.clear()
self.le_password.setDisabled(True)
self.le_password.setPlaceholderText("")
self.le_password.setStyleSheet("background:transparent; color:rgba(0,0,0,0); border:none; ")
def validate_password(self):
password = self.le_password.text()
if password == clibs.password:
self.hide_le_password()
signal_bus.home_overlay_close.emit()
self.deleteLater()
return True
elif password == "":
self.hide_le_password()
return False
else:
QMessageBox.critical(self, "错误", "密码不正确,请确认后重新输入!")
self.show_le_password()
return False
@staticmethod
def circle_pixmap(src: QPixmap, diameter: int) -> QPixmap:
dst = QPixmap(diameter, diameter)
dst.fill(Qt.GlobalColor.transparent)
painter = QPainter(dst)
painter.setRenderHint(QPainter.RenderHint.Antialiasing)
painter.setPen(Qt.PenStyle.NoPen)
painter.setBrush(QBrush(src))
painter.drawEllipse(dst.rect())
painter.end()
return dst
def paintEvent(self, event):
if not self.background_pixmap.isNull():
painter = QPainter(self)
painter.setRenderHint(QPainter.RenderHint.Antialiasing)
scaled_pixmap = self.background_pixmap.scaled(self.size(), Qt.AspectRatioMode.IgnoreAspectRatio, Qt.TransformationMode.SmoothTransformation)
x = (self.width() - scaled_pixmap.width()) // 2
y = (self.height() - scaled_pixmap.height()) // 2
painter.drawPixmap(QPoint(x, y), scaled_pixmap)
painter.setBrush(QColor(0, 0, 0, 144)) # 144 ≈ 50% 暗度,越大越暗
painter.setPen(Qt.PenStyle.NoPen)
painter.drawRect(self.rect())
painter.end()
super().paintEvent(event)
if __name__ == '__main__':
app = QApplication(sys.argv)
your_widget = WidgetWithBg()
your_widget.resize(1000, 450)
your_widget.show()
sys.exit(app.exec())