首页 > 其他分享 >基于PySide6与requests的多功能B站小帮手软件GUI界面设计并打包为exe文件

基于PySide6与requests的多功能B站小帮手软件GUI界面设计并打包为exe文件

时间:2024-07-18 13:25:05浏览次数:12  
标签:界面设计 layout GUI QtWidgets PySide6 setStyleSheet addWidget font self


小生今日闲来无事,学习了PySide6,并基于PySide6为之前写过的爬虫程序设计了GUI界面,和ffmpeg一起打包成一个exe文件,做成一个面向大众群体的软件。


该软件目前仍在持续更新中,目前是0.6.0版本喵。

先放一张软件GUI成品图喵:

话不多说,我们直接讲解喵~


0. 导入库

下面是本程序所有需要用到的库(仅供参考):

from dataclasses import dataclass
from PySide6 import QtWidgets, QtGui, QtCore
from PySide6.QtWidgets import QApplication, QWidget, QPushButton, QLabel, QMainWindow, QVBoxLayout
from PySide6.QtCore import Qt, QSize, QRect, QDateTime, QTimer
from PySide6.QtGui import QPainter, QPaintEvent, QIcon, QFont, QMouseEvent, QBrush, QPen, QRegion, QColor
from qt_material import apply_stylesheet
import enum
import random
import sys
import requests
import re
import ffmpeg
import os
import time
import webbrowser

1. 视频获取模块

(具体步骤放在另一篇文章中讲解,感兴趣的友友们可以参考一下喵)

2. 主界面制作

2. 1界面布局

(1)首先,主界面分为两大部分:上、下。

(2)这里上部分包含3行,

        第一行为食用指南按钮(QPushButton);第二行是一个QHBoxLayout,其中结构为:QLabel + QLineEdit;第三行也是一个QHBoxLayout,其中结构为:QLabel + QLineEdit + QPushButton。

(3)下部分包含2列,

        第一列为一个QVBoxLayout,其中结构为:QComboBox + QButtonGroup(其中有4个QRadioButton),第二列为一个QVBoxLayout,其中结构为:QTextBrowser + QProgressBar。

        代码如下:(这里只贴出了初始化部分的代码,功能函数小生就不多解释了喵,大家可以自行设计~)

