赞
踩
通过使用python、pyside6学习开发《艺术签名助手》这款桌面端软件,打造一款属于自己的个性化签名软件,提升自己的签名气质!
通过项目的练手,掌握pycharm环境下使用PySide6开发桌面端软件、并打包发布的整个流程。
1.2.2、主窗口分2个区:左侧菜单区、右侧工作区
Windows10 64位电脑
PyCharm Community Edition 2022.1.1、Python 3.8.10、PySide6、Pyinstaller、auto-py-to-exe
UI设计: 使用pyside6-designer.exe设计,
Ui编译:使用pyside6-uic.exe编译成py文件,
逻辑功能实现:Python
主要第三方库:requests :pip install requests
项目打包:auto-py-to-exe
Pycharm打开后,在File菜单选择New Project,打开界面,新建项目名Characters_Assistant,同时新建一个Base interpreter为Python 3.8的虚拟环境venv,如下:
Pycharm终端Terminal,虚拟环境下输入:pip install pyside6==6.4.3
回车后等待安装成功:Successfully installed PySide6-6.4.3 PySide6-Addons-6.4.3 PySide6-Essentials-6.4.3 shiboken6-6.4.3
2.4.2、配置外部工具pyside6-designer.exe、pyside6-uic.exe、Pyside6-rcc.exe
参考:Pycharm配置关于pyside6的外部工具 (syrr.cn)
2.4.2.1、pyside6-designer.exe
Pycharm/File/Settings/Tools/External Tools 界面点击+添加:
填写:名称Pyside6-Designer、描述 打开ui文件、程序E:\PycharmProjects\Art_Sign_Assistant\venv\Lib\site-packages\PySide6\designer.exe、参数$FileNameWithoutExtension$.ui、工作路径$FileDir$等,如下:
2.4.2.2、pyside6-uic.exe
Pycharm/File/Settings/Tools/External Tools界面点击+添加:
填写:名称Pyside6-UIC、描述将ui文件转为Python文件、程序E:\PycharmProjects\Art_Sign_Assistant\venv\Scripts\pyside6-uic.exe、参数$FileName$ -o ui_$FileNameWithoutExtension$.py、工作路径$FileDir$等,如下:
2.4.2.3、Pyside6-rcc.exe
Pycharm/File/Settings/Tools/External Tools界面点击+添加:
填写:名称Pyside6-RCC、描述将rcc资源文件转为Python文件、程序E:\PycharmProjects\Art_Sign_Assistant\venv\Scripts\pyside6-rcc.exe、参数$FileName$ -o rcc_$FileNameWithoutExtension$.py、工作路径$FileDir$等:
2.4.3、项目结构
入口函数,位于app.py里的main函数。其中,
img存放图标图片文件;
src文件夹存放各模块程序源代码文件;
ui文件夹存放pyside designer设计的ui 文件;
venv文件夹为项目虚拟环境文件夹;
在Pycharm中打开Tools菜单进入External Tools,选择使用pyside6-designer.exe设计主窗口界面,保存为 index.ui文件。
index.ui设计时,结合项目主要模块界面及各模块功能,整个主窗口Form部件为垂直布局verticalLayout,它又分为上下两个布局:上部为顶部区域水平布局top_zone_horizontalLayout_2,下部为中心区水平布局center_zone_horizontalLayout。
顶部区域水平布局top_zone_horizontalLayout_2,可以包含:应用的logo、使用帮助等功能区部件:
中心区水平布局center_zone_horizontalLayout,又分为:侧边菜单工具箱side_menu_toolBox部件,和 工作区堆叠部件workspace_stackedWidget:
index.ui文件完成后使用pyside6-uic.exe编译成 ui_index.py文件,供src/index_module/index.py文件引入,补充界面设计,并添加业务逻辑。
index.py文件代码:
- # -*- coding: utf-8 -*-
- '''
- 主窗口类:
- 顶部,顶部区域水平布局top_zone_horizontalLayout_2,包含:应用的logo、活动、当前用户、登录、会员充值、使用帮助等功能区部件;
- 中心区:中心区水平布局center_zone_horizontalLayout,又分为:侧边菜单工具箱side_menu_toolBox部件,和 工作区堆叠部件
- workspace_stackedWidget;
- '''
- from os import startfile
-
- from PySide6.QtGui import QIcon, QPixmap, QFont
-
- from PySide6.QtWidgets import (
- QWidget
- )
-
- # 首先,用外部工具pyside6-designer.exe设计外观界面,保存为 index.ui,
- # 然后用pyside6-uic.exe编译生成py文件:ui_index.py,从它里面导入里面的Ui_Form类
- from src.art_sign_page_module.art_sign_page import ArtSignPage
- from src.index_module.ui_index import Ui_Form
-
-
- # 主窗口类MyWindow,同时也继承我导入的Ui_Form类
- class MyWindow(QWidget, Ui_Form):
- def __init__(self):
- super().__init__()
- # 安装设计好的外观界面Ui
- self.setupUi(self)
- # 初始化窗口
- self.init_window()
- # 信号绑定
- self.bind()
-
- # 窗口打开时初始界面设置
- def init_window(self):
- # 设置主窗口标题栏Icon
- self.setWindowIcon(QIcon(r"./img/art_sign_assistant_32.ico"))
- # # 设置主窗口logo图片
- # self.logo_label.setPixmap(QPixmap(r"./img/logo-163x48.png"))
- # # 主页链接
- # self.index_label.setText("<a href='https://www.aizhuanhuan.cn/'>aizhuanhuan.cn</a>")
- # self.index_label.setFont(QFont("Microsoft YaHei", 30, 25))
-
- # 侧边菜单栏side_menu_toolBox各菜单设置图标初始值
- self.toggle_expand_icon = QIcon(r"./img/toggle-expand.png") # "+"
- self.toggle_icon = QIcon(r"./img/toggle.png") # "-"
- # 遍历侧边菜单栏side_menu_toolBox菜单,修改当前菜单为未展开图标toggle_icon,同时修改其它菜单为展开图标toggle_expand_icon
- for i in range(self.side_menu_toolBox.count()):
- if i == self.side_menu_toolBox.currentIndex():
- self.side_menu_toolBox.setItemIcon(i, self.toggle_icon)
- else:
- self.side_menu_toolBox.setItemIcon(i, self.toggle_expand_icon)
- # 设置侧边菜单栏side_menu_toolBox
- self.side_menu_toolBox.setCurrentIndex(0)
- # 设置侧边菜单栏side_menu_toolBox各菜单初始图标
- # 遍历侧边菜单栏菜单,修改当前菜单为未展开图标toggle_icon,同时修改其它菜单为展开图标toggle_expand_icon
- self.change_menu_current_icon(0)
-
- # 设置工作区workspace_stackedWidget所有页面:
- # 艺术签名字生成页面
- # 主窗口作为各页面的父级参数传入,以便交互
- self.art_sign_page = ArtSignPage(self)
-
- # 工作区堆栈部件添加所有页面部件
- self.workspace_stackedWidget.addWidget(self.art_sign_page)
-
- # 设置工作区workspace_stackedWidget初始页面为 art_sign_page 页面
- self.workspace_stackedWidget.setCurrentWidget(self.art_sign_page)
-
- # 绑定信号函数
- def bind(self):
- # 主页文本标签部件信号,链接一旦有鼠标悬浮,则打开主页”aizhuanhuan“
- self.index_label.linkHovered.connect(lambda val: startfile(val)) # type: ignore
-
- # 侧边菜单栏side_menu_toolBox当前菜单变化的信号,链接到改变当前菜单图标的函数
- self.side_menu_toolBox.currentChanged.connect(self.side_menu_change_current_icon)
- # 侧边菜单栏side_menu_toolBox当前菜单变化的信号,链接到工作区workspace_stackedWidget当前菜单第一个子菜单对应页面的函数
- self.side_menu_toolBox.currentChanged.connect(self.change_workspace_stackedWidget_current_page)
- # 侧边菜单栏当前菜单内子菜单点击的信号,链接到工作区workspace_stackedWidget当前子菜单对应页面的函数
- self.art_sign_pushButton.clicked.connect(self.change_current_page_to_art_sign_page)
-
- # # 点击“aizhuanhuan”按钮,打开浏览器进入aizhuanhuan网站
- # def open_index_page(self):
- # # 自动调用系统默认浏览器
- # startfile("https://www.aizhuanhuan.cn/")
-
- # 改变菜单图标函数,关键字参数current_index传入的值是当前菜单索引
- def change_menu_current_icon(self, current_index=None):
- # 遍历侧边菜单栏菜单,修改当前菜单为未展开图标toggle_icon,同时修改其它菜单为展开图标toggle_expand_icon
- for i in range(self.side_menu_toolBox.count()):
- if i == current_index:
- self.side_menu_toolBox.setItemIcon(i, self.toggle_icon)
- else:
- self.side_menu_toolBox.setItemIcon(i, self.toggle_expand_icon)
-
- # 侧边菜单栏side_menu_toolBox当前菜单变化时,改变所有菜单图标
- def side_menu_change_current_icon(self, index):
- # print("侧边菜单栏当前菜单变为:", index)
- # 遍历侧边菜单栏菜单,修改当前菜单为未展开图标toggle_icon,同时修改其它菜单为展开图标toggle_expand_icon
- self.change_menu_current_icon(index)
-
- # 侧边菜单栏side_menu_toolBox当前菜单点击,展示工作区workspace_stackedWidget当前菜单第一个子菜单对应页面
- # 参数index为侧边菜单栏side_menu_toolBox当前菜单索引
- def change_workspace_stackedWidget_current_page(self, index):
- # print("侧边菜单栏当前菜单变化,展示当前菜单对应工作区页面的首页面")
- # “图片通用工具”菜单general_menu,对应工作区workspace_stackedWidget页面即“图片文字识别”页面
- if index == 0:
- self.workspace_stackedWidget.setCurrentWidget(self.art_sign_page)
-
-
- # 工作区workspace_stackedWidget当前页面改为当前菜单对应页面
- def change_current_page_to_art_sign_page(self):
- self.workspace_stackedWidget.setCurrentWidget(self.art_sign_page)
在src/index_module/index.py内,构建一个主窗口类MyWindow,继承QWidget, Ui_Form,其中,QWidget是窗口部件类(对于主窗口起始也可以用QMainWindow类);
Ui_Form类是外观界面文件index.ui编译文件ui_index.py里的类。
主窗口类MyWindow继承Ui_Form类,在内部__init__函数内,还需要安装ui,即
# 安装设计好的外观界面Ui
self.setupUi(self)
主窗口类MyWindow内部__init__函数内,还需要初始化窗口、信号绑定:
# 初始化窗口
self.init_window()
# 信号绑定
self.bind()
初始化窗口函数init_window(self),主要用于设置应用打开时主窗口的初始显示界面。包括:主窗口标题栏、logo图片、当前用户文本标签、‘已登录用户字典’初始化,Login登录窗口部件类对象,侧边菜单栏side_menu_toolBox各菜单设置图标初始值、设置工作区workspace_stackedWidget所有页面,以及设置工作区workspace_stackedWidget初始页面;
绑定信号函数bind(self),主要用于设置主窗口内各部件信号触发,以及连接到相关的函数。比如:
侧边菜单栏side_menu_toolBox当前菜单变化的信号,链接到改变当前菜单图标;
侧边菜单栏side_menu_toolBox当前菜单内子菜单点击的信号,链接到工作区workspace_stackedWidget当前子菜单对应页面的函数;
在Pycharm中打开Tools菜单进入External Tools,选择使用pyside6-designer.exe设计页面,保存为 art_sign_page.ui文件。
art_sign_page.ui部件为垂直布局verticalLayout,它又分为上下两块:上部图片显示部件,下部为水平布局的按钮参数设置区域。
image_ocr_page.ui文件完成后使用pyside6-uic.exe编译成 ui_ image_ocr_page.py文件,供src/art_sign_page_module/art_sign_page.py文件引入,补充界面设计,并添加业务逻辑。
3.2.2、界面功能
art_sign_page.py代码:
- # -*- coding: utf-8 -*-
- '''
- 艺术签名页面:
- 右边工作区显示“艺术签名”页面,并在页面操作:导入文件,对文件进行处理。
- '''
-
- import os
- import re, requests
- from urllib.request import urlretrieve
-
- from PySide6.QtCore import (QCoreApplication, QDate, QDateTime, QLocale,
- QMetaObject, QObject, QPoint, QRect,
- QSize, QTime, QUrl, Qt)
- from PySide6.QtGui import (QBrush, QColor, QConicalGradient, QCursor,
- QFont, QFontDatabase, QGradient, QIcon,
- QImage, QKeySequence, QLinearGradient, QPainter,
- QPalette, QPixmap, QRadialGradient, QTransform)
- from PySide6.QtWidgets import (QApplication, QFrame, QHBoxLayout, QHeaderView,
- QLabel, QLineEdit, QPushButton, QRadioButton,
- QSizePolicy, QSpacerItem, QStackedWidget, QTableWidget,
- QTableWidgetItem, QToolBox, QToolButton, QVBoxLayout,
- QWidget, QFileDialog, QMessageBox, QButtonGroup, QColorDialog)
-
- from src.utils import GetDesktopPath, get_file_name, gen_rnd_filename
-
- # 首先,用外部工具pyside6-designer.exe设计外观界面,保存为 art_sign_page.ui,
- # 然后用pyside6-uic.exe编译生成py文件:ui_art_sign_page.py,从它里面导入里面的 Ui_art_sign_page 类
- from src.art_sign_page_module.ui_art_sign_page import Ui_art_sign_page
-
-
- # 页面类,继承ui界面类 Ui_art_sign_page
- class ArtSignPage(QWidget, Ui_art_sign_page):
- # 关键字参数parent 父级,设置为主窗口
- def __init__(self, parent=None):
- super().__init__()
- # 安装设计好的外观界面Ui
- self.setupUi(self)
- self.parent = parent
-
- # ”输入姓名“行文本输入框输入默认初值“艺术签名”
- self.name_lineEdit.setText("艺术签名")
-
- # ”签名字体“下拉列表选项框选项,以及默认初值
- self.font_comboBox.addItems(["行书签", "超级艺术签", "潇洒签", "手写连笔字", "行草签", "花式签", "温柔女生",
- "个性签", "商务签", "正楷体", "楷书签", "情书签", "卡通可爱签"])
- self.font_comboBox.setCurrentText("商务签")
-
- # 字体默认值"商务签"对应值
- self.fonts = "16.ttf"
- # # “字体颜色”默认黑色
- self.font_color = "#000000"
- # “背景颜色””默认白色
- self.bg_color = "#ffffff"
-
- # 信号绑定
- self.bind()
-
- # 绑定信号函数
- def bind(self):
- # ”签名字体“下拉列表选项框选项值变化信号,链接到函数
- self.font_comboBox.currentTextChanged.connect(self.get_fonts)
- # “字体颜色”按钮点击信号,链接到函数
- self.font_color_pushButton.clicked.connect(self.get_font_color)
- # “背景颜色”按钮点击信号,链接到函数
- self.bg_color_pushButton_2.clicked.connect(self.get_bg_color)
- # 设置默认的签名图片输出路径
- self.set_out_dir()
- # 页面”另存为“按钮点击信号,链接到函数another_save_out_dir
- self.another_save_pushButton_2.clicked.connect(self.another_save_out_dir)
- # 页面”开始去除“按钮点击信号,链接到函数start_convert
- self.start_generate_pushButton_3.clicked.connect(self.start_generate)
-
- # ”签名字体“下拉列表选项框选项值变化
- def get_fonts(self, text):
- print("当前字体:", text)
- # ”签名字体“下拉列表选项对应字体字典
- mapping_dict = {
- "行书签": "6.ttf",
- "超级艺术签": "7.ttf",
- "潇洒签": "8.ttf",
- "手写连笔字": "9.ttf",
- "行草签": "11.ttf",
- "花式签": "12.ttf",
- "温柔女生": "13.ttf",
- "个性签": "15.ttf",
- "商务签": "16.ttf",
- "正楷体": "17.ttf",
- "楷书签": "19.ttf",
- "情书签": "20.ttf",
- "卡通可爱签": "25.ttf"
- }
- self.fonts = mapping_dict[text]
-
-
- # 获取"字体颜色",并设置给变量self.font_color
- def get_font_color(self):
- color = QColorDialog().getColor()
- if color is not None:
- self.font_color = color.name()
- # 如果不选颜色,则默认黑色
- else:
- self.font_color = "#000000"
-
-
- # 获取"背景颜色"的颜色,并设置给变量self.bg_color
- def get_bg_color(self):
- color = QColorDialog().getColor()
- if color is not None:
- self.bg_color = color.name()
- # 如果不选颜色,则默认白色
- else:
- self.bg_color = "#ffffff"
-
-
-
- # 为添加的文件设置统一的“输出路径”文本输入框默认值
- def set_out_dir(self):
- # 默认“输出文件”路径:桌面路径构建文件夹“aizhuanhuan”
- out_dir = os.path.join(GetDesktopPath(), "aizhuanhuan")
- self.out_dir_lineEdit_2.setText(out_dir)
-
- # 点击”另存为“按钮,修改“输出路径”文本输入框值
- def another_save_out_dir(self):
- # 打开已存在路径,返回:result为路径
- new_out_dir = QFileDialog.getExistingDirectory(self, "另存为文件夹", ".")
- if new_out_dir is not None:
- self.out_dir_lineEdit_2.setText(new_out_dir)
-
- # 点击”生成艺术签名“按钮,对表格中所有的文件进行转换,
- # 处理过程中,“生成艺术签名”按钮不可用,
- # 正在处理的行的“处理状态”字段值设置由“待处理”修改为“处理中...”,
- # 转换完成后,该行对应转换好的文件保存到“输出路径”下,保存文件名为“输出文件名”;
- # 转换完成后,该行的“处理状态”字段值设置由“处理中...”修改为“处理完成!”,
- # 转换完成后,“生成艺术签名”按钮可用!
- def start_generate(self):
- # 签名图片名,带扩展名.gif
- out_file_name = self.name_lineEdit.text() + ".png"
- # 输出文件全路径,前面带上“输出路径”文本输入框的值
- out_file_path = os.path.join(self.out_dir_lineEdit_2.text(), out_file_name)
- # 输出文件夹路径不存在则创建
- if not os.path.isdir(self.out_dir_lineEdit_2.text()):
- os.makedirs(self.out_dir_lineEdit_2.text())
-
- # 设定签名参数
- data = {
- 'word': self.name_lineEdit.text(), # 需要设计的姓名
- 'fonts': self.fonts, # 字体
- 'sizes': self.font_size_spinBox.value(), # 字体大小
- 'fontcolor': self.font_color, # 字体颜色
- 'colors': self.bg_color # 签名背景颜色
- }
-
- # 访问的url(url网站地址仅供学习研究使用,请勿商用)
- url = 'http://www.kachayv.cn/'
- header = {
- 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36 Edg/114.0.1823.67'}
-
- result = requests.post(url, headers=header, data=data)
- result.encoding = 'utf-8'
- html = result.text
- # print("测试:html:", html)
- p = re.compile('<img id="showImg" src="cache/(.*?)"/>')
- match = p.findall(html)
- # print("match[0]:", match[0])
- # 将获取图片保存到out_file_path
- urlretrieve('http://www.kachayv.cn/cache/' + match[0], out_file_path)
-
- # 同时,将图片显示到”显示图片“部件
- if os.path.isfile(out_file_path):
- # 将处理后图片 展示到部件上
- # 调用图片自适应文本标签部件函数,代入参数:图片路径 和文本标签部件
- self.image_adapt_label(out_file_path, self.show_label)
-
-
- # 图片自适应文本标签部件函数, 参数:图片路径和文本标签部件
- def image_adapt_label(self, image_file_path, label):
- width = QPixmap(image_file_path).width() ##获取图片宽度
- height = QPixmap(image_file_path).height() ##获取图片高度
- ##比较图片宽度与label宽度之比和图片高度与label高度之比
- if width / label.width() >= height / label.height():
- ratio = width / label.width()
- else:
- ratio = height / label.height()
- ##定义新图片的宽和高
- new_width = width / ratio
- new_height = height / ratio
- # 按照新宽高缩放图片
- scaled_image = QPixmap(QPixmap(image_file_path)).scaled(int(new_width), int(new_height), Qt.IgnoreAspectRatio,
- Qt.SmoothTransformation)
- label.setPixmap(scaled_image)
-
绑定信号函数bind(self),主要用于设置页面内各部件信号触发,以及连接到相关的函数。
3.2、程序运行入口app.py
- # -*- coding: utf-8 -*-
- '''
- app.py应用启动文件。
- 侧边菜单栏,右边工作区,点击侧边菜单栏的菜单项,右边工作区显示对应菜单项的页面。
- 使用QToolBox+QStackedWidget
- 参考:https://blog.csdn.net/jun_zhong866810/article/details/119800461
- '''
-
- import sys
- from PySide6.QtWidgets import (
- QApplication,
- )
-
- from src.index_module.index import MyWindow
-
-
- if __name__ == "__main__":
- app = QApplication([])
- window = MyWindow()
- window.show()
- sys.exit(app.exec())
如下图,在pycharm中app.py里,点击绿色三角形,即可运行程序。
4.2、运行结果:
4.3、使用它生成艺术签名
如下图,输入“姓名”、选择“签名字体”,设置好“字体颜色”、“背景颜色”等,点击“生成艺术签名”按钮,得到如下结果:
Pycharm项目虚拟环境下终端命令行中命令:
(venv) PS E:\PycharmProjects\Art_Sign_Assistant >auto-py-to-exe
回车启动后界面:
E:/PycharmProjects/Art_Sign_Assistant/app.py
本项目,由于有各种依赖,打包后项目文件较大估计0.7GB左右,因此,采用“单目录”打包
选择“基于窗口的(隐藏控制台)”
自己准备一个即可
添加文件、添加文件夹,项目下文件夹、文件。
“常规选项”—name里面设置 “艺术签名助手” ,作为打包后应用名称。
“捆绑什么,搜索哪里”—key 里面设置加密值:xxxxxxxxxx
可以设置打包文件的输出目录Output Directory:E:/艺术签名助手项目
保存所有选项配置到json文件:
还可以将5.2.1-5.2.7所有配置信息保存进json文件,通过“设置/配置/导出配置到JSON文件”: Art_Sign_Assistant-auto_py_to_exe_config.json
5.2.9、点击“将.PY转换为.EXE“按钮打包
5.3、打包成功
在打包后的输出文件夹 ”E:/艺术签名助手项目“ 中双击“艺术签名助手.exe“文件,运行即可.
打包软件下载地址:<艺术签名助手>
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。