221 lines
		
	
	
		
			8.4 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			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())
 |