class MainWindow(QtWidgets.QMainWindow):
    def __init__(self):
        super().__init__()
        self.mode0 = '爬取单个视频'    # 初始模式为单个视频爬取
        self.mode = 0    # 这里是视频爬取模式选择的参数
        self.bv = ''    # 这里是BV号存储的参数
        self.path = ''    # 这里是文件存储路径的参数

        # 初始化
        self.window().setStyleSheet(u"color:white; border-radius: 5px")
        self.setWindowTitle('小帮手')
        self.setWindowFlags(Qt.FramelessWindowHint)    # 隐藏原版标题栏
        self.setAttribute(Qt.WA_TranslucentBackground)
        self.resize(450, 500)    # 设置主界面大小
        title_Bar = CustomTitleBar('小帮手    ฅ^•ω•^ฅ', self)
        centralWidget = QtWidgets.QWidget()
        self.setCentralWidget(centralWidget)

        # 食用指南(相关代码后面会解释)
        button = QtWidgets.QPushButton('食 用 指 南 (必 看)')
        button.setStyleSheet("QPushButton:hover{background:#136763;}")
        button.clicked.connect(self.open_new_window)    # 这里的功能代码请自行设计喵

        # 输入BV号的那一行Layout
        BV_layout = QtWidgets.QHBoxLayout()
        tip_label = QtWidgets.QLabel('请输入BV号:')
        tip_label.setStyleSheet('font-family: Microsoft Yahei; font-size: 10pt; font-weight: bold')
        self.put_BV = QtWidgets.QLineEdit()
        self.put_BV.setPlaceholderText('在此输入BV号喵')
        self.put_BV.setStyleSheet('font-family: Microsoft Yahei; font-size: 10pt; font-weight: bold; ')
        self.search_button = QtWidgets.QPushButton('开始获取')
        self.search_button.setStyleSheet("QPushButton:hover{background:#136763;}")
        BV_layout.addWidget(tip_label)
        BV_layout.addWidget(self.put_BV)
        BV_layout.addWidget(self.search_button)
        self.search_button.clicked.connect(self.start)    # 这里的功能代码请自行设计喵
        tip_label.setStyleSheet("""
                        QLabel {
                            font-family: Microsoft Yahei;
                            font-size: 10pt;
                            font-weight: bold;
                        }
                    """)

        # 输入文件路径的那一行的Layout
        path_layout = QtWidgets.QHBoxLayout()
        self.path_tip = QtWidgets.QLabel('请输入下载路径:')
        self.path_tip.setStyleSheet('font-family: Microsoft Yahei; font-size: 10pt; font-weight: bold')
        self.put_path = QtWidgets.QLineEdit()
        self.put_path.setPlaceholderText('在此输入下载路径喵')
        self.put_path.setStyleSheet('font-family: Microsoft Yahei; font-size: 10pt; font-weight: bold')
        path_layout.addWidget(self.path_tip)
        path_layout.addWidget(self.put_path)



        # 爬取方式选择
        mode_tip = QtWidgets.QLabel('模式选择')
        mode_tip.setStyleSheet('font-family: Microsoft Yahei; font-size: 10pt; font-weight: bold')
        mode_layout = QtWidgets.QVBoxLayout()
        self.button0 = QtWidgets.QComboBox()
        self.button0.addItems(['爬取单个视频', '爬取视频合集'])
        self.button0.setStyleSheet('font-family: Microsoft Yahei; font-size: 10pt; font-weight: bold')
        self.button0.currentIndexChanged.connect(self.choose_mode0)    # 这里的功能代码请自行设计喵

        # 模式选择单选按钮
        self.buttongroup = QtWidgets.QButtonGroup()    # 先设置一个ButtonGroup
        button1 = QtWidgets.QRadioButton('模式1', centralWidget)
        button1.setStyleSheet('font-family: Microsoft Yahei; font-size: 10pt; font-weight: bold')
        button2 = QtWidgets.QRadioButton('模式2', centralWidget)
        button2.setStyleSheet('font-family: Microsoft Yahei; font-size: 10pt; font-weight: bold')
        button3 = QtWidgets.QRadioButton('模式3', centralWidget)
        button3.setStyleSheet('font-family: Microsoft Yahei; font-size: 10pt; font-weight: bold')
        button4 = QtWidgets.QRadioButton('模式4', centralWidget)
        button4.setStyleSheet('font-family: Microsoft Yahei; font-size: 10pt; font-weight: bold')
        self.buttongroup.addButton(button1, 1)
        self.buttongroup.addButton(button2, 2)
        self.buttongroup.addButton(button3, 3)
        self.buttongroup.addButton(button4, 4)
        mode_layout.addWidget(button1)
        mode_layout.addWidget(button2)
        mode_layout.addWidget(button3)
        mode_layout.addWidget(button4)
        self.buttongroup.buttonClicked.connect(self.choose_mode)    # 这里的功能代码请自行设计喵
        main_mode = QtWidgets.QVBoxLayout()
        main_mode.addWidget(self.button0)
        main_mode.addLayout(mode_layout)

        # 进程窗口与进度条
        process_layout = QtWidgets.QVBoxLayout()
        bottom_layout = QtWidgets.QHBoxLayout()
        self.text_output = QtWidgets.QTextBrowser()
        self.process = QtWidgets.QProgressBar()
        self.process.setRange(0, 4)
        process_layout.addWidget(self.text_output)
        process_layout.addWidget(self.process)
        self.process.setStyleSheet(u"QProgressBar::chunk\n"
                                    "{\n"
                                    "border-radius:11px;\n"
                                    "background:qlineargradient(spread:pad,x1:0,y1:0,x2:1,y2:0,stop:0 #76EEC6,stop:1  #76EEC6);\n"
                                    "}\n"
                                    "QProgressBar#progressBar\n"
                                    "{\n"
                                    "height:22px;\n"
                                    "text-align:center;/*\u6587\u672c\u4f4d\u7f6e*/\n"
                                    "font-size:14px;\n"
                                    "color:white;\n"
                                    "border-radius:11px;\n"
                                    "background: #000000 ;\n"
                                    "}")
        bottom_layout.addLayout(main_mode)
        bottom_layout.addLayout(process_layout)
        main_mode.setContentsMargins(0, 0, 10, 0)
        mode_layout.setContentsMargins(10, 0, 0, 0)

        # 创建主Layout
        main_layout = QtWidgets.QVBoxLayout(centralWidget)
        main_layout.addWidget(title_Bar)
        self.block_line = QtWidgets.QLabel('')
        main_layout.addWidget(self.block_line)
        main_layout.addWidget(button)
        main_layout.addLayout(path_layout)
        main_layout.addLayout(BV_layout)
        main_layout.addLayout(bottom_layout)
        main_layout.setContentsMargins(20, 15, 20, 15)

        # 启动动画(精简版)
        self.anim = QtCore.QPropertyAnimation(self.window(), b'geometry')
        self.anim.setDuration(100)
        x = 550
        y = 200
        self.anim.setStartValue(QtCore.QRect(x, y, 450, 500))
        self.anim.setEndValue(QtCore.QRect(x, y-50, 450, 500))
        self.anim.start()

