编程技术文章分享与教程

网站首页 > 技术文章 正文

PyQt5界面美化(一)(pyqt 界面美化)

hmc789 2024-11-15 19:34:15 技术文章 2 ℃

借助Fitten Code插件进行PyQt5界面美化!

例如从网上找到一张漂亮的UI示意图:

接下来借助Fitten Code插件一步一步实现如上图中的界面。首先我们先进行提问,它会给出一个大致框架的代码,如下图:


运行代码后效果如下:



界面只有一个大致的布局,距离原始图片中的效果还差的有点儿远。我们可以一步一步进行提问并优化。

最终美化后的代码如下:

import sys
import qtawesome
from PyQt5.QtWidgets import QApplication, QWidget, QButtonGroup, QVBoxLayout, QHBoxLayout, QLabel, QPushButton, QTableWidget, QTableWidgetItem, QCheckBox, QStyledItemDelegate, QStyle, QFrame
from PyQt5.QtGui import QColor, QPainter, QPen, QIcon, QPixmap
from PyQt5.QtCore import Qt, QDate, QSize, QByteArray, QBuffer, QEvent


class CustomDelegate(QStyledItemDelegate):
    def paint(self, painter, option, index):
        # 调用默认的绘制方法
        super().paint(painter, option, index)
        # 检查是否为第一列且行被选中
        if index.column() == 0 and (option.state & QStyle.State_Selected):
            # 绘制紫色小竖条
            painter.save()
            painter.setPen(Qt.NoPen)
            painter.setBrush(QColor("#8a2be2"))
            rect = option.rect.adjusted(0, 0, -option.rect.width() + 6, 0)  # 调整矩形以绘制竖条
            painter.drawRect(rect)
            painter.restore()

class ProgressRing(QWidget):
    def __init__(self, progress=0, color=QColor(106, 121, 249)):
        super().__init__()
        self.progress = progress  # 进度百分比
        self.color = color # 进度条颜色
        


    def paintEvent(self, event):
        painter = QPainter(self)
        painter.setRenderHint(QPainter.Antialiasing)
        
        # 设置圆环的参数
        rect = self.rect().adjusted(10, 10, -10, -10)  # 圆环位置和大小
        start_angle = 90 * 16  # 起始角度
        span_angle = - int(self.progress * 360 / 100) * 16  # 进度部分的大小(以16分之一度为单位)
        
        # 绘制背景圆环
        pen = QPen(QColor(220, 220, 220), 5)  # 设置边框颜色和宽度
        painter.setPen(pen)
        painter.setBrush(Qt.NoBrush)  # 背景不填充
        painter.drawArc(rect, start_angle, 360 * 16)  # 绘制背景圆环
        
        # 绘制进度圆环
        pen = QPen(self.color, 5)  # 设置边框颜色和宽度
        painter.setPen(pen)  # 更新画笔
        painter.setBrush(Qt.NoBrush)  # 进度不填充
        painter.drawArc(rect, start_angle, span_angle)  # 绘制进度圆环
        
        # 绘制进度文本
        painter.setPen(QColor(0, 0, 0))  # 设定文字颜色
        painter.drawText(self.rect(), Qt.AlignCenter, f"{self.progress}%")

class MainWindow(QWidget):
    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):
        self.setWindowTitle('任务管理')
        self.setGeometry(100, 100, 1550, 700)
        
        # 设置样式
        self.setStyleSheet("""
            QWidget {
                background-color: #f4f4f4;  /* 内容区域背景 */
                font-family: 'Microsoft YaHei UI';
            }
            QLabel {
                color: #030303;  /* 字体颜色 */
                font-size: 16px;
                font-weight: bold;
            }
            QPushButton {
                background-color: #6a79f9; /* 按钮背景颜色 */
                color: white; 
                border: none; 
                padding: 12px; 
                border-radius: 5px; 
                font-size: 16px;
                font-weight: bold;
            }
            QPushButton:hover {
                background-color: #5a69e6; /* 悬停效果 */
            }
            QTableWidget {
                background-color: #ffffff;  /* 表格背景 */
                border: none;  /* 隐藏边框 */
            }
            QTableWidget::item {
                padding: 10px;
                background-color: #ffffff;
                border: none;  /* 隐藏边框 */
            }
            QTableWidget::item:selected {
                background-color: #e5e5ff; /* 选中行的背景 */
                color: #333; /* 选中行字体颜色 */
                font-weight: bold; /* 选中行字体加粗 */
                /* border-left: 5px solid #8a2be2;  左侧紫色竖条 */
            }
            QHeaderView::section {
                background-color: #f0f0f0;  /* 轻浅的表头背景颜色 */
                color: #333;  /* 表头字体颜色 */
                padding: 10px;
                font-weight: bold;  /* 表头字体加粗 */
                border: none;  /* 隐藏表头边框 */
            }
            QCheckBox {
                background-color: transparent;  /* 透明背景 */
                border: none;  /* 隐藏边框 */
                padding: 0px;  /* 复选框缩进 */
            }
        """)
        # 主布局
        mainLayout = QHBoxLayout(self)
        
        # 左侧边栏
        sidebar = QVBoxLayout()
        sidebarWidget = QWidget()
        sidebarWidget.setLayout(sidebar)
        sidebarWidget.setFixedWidth(200)  # 设置左侧边栏宽度
        
        # 设置左侧边栏背景颜色
        sidebarWidget.setStyleSheet("""
            QWidget {
                background: qlineargradient(x1: 0, y1: 1, x2: 1, y2: 0.8, stop: 0 #434569, stop: 1 #5A3C54); /* 左侧边栏背景颜色 */
            }
        """)  
        logo_button = QPushButton("", self)
        logo_button.setFixedSize(160, 160)  # 设置大小
        logo_button.setStyleSheet("border: 2px solid #FFFFFF; border-radius: 80px; padding: 10px;")
        # 设置logo图标
        logo_button.setIcon(QIcon("D:\\Gitee\\2-Python\\2.2-ToutiaoFavorites\\Resources\\小宇宙logo.ico"))
        logo_button.setIconSize(QSize(120, 120))  # 设置图标大小
        sidebar.addWidget(logo_button)
        profileLabel = QLabel("小宇宙", self)
        profileLabel.setAlignment(Qt.AlignCenter)  # 居中对齐
        profileLabel.setStyleSheet("font-size: 24px; font-weight: bold; color: #ffffff;")
        sidebar.addWidget(profileLabel)
        
        # 添加按钮组并设置互斥性
        menu_buttonGroup = QButtonGroup(self)
        menu_buttonGroup.setExclusive(True)
        
        # 添加侧边栏的按钮和标签
        self.plan_layout = QVBoxLayout()
        self.plan_layout.setSpacing(0)
        self.plan_layout.setContentsMargins(0, 0, 0, 0)
        self.plan_button = QPushButton("", self)
        self.plan_button.setIcon(qtawesome.icon('fa.check-square', color="white"))
        self.plan_button.setIconSize(QSize(40, 40))
        self.plan_button.setCheckable(True)
        self.plan_button.setChecked(False)
        self.plan_button.installEventFilter(self)  # 为每个按钮安装事件过滤器
        self.plan_button.toggled.connect(self.onPlanBtnToggled)  # 绑定事件处理函数
        menu_buttonGroup.addButton(self.plan_button)
        self.plan_label = QLabel("计划", self)
        self.plan_label.setAlignment(Qt.AlignHCenter | Qt.AlignTop)  # 本文居中
        self.plan_label.setStyleSheet("color:white;")
        self.plan_layout.addWidget(self.plan_button)
        self.plan_layout.addWidget(self.plan_label)
        sidebar.addLayout(self.plan_layout)
        
        self.project_layout = QVBoxLayout()
        self.project_layout.setSpacing(0)
        self.project_layout.setContentsMargins(0, 0, 0, 0)
        self.project_button = QPushButton("", self)
        self.project_button.setIcon(qtawesome.icon('fa.list-alt', color="white"))
        self.project_button.setIconSize(QSize(40, 40))
        self.project_button.setCheckable(True)
        self.project_button.setChecked(False)
        self.project_button.installEventFilter(self)  # 为每个按钮安装事件过滤器
        self.project_button.toggled.connect(self.onProjectBtnToggled)  # 绑定事件处理函数
        menu_buttonGroup.addButton(self.project_button)
        self.project_label = QLabel("项目", self)
        self.project_label.setAlignment(Qt.AlignHCenter | Qt.AlignTop)  # 本文居中
        self.project_label.setStyleSheet("color:white;")
        self.project_layout.addWidget(self.project_button)
        self.project_layout.addWidget(self.project_label)
        sidebar.addLayout(self.project_layout)
        
        self.info_layout = QVBoxLayout()
        self.info_layout.setSpacing(0)
        self.info_layout.setContentsMargins(0, 0, 0, 0)
        self.info_button = QPushButton("", self)
        self.info_button.setIcon(qtawesome.icon('fa.indent', color="white"))
        self.info_button.setIconSize(QSize(40, 40))
        self.info_button.setCheckable(True)
        self.info_button.setChecked(False)
        self.info_button.installEventFilter(self)  # 为每个按钮安装事件过滤器
        self.info_button.toggled.connect(self.onInfoBtnToggled)  # 绑定事件处理函数
        menu_buttonGroup.addButton(self.info_button)
        self.info_label = QLabel("信息", self)
        self.info_label.setAlignment(Qt.AlignHCenter | Qt.AlignTop)  # 本文居中
        self.info_label.setStyleSheet("color:white;")
        self.info_layout.addWidget(self.info_button)
        self.info_layout.addWidget(self.info_label)
        sidebar.addLayout(self.info_layout)
        
        sidebar.addStretch(10)  # 添加拉伸因子,使按钮之间有空隙
        
        market_button = QPushButton("", self)
        market_button.setIcon(qtawesome.icon('mdi.purse-outline', color="white"))
        market_button.setIconSize(QSize(40, 40))
        self.setupMenuBtnStyle(market_button)
        sidebar.addWidget(market_button)
        
        setting_button = QPushButton("", self)
        setting_button.setIcon(qtawesome.icon('mdi.hexagon-slice-6', color="white"))
        setting_button.setIconSize(QSize(40, 40))
        self.setupMenuBtnStyle(setting_button)
        sidebar.addWidget(setting_button)
        
        # 进度显示区域
        progressFrame = QFrame(self)
        progressLayout = QVBoxLayout()
        progressFrame.setLayout(progressLayout)
        
        # 水平布局放置圆环和“今日任务”文本
        hLayout1 = QHBoxLayout()
        # 进度条
        self.progressRing_today = ProgressRing(70, QColor(106, 121, 249))  # 设置初始进度为70%
        self.progressRing_today.setFixedSize(120, 120)  # 设置进度环大小
        hLayout1.addWidget(self.progressRing_today, alignment=Qt.AlignCenter)
        # 进度文本
        todayTaskLabel = QLabel("今日任务", self)
        todayTaskLabel.setAlignment(Qt.AlignCenter)  # 居中对齐
        hLayout1.addWidget(todayTaskLabel)  # 添加文本到同一行
        progressLayout.addLayout(hLayout1)  # 将水平布局添加到进度框中
        
        # 水平布局放置圆环和“历史任务”文本
        hLayout2 = QHBoxLayout()
        self.progressRing_history = ProgressRing(50, QColor(200, 102, 224))  # 设置初始进度为70%
        self.progressRing_history.setFixedSize(120, 120)  # 设置进度环大小
        hLayout2.addWidget(self.progressRing_history, alignment=Qt.AlignCenter)
        # 进度文本
        historyTaskLabel = QLabel("历史任务", self)
        historyTaskLabel.setAlignment(Qt.AlignCenter)  # 居中对齐
        hLayout2.addWidget(historyTaskLabel)
        progressLayout.addLayout(hLayout2)  # 将水平布局添加到进度框中
        
        # 水平布局放置数量显示
        hLayout3 = QHBoxLayout()
        countLabel1 = QLabel("数量: ", self)
        countLabel1.setAlignment(Qt.AlignCenter)  # 居中对齐
        countLabel2 = QLabel("24", self)
        countLabel2.setAlignment(Qt.AlignVCenter | Qt.AlignLeft)  # 居左对齐
        countLabel2.setStyleSheet("font-size: 24px;")  # 更新样式
        hLayout3.addWidget(countLabel1)
        hLayout3.addWidget(countLabel2)
        progressLayout.addLayout(hLayout3)  # 将水平布局添加到进度框中
        
        # 添加分割线
        line1 = QFrame()
        line1.setFrameShape(QFrame.HLine)  # 设置为水平线
        line1.setFrameShadow(QFrame.Sunken)  # 设置阴影效果
        progressLayout.addWidget(line1)
        
        # 添加创建任务按钮
        createBtn = QPushButton("创建", self)
        # 设置按钮的样式表
        createBtn.setStyleSheet("""
            QPushButton {
                background: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0, stop: 0 #800080, stop: 1 #66B2FF);  /* 调整右侧颜色 */
                color: white;
                border: 2px solid rgba(0, 0, 0, 0.2); /* 添加边框以模拟阴影 */
                padding: 10px;
                height: 40px;
                font-size: 20px;
                border-radius: 15px;
                margin: 5px; /* 添加外边距以分离按钮与背景 */
            }
            QPushButton:hover {
                background: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0, stop: 0 #9933CC, stop: 1 #99CCFF); /* 悬停时的颜色调整 */
            }
            """)
        progressLayout.addWidget(createBtn)
        
        # 创建一个QCheckBox,并将其设置为不可见
        self.checkbox = QCheckBox('', self)
        self.checkbox.setChecked(False)
        self.checkbox.setVisible(False)  # 隐藏复选框
        
        # 创建开关区域
        self.toggle_area = QWidget(self)
        self.toggle_area.setFixedSize(190, 50)  # 设置开关区域的大小
        self.toggle_area.setStyleSheet("background: #D8D3E1; border-radius: 25px;")  # 设置背景和圆角
        
        # 创建左侧和右侧的 QLabel
        self.label_left = QLabel('显示', self.toggle_area)
        self.label_right = QLabel('全部', self.toggle_area)
        
        # 设置标签的样式
        self.setupLabel(self.label_left, "green")  # Off 标签
        self.setupLabel(self.label_right, "gray")    # On 标签
        
        # 设置标签的固定大小和位置
        self.label_left.setFixedSize(95, 50)  # 左侧标签占一半
        self.label_right.setFixedSize(95, 50)   # 右侧标签占一半
        self.label_left.move(0, 0)  # Off 标签左上角坐标
        self.label_right.move(95, 0)   # On 标签左上角坐标,实现重叠
        progressLayout.addWidget(self.toggle_area)
        
        # 初始化开关状态
        self.updateSwitch()
        self.toggle_area.mousePressEvent = self.toggle
        
        # 添加目标控件
        icon = qtawesome.icon('mdi.tune-vertical-variant', color='black')
        pixmap = icon.pixmap(20, 20)
        # 将 QPixmap 转换为 QImage,然后转换为 Base64 编码的字符串
        image = pixmap.toImage()
        byte_array = QByteArray()
        buffer = QBuffer(byte_array)
        image.save(buffer, "PNG")
        b64_icon = byte_array.toBase64().data().decode()
        # 创建 QLabel 并设置富文本, 其中包含 Base64 编码的图标
        html = f'<img src="data:image/png;base64,{b64_icon}"/> 目标'
        targetLabel = QLabel(html)
        progressLayout.addWidget(targetLabel)
        # 添加分割线
        line2 = QFrame()
        line2.setFrameShape(QFrame.HLine)  # 设置为水平线
        line2.setFrameShadow(QFrame.Sunken)  # 设置阴影效果
        progressLayout.addWidget(line2)
        self.targetBtn1 = QPushButton("周览照片", self)
        self.targetBtn1.setIcon(qtawesome.icon('mdi.card-plus-outline', color="black"))
        self.targetBtn1.setIconSize(QSize(20, 20))
        self.targetBtn1.setProperty('icon_name', 'mdi.card-plus-outline')  # 设置自定义属性以标识图标
        self.targetBtn1.installEventFilter(self)  # 为每个按钮安装事件过滤器
        self.targetBtn2 = QPushButton("检查清单", self)
        self.targetBtn2.setIcon(qtawesome.icon('mdi.format-float-left', color="black"))
        self.targetBtn2.setIconSize(QSize(20, 20))
        self.targetBtn2.setProperty('icon_name', 'mdi.format-float-left')  # 设置自定义属性以标识图标
        self.targetBtn2.installEventFilter(self)  # 为每个按钮安装事件过滤器
        self.targetBtn3 = QPushButton("周期性任务", self)
        self.targetBtn3.setIcon(qtawesome.icon('mdi.widgets-outline', color="black"))
        self.targetBtn3.setIconSize(QSize(20, 20))
        self.targetBtn3.setProperty('icon_name', 'mdi.widgets-outline')  # 设置自定义属性以标识图标
        self.targetBtn3.installEventFilter(self)  # 为每个按钮安装事件过滤器
        self.targetBtn4 = QPushButton("历史任务", self)
        self.targetBtn4.setIcon(qtawesome.icon('fa5s.poll', color="black"))
        self.targetBtn4.setIconSize(QSize(20, 20))
        self.targetBtn4.setProperty('icon_name', 'fa5s.poll')  # 设置自定义属性以标识图标
        self.targetBtn4.installEventFilter(self)  # 为每个按钮安装事件过滤器
        # 设置按钮样式
        self.setupTargetBtnStyle(self.targetBtn1)
        self.setupTargetBtnStyle(self.targetBtn2)
        self.setupTargetBtnStyle(self.targetBtn3)
        self.setupTargetBtnStyle(self.targetBtn4)
        # 按钮添加到布局上
        progressLayout.addWidget(self.targetBtn1)
        progressLayout.addWidget(self.targetBtn2)
        progressLayout.addWidget(self.targetBtn3)
        progressLayout.addWidget(self.targetBtn4)
        
        # 设置侧边栏的占位符项
        sidebar.addStretch(1)
        
        # 主要内容区域
        mainArea = QVBoxLayout()
        
        # 获取当前日期
        today = QDate.currentDate()
        
        # 日期选择
        todayLabel = QLabel(today.toString("yyyy年 MM月 dd日"), self)
        todayLabel.setStyleSheet("font-size: 25px; font-weight: bold;")
        mainArea.addWidget(todayLabel)
        
        # 创建日期控件布局
        date_layout = QHBoxLayout()
        weekdays = ["一", "二", "三", "四", "五", "六", "日"]
        # 添加按钮组并设置互斥性
        date_buttonGroup = QButtonGroup(self)
        date_buttonGroup.setExclusive(True)
        week_labels = []
        # 创建日期按钮或标签
        for i in range(-2, 5):  # 前两天到后四天
            date = today.addDays(i)
            # 日期按钮
            date_pushbutton = QPushButton(date.toString("MM/dd"), self)
            date_pushbutton.setFixedSize(70, 70)
            date_pushbutton.setStyleSheet("""
                                        QPushButton {
                                            color: #000000;
                                            font-size: 16px; 
                                            font-weight: bold; 
                                            border-radius: 35px;
                                            background-color: #F4F4F4;
                                        }
                                        QPushButton:checked {
                                            color: white;
                                            font-size: 16px; 
                                            font-weight: bold; 
                                            border-radius: 35px;
                                            background: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 1, stop: 0 #9933CC, stop: 1 #99CCFF); /* 悬停时的颜色调整 */
                                        }
                                        """)
            date_pushbutton.setCheckable(True)  # 设置为可选按钮
            date_pushbutton.setChecked(i == 0)  # 设置选中状态
            date_buttonGroup.addButton(date_pushbutton)
            # 周几标签
            week_day = weekdays[date.dayOfWeek() - 1]  # 获取星期几
            week_label = QLabel(f"周{week_day}", self)
            week_label.setAlignment(Qt.AlignHCenter | Qt.AlignTop)  # 居中靠上对齐
            week_label.setFixedSize(70, 70)
            week_label.setStyleSheet("font-size: 14px; font-weight: bold;")
            week_labels.append(week_label)
            # 创建垂直布局将日期和周几绑定
            date_week_layout = QVBoxLayout()
            date_week_layout.setSpacing(0) # 设置布局中的间距为0像素
            date_week_layout.addWidget(date_pushbutton)
            date_week_layout.addWidget(week_label)
            date_layout.addLayout(date_week_layout)
        # 添加左右箭头按钮
        left_button = QPushButton("<", self)
        left_button.setFixedSize(50, 50)
        left_button.setStyleSheet("""
                                QPushButton {
                                    color: gray; 
                                    font-size: 20px; 
                                    font-weight: bold; 
                                    border-radius: 25px; 
                                    background-color: #FFFFFF; 
                                    border: 1px solid gray;
                                }
                                QPushButton:hover {
                                    color: white;
                                    background: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0, stop: 0 #9933CC, stop: 1 #99CCFF); /* 悬停时的颜色调整 */
                                }
                                """)
        right_button = QPushButton(">", self)
        right_button.setFixedSize(50, 50)
        right_button.setStyleSheet("""
                                QPushButton {
                                    color: gray; 
                                    font-size: 20px; 
                                    font-weight: bold; 
                                    border-radius: 25px; 
                                    background-color: #FFFFFF; 
                                    border: 1px solid gray;
                                }
                                QPushButton:hover {
                                    color: white;
                                    background: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0, stop: 0 #9933CC, stop: 1 #99CCFF); /* 悬停时的颜色调整 */
                                }
                                """)
        date_layout.insertWidget(0, left_button)
        date_layout.addWidget(right_button)
        # 添加日期控件布局到主布局
        mainArea.addLayout(date_layout)
        
        # 代办清单
        todo_layout = QHBoxLayout()
        label_todolist = QLabel('代办清单', self)
        label_todolist.setStyleSheet("font-size: 20px;")
        todo_layout.addWidget(label_todolist)
        
        todo_layout.addStretch(50)  # 添加拉伸因子,使按钮之间有空隙
        
        # 以列表形式查看
        self.showlist_button = QPushButton("", self)
        self.showlist_button.setIcon(qtawesome.icon('ei.align-justify', color="black"))
        self.showlist_button.setIconSize(QSize(20, 20))
        self.showlist_button.setProperty('icon_name', 'ei.align-justify')  # 设置自定义属性以标识图标
        self.showlist_button.installEventFilter(self)  # 为每个按钮安装事件过滤器
        # 设置按钮样式
        self.setupTargetBtnStyle(self.showlist_button)
        todo_layout.addWidget(self.showlist_button)
        
        # 以平铺图标形式查看
        self.showicon_button = QPushButton("", self)
        self.showicon_button.setIcon(qtawesome.icon('ei.th-large', color="black"))
        self.showicon_button.setProperty('icon_name', 'ei.th-large')  # 设置自定义属性以标识图标
        self.showicon_button.installEventFilter(self)  # 为每个按钮安装事件过滤器
        self.showicon_button.setIconSize(QSize(20, 20))
        # 设置按钮样式
        self.setupTargetBtnStyle(self.showicon_button)
        todo_layout.addWidget(self.showicon_button)
        
        mainArea.addLayout(todo_layout)
        
        # 待办清单表格
        tableWidget = QTableWidget(self)
        # 设置自定义委托
        tableWidget.setItemDelegate(CustomDelegate())
        tableWidget.setRowCount(6)
        tableWidget.setColumnCount(6)
        tableWidget.setHorizontalHeaderLabels(['', '名称', '紧急程度', '满', '周期', 'From'])
        tableWidget.horizontalHeader().setDefaultAlignment(Qt.AlignLeft)  # 设置水平表头居左对齐
        
        for i in range(6):
            # 第一列复选框
            checkBox = QCheckBox()
            tableWidget.setCellWidget(i, 0, checkBox)
            # 第二列字体颜色与照片一致
            item = QTableWidgetItem("还书(芥草与泥淖)")
            item.setForeground(Qt.blue)  # 设置颜色
            tableWidget.setItem(i, 1, item)
            # 第三列字体设置为黄色
            urgentItem = QTableWidgetItem("!!!")
            urgentItem.setForeground(QColor("orange"))  # 设置字体为黄色
            tableWidget.setItem(i, 2, urgentItem)
            tableWidget.setItem(i, 3, QTableWidgetItem("0"))
            tableWidget.setItem(i, 4, QTableWidgetItem("日"))
            tableWidget.setItem(i, 5, QTableWidgetItem("今天"))
        
        # 自定义表头样式
        tableWidget.horizontalHeader().setVisible(True)  # 显示表头
        tableWidget.verticalHeader().setVisible(False)  # 隐藏表头列
        tableWidget.setShowGrid(False)  # 禁用网格线
        
        # 设置单行选中方式
        tableWidget.setSelectionBehavior(QTableWidget.SelectRows)  # 单行选中
        tableWidget.setSelectionMode(QTableWidget.SingleSelection)  # 只能选中一行
        
        # 设置列宽
        tableWidget.setColumnWidth(0, 40)  # 将第一列宽度设置为40
        tableWidget.setColumnWidth(1, 300) # 设置适当宽度的其他列
        tableWidget.setColumnWidth(2, 150)
        tableWidget.setColumnWidth(3, 150)
        
        mainArea.addWidget(tableWidget)
        
        # 将侧边栏、进度框和主要内容区域添加到主布局中
        mainLayout.addWidget(sidebarWidget)
        mainLayout.addWidget(progressFrame)
        mainLayout.addLayout(mainArea)
        
        self.setLayout(mainLayout)
    
    def setupLabel(self, label, color):
        """ 设置标签样式 """
        label.setAlignment(Qt.AlignCenter)
        label.setStyleSheet(f"color: gray; font-size: 14px; background: {color}; "
                            f"border-radius: 25px; height: 50px;")
    
    def setupTargetBtnStyle(self, button):
        button.setStyleSheet("""
                            QPushButton {
                                color: #000000;
                                text-align: left;
                                font-size: 16px; 
                                font-weight: bold; 
                                border-radius: 5px;
                                background-color: #F4F4F4;
                            }
                            QPushButton:hover { 
                                color: white;
                                font-size: 16px; 
                                font-weight: bold; 
                                border-radius: 5px;
                                background: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 1, stop: 0 #9933CC, stop: 1 #99CCFF); /* 悬停时的颜色调整 */
                            }
                            """)
    
    def setupMenuBtnStyle(self, button):
        button.setStyleSheet("""
                            QPushButton:hover { 
                                border-radius: 5px;
                                background: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 1, stop: 0 #9933CC, stop: 1 #99CCFF); /* 悬停时的颜色调整 */
                            }
                            """)
    
    
    def eventFilter(self, obj, event):
        # 检测鼠标悬浮事件
        if event.type() == QEvent.Enter:
            # 如果是QPushButton并且鼠标进入,则更改图标颜色
            #if isinstance(obj, QPushButton):
            if obj in [self.targetBtn1, self.targetBtn2, self.targetBtn3, self.targetBtn4, self.showlist_button, self.showicon_button]:
                icon_name = obj.property('icon_name')  # 获取自定义属性中的图标名称
                obj.setIcon(qtawesome.icon(icon_name, color='white'))  # 设置悬浮状态的图标和颜色
            elif obj == self.plan_button and not self.plan_button.isChecked():
                self.plan_button.setStyleSheet("""
                                                background-color: #43445A;
                                                border-top-left-radius: 5px;
                                                border-top-right-radius: 5px;
                                                border-bottom-left-radius: 0px;
                                                border-bottom-right-radius: 0px;
                                            """)
                self.plan_label.setStyleSheet("""
                                                color: white;
                                                background-color: #43445A;
                                                border-top-left-radius: 0px;
                                                border-top-right-radius: 0px;
                                                border-bottom-left-radius: 5px;
                                                border-bottom-right-radius: 5px;
                                            """)
            elif obj == self.project_button and not self.project_button.isChecked():
                self.project_button.setStyleSheet("""
                                                background-color: #43445A;
                                                border-top-left-radius: 5px;
                                                border-top-right-radius: 5px;
                                                border-bottom-left-radius: 0px;
                                                border-bottom-right-radius: 0px;
                                            """)
                self.project_label.setStyleSheet("""
                                                color: white;
                                                background-color: #43445A;
                                                border-top-left-radius: 0px;
                                                border-top-right-radius: 0px;
                                                border-bottom-left-radius: 5px;
                                                border-bottom-right-radius: 5px;
                                            """)
            elif obj == self.info_button and not self.info_button.isChecked():
                self.info_button.setStyleSheet("""
                                                background-color: #43445A;
                                                border-top-left-radius: 5px;
                                                border-top-right-radius: 5px;
                                                border-bottom-left-radius: 0px;
                                                border-bottom-right-radius: 0px;
                                            """)
                self.info_label.setStyleSheet("""
                                                color: white;
                                                background-color: #43445A;
                                                border-top-left-radius: 0px;
                                                border-top-right-radius: 0px;
                                                border-bottom-left-radius: 5px;
                                                border-bottom-right-radius: 5px;
                                            """)
        elif event.type() == QEvent.Leave:
            # 如果是QPushButton并且鼠标离开,则恢复默认图标颜色
            #if isinstance(obj, QPushButton):
            if obj in [self.targetBtn1, self.targetBtn2, self.targetBtn3, self.targetBtn4, self.showlist_button, self.showicon_button]:
                icon_name = obj.property('icon_name')  # 获取自定义属性中的图标名称
                obj.setIcon(qtawesome.icon(icon_name, color='black'))  # 恢复默认图标和颜色
            elif obj == self.plan_button and not self.plan_button.isChecked():
                self.plan_button.setStyleSheet("background-color: none;")
                self.plan_label.setStyleSheet("color: white; background-color: none;")
            elif obj == self.project_button and not self.project_button.isChecked():
                self.project_button.setStyleSheet("background-color: none;")
                self.project_label.setStyleSheet("color: white; background-color: none;")
            elif obj == self.info_button and not self.info_button.isChecked():
                self.info_button.setStyleSheet("background-color: none;")
                self.info_label.setStyleSheet("color: white; background-color: none;")
        # 继续传递事件以进行默认处理
        return super().eventFilter(obj, event)
    
    def toggle(self, event):
        self.checkbox.setChecked(not self.checkbox.isChecked())
        self.updateSwitch()

    def updateSwitch(self):
        """ 更新左右标签的颜色和重叠样式 """
        if self.checkbox.isChecked():
            # 当选中 "On" 时
            self.label_left.setStyleSheet("""
                                            color: gray; 
                                            font-size: 14px; 
                                            background: #D8D3E1; 
                                            border-radius: 25px; 
                                            height: 50px;
                                        """)
            self.label_right.setStyleSheet("""
                                            color: white; 
                                            font-size: 14px; 
                                            background: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0, stop: 0 #800080, stop: 1 #66B2FF);  /* 调整右侧颜色 */
                                            border-radius: 25px; 
                                            height: 50px; 
                                            margin-left: 0px; /* 让 On 标签覆盖到 Off 标签的右边 */
                                        """)  
        else:
            # 当选中 "Off" 时
            self.label_left.setStyleSheet("""
                                            color: white; 
                                            font-size: 14px; 
                                            background: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0, stop: 0 #800080, stop: 1 #66B2FF);  /* 调整右侧颜色 */
                                            border-radius: 25px; 
                                            height: 50px;
                                        """)
            self.label_right.setStyleSheet("""
                                            color: gray; 
                                            font-size: 14px; 
                                            background: #D8D3E1; 
                                            border-radius: 25px; 
                                            height: 50px; 
                                            margin-left: 0px;  /* 让 Off 标签覆盖到 On 标签的左边*/
                                        """)  
    
    
    def onPlanBtnToggled(self, checked):
        if checked:
            self.plan_button.setStyleSheet("""
                                            background-color: #9DA1C4;
                                            border-top-left-radius: 5px;
                                            border-top-right-radius: 5px;
                                            border-bottom-left-radius: 0px;
                                            border-bottom-right-radius: 0px;
                                        """)
            self.plan_label.setStyleSheet("""
                                            color: white;
                                            background-color: #9DA1C4;
                                            border-top-left-radius: 0px;
                                            border-top-right-radius: 0px;
                                            border-bottom-left-radius: 5px;
                                            border-bottom-right-radius: 5px;
                                        """)
        else:
            self.plan_button.setStyleSheet("background-color: none;")
            self.plan_label.setStyleSheet("color: white; background-color: none;")
    

    def onProjectBtnToggled(self, checked):
        if checked:
            self.project_button.setStyleSheet("""
                                            background-color: #9DA1C4;
                                            border-top-left-radius: 5px;
                                            border-top-right-radius: 5px;
                                            border-bottom-left-radius: 0px;
                                            border-bottom-right-radius: 0px;
                                        """)
            self.project_label.setStyleSheet("""
                                            color: white;
                                            background-color: #9DA1C4;
                                            border-top-left-radius: 0px;
                                            border-top-right-radius: 0px;
                                            border-bottom-left-radius: 5px;
                                            border-bottom-right-radius: 5px;
                                        """)
        else:
            self.project_button.setStyleSheet("background-color: none;")
            self.project_label.setStyleSheet("color: white; background-color: none;")
    
    def onInfoBtnToggled(self, checked):
        if checked:
            self.info_button.setStyleSheet("""
                                            background-color: #9DA1C4;
                                            border-top-left-radius: 5px;
                                            border-top-right-radius: 5px;
                                            border-bottom-left-radius: 0px;
                                            border-bottom-right-radius: 0px;
                                        """)
            self.info_label.setStyleSheet("""
                                            color: white;
                                            background-color: #9DA1C4;
                                            border-top-left-radius: 0px;
                                            border-top-right-radius: 0px;
                                            border-bottom-left-radius: 5px;
                                            border-bottom-right-radius: 5px;
                                        """)
        else:
            self.info_button.setStyleSheet("background-color: none;")
            self.info_label.setStyleSheet("color: white; background-color: none;")


if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = MainWindow()
    window.show()
    sys.exit(app.exec_())


运行后的效果如下:


动画效果如下:

可见效果与原图已经有99%的相似度了!

标签列表
最新留言