2.2 标题栏设计

标题栏样式

这里需要为标题栏单独建立一个类喵,现将原始的标题栏隐藏,再显示自行设计的标题栏。

具体实现代码如下:(这里贴出了标题栏类的所有代码,欢迎大家参考喵~)

class CustomTitleBar(QtWidgets.QWidget):
    """标题栏类"""
    # 初始化
    def __init__(self, word, parent=None):
        super().__init__(parent)

        self.setFixedHeight(30)
        layout = QtWidgets.QHBoxLayout()
        layout.setContentsMargins(0, 0, 0, 0)

        self.titleLabel = QtWidgets.QLabel(word)
        self.titleLabel.setStyleSheet("color: white; font-size: 15pt; font-weight: bold;")
        self.minimizeButton = QtWidgets.QPushButton("")
        self.minimizeButton.setFixedSize(30, 30)
        self.minimizeButton.setStyleSheet(
            "QPushButton{border-image:url('./images/min.png');background:#363636;border-radius:10px;}"  # 29c941
            "QPushButton:hover{background:#1ac033;}"
        )
        self.minimizeButton.clicked.connect(self.minimize)

        self.maximizeButton = QtWidgets.QPushButton("")
        self.maximizeButton.setFixedSize(30, 30)
        self.maximizeButton.setStyleSheet(
            "QPushButton{border-image:url('./images/max.png');background:#363636;border-radius:10px;}"
            "QPushButton:hover{background:#ecae27;}"
        )
        self.maximizeButton.clicked.connect(self.maximize_restore)

        self.closeButton = QtWidgets.QPushButton("")
        self.closeButton.setFixedSize(30, 30)
        self.closeButton.setStyleSheet(
            "QPushButton{border-image:url('./images/close.png');background:#363636;border-radius:10px;}"
            "QPushButton:hover{background:#eb4845;}"
        )
        self.closeButton.clicked.connect(self.close)

        layout.addWidget(self.titleLabel)
        layout.addStretch()
        layout.addWidget(self.minimizeButton)
        layout.addWidget(self.maximizeButton)
        layout.addWidget(self.closeButton)

        self.setLayout(layout)
        self.start = None
        self.pressing = False

    def minimize(self):
        # 界面最小化
        self.window().showMinimized()

    def maximize_restore(self):
        # 界面最大化
        if self.window().isMaximized():
            self.window().showNormal()
        else:
            self.window().showMaximized()

    def close(self):
        # 关闭界面
        self.window().close()

    def mousePressEvent(self, event: QMouseEvent):
        # 光标按下处理
        if event.button() == Qt.LeftButton:
            self.start = event.globalPos()
            self.pressing = True

    def mouseMoveEvent(self, event: QMouseEvent):
        # 光标移动处理
        if self.pressing:
            self.window().move(self.window().pos() + event.globalPos() - self.start)
            self.start = event.globalPos()

    def mouseReleaseEvent(self, event: QMouseEvent):
        # 光标松开处理
        self.pressing = False

2.3 “食用指南”界面设计

“食用界面”是点击按钮后弹出的一个提示窗口,有该软件的使用指南。

成品图如下所示:

“食用指南”界面成品图

相关设计代码如下:(这里只贴出了初始化部分的代码,功能函数小生就不多解释了喵,大家可以自行设计~)

class MyDialog(QtWidgets.QDialog):
    # 食用指南界面
    def __init__(self):
        super().__init__()
        self.setWindowTitle('食用指南')
        self.resize(500, 400)
        self.setWindowOpacity(0.9)
        self.setWindowFlags(Qt.FramelessWindowHint)

        self.setMinimumSize(QSize(300, 100))

        titleBar = CustomTitleBar('>>食用指南<<', self)

        self.second_layout = QtWidgets.QVBoxLayout(self)
        tips1 = QtWidgets.QLabel('a. 本工具可以通过输入BV号,直接获取相应的B站音视频资源喵')
        tips2 = QtWidgets.QLabel('b. 在获取视频资源之前,请务必先输入下载位置喵(填入绝对路径)')
        tips3 = QtWidgets.QLabel('   【可以右键想要使用的文件夹,点击复制文件地址,粘贴到框里】')
        tips4 = QtWidgets.QLabel('c. 爬取时有四种模式喵:')
        tips5 = QtWidgets.QLabel('   1. 模式一:仅下载音频')
        tips6 = QtWidgets.QLabel('   2. 模式二:仅下载视频画面')
        tips7 = QtWidgets.QLabel('   3. 模式三:分别下载音频和视频画面')
        tips8 = QtWidgets.QLabel('   4. 模式四:下载完整的视频')
        tips9 = QtWidgets.QLabel('d. 做完以上工作,就可以开始获取视频了喵~')
        tips10 = QtWidgets.QLabel('【如需定制软件或小工具可联系作者本人:2199325776(QQ号)】')


        tips1.setStyleSheet('font-family: Microsoft Yahei; font-size: 10pt; font-weight: bold')
        tips2.setStyleSheet('font-family: Microsoft Yahei; font-size: 10pt; font-weight: bold')
        tips3.setStyleSheet('font-family: Microsoft Yahei; font-size: 10pt; font-weight: bold')
        tips4.setStyleSheet('font-family: Microsoft Yahei; font-size: 10pt; font-weight: bold')
        tips5.setStyleSheet('font-family: Microsoft Yahei; font-size: 10pt; font-weight: bold')
        tips6.setStyleSheet('font-family: Microsoft Yahei; font-size: 10pt; font-weight: bold')
        tips7.setStyleSheet('font-family: Microsoft Yahei; font-size: 10pt; font-weight: bold')
        tips8.setStyleSheet('font-family: Microsoft Yahei; font-size: 10pt; font-weight: bold')
        tips9.setStyleSheet('font-family: Microsoft Yahei; font-size: 10pt; font-weight: bold')
        tips10.setStyleSheet('font-family: Microsoft Yahei; font-size: 11pt; font-weight: bold')

        do_not_click = QtWidgets.QPushButton('不要点我喵')
        do_not_click.setStyleSheet("QPushButton:hover{background:#136763;}")
        do_not_click.clicked.connect(self.dont_click)    # 这里的功能代码大家请自行设计喵
        do_not_click.resize(50, 30)



        self.second_layout.addWidget(titleBar)
        self.second_layout.addWidget(tips1)
        self.second_layout.addWidget(tips2)
        self.second_layout.addWidget(tips3)
        self.second_layout.addWidget(tips4)
        self.second_layout.addWidget(tips5)
        self.second_layout.addWidget(tips6)
        self.second_layout.addWidget(tips7)
        self.second_layout.addWidget(tips8)
        self.second_layout.addWidget(tips9)
        self.second_layout.addWidget(tips10)
        # self.second_layout.addWidget(tips11)

        dont = QtWidgets.QHBoxLayout(self)
        dont.addWidget(do_not_click)

        self.second_layout.addLayout(dont)
        self.second_layout.setContentsMargins(20, 20, 20, 20)

2.4 整体样式的选择

整体样式采用了qt_material中的样式,在apply_stylesheet()方法中选择theme为'dark_teal.xml',这里不做展开

2.5 打包成exe文件

因为本软件需要用到ffmpeg,所以需要将ffmpeg一并打包进exe文件中。

具体操作步骤如下:

(1)先将ffmpeg文件夹下的ffmpeg.exe文件复制到项目文件夹中

(2)在程序中开头添加如下代码:

ffmpeg_path = os.path.join(os.path.dirname(__file__), 'ffmpeg.exe')

(3)接着打开Terminal终端界面,输入以下代码:

pyinstaller -F -w 小帮手6.0.py --add-data 'ffmpeg.exe;.'

(4)等待打包完成即可喵~(相关exe文件会在dist文件夹中)


最后

0.6.0版本的GUI设计大部分设计内容到这里就基本上结束了,核心代码这里不做过多展开,感兴趣的小伙伴可以自行设计喵。

我是若琼,一名来自南京邮电大学,爱好编程的大一学生,欢迎各位私信留言喵~

标签:界面设计,layout,GUI,QtWidgets,PySide6,setStyleSheet,addWidget,font,self
From: https://blog.csdn.net/2301_79886169/article/details/140398444

相关文章