一、新建项目,目录结构如图:
PYS下存放脚本,SRC下存放资源文件,UIS下存放组态画面文件。
在每个子目录下都有__init__.py文件,系统会自动将其识别为软件包。
其中一个UIS.__init__.py文件的内容:
# import os
# 定义需要导入主脚本的所有画面,这是自动的方法,优点是可以自动生成画面列表,缺点是在主脚本中不能自动识别画面
# all_py = []
# for file in os.listdir('../UIS'):
# file_name, file_extension = os.path.splitext(file)
# if file_extension == '.py' and file_name != '__init__':
# all_py.append(file_name)
# __all__ = all_py
# 手动定义需要导入的画面列表,在主脚本中可以自动识别画面名称
__all__ = ['demo_ui'] # 导入画面
__all__列表定义了在别的脚本中调用本软件包,例如:
from UIS import *
需要导入的所有脚本列表。
二、使用uic工具将demo.ui转为脚本文件demo_ui.py。
三、使用RCC工具将资源文件media.qrc转为media_rc.py,并将其剪切粘贴至PYS文件夹(由于demo_ui.py是自动生成的,所以它对资源文件media_rc.py的调用时默认脚本文件夹)。
四、编写主脚本:
# encoding: utf-8
import sys
import time
from functools import partial
from PySide6.QtCore import Signal, QTimer, QObject, QPropertyAnimation, QEasingCurve
from PySide6.QtWidgets import QMainWindow, QApplication
# 导入画面
from UIS import *
# 导入脚本
from PYS import *
# 主画面类
class MainWindow(QMainWindow, demo_ui.Ui_MainWindow):
def __init__(self):
super().__init__()
self.setupUi(self)
self.run() # 初始化
self.slot_signal() # 信号与槽
# 主画面的初始化
def run(self):
self.move(200, 200)
self.show() # 显示画面
self.btnHome.setProperty('selected', True)
self.btnHome.setStyleSheet(self.btnHome.styleSheet()) # 刷新显示)
# 主画面的左边栏动画定义
ui.animate_leftFrame = QPropertyAnimation(self.leftFrame, b"minimumWidth") # 定义动画
ui.animate_leftFrame.setDuration(300) # 动画时间
# 左边栏的按钮站
self.left_button_station = [x for x in self.left_buttonsBox.children() if x.isWidgetType()]
# 信号与槽
def slot_signal(self):
# 时钟显示槽函数
def dateTimeShow_setText():
now = time.localtime()
time_str = time.strftime("%Y-%m-%d %H:%M:%S", now)
self.dateTimeShow.setText(time_str)
ui.secondSignal.connect(dateTimeShow_setText) # 槽函数的连接
# toggle按钮点击的槽函数
def btnToggle_clicked():
# 执行动画
JOBS.btn_animation(self.leftFrame, ui.animate_leftFrame)
# 刷新显示
for b in self.left_button_station:
b.setProperty('spread', not b.property('spread'))
b.setStyleSheet(b.styleSheet()) # 刷新显示
self.btnToggle.clicked.connect(btnToggle_clicked)
# 左边栏按钮站点击的槽函数
def left_buttons_clicked(button):
def one_btn_clicked():
# 设置各个按钮的显示外观
def set_styleSheet():
for b in self.left_button_station:
if b is not button:
b.setProperty('selected', False)
else:
b.setProperty('selected', True)
b.setStyleSheet(b.styleSheet()) # 刷新显示
set_styleSheet()
# 每个按钮的功能函数
if button is self.btnHome:
self.stackedWidget.setCurrentWidget(self.page_1)
elif button is self.btnNew:
self.stackedWidget.setCurrentWidget(self.page_2)
elif button is self.btnSave:
self.stackedWidget.setCurrentWidget(self.page_3)
elif button is self.btnExit:
self.stackedWidget.setCurrentWidget(self.page_4)
return one_btn_clicked
# 左边栏按钮站的按钮们点击的连接
for b in self.left_button_station:
b.clicked.connect(partial(left_buttons_clicked(b)))
# 项目的定义
class UI(QObject): # 将项目定义为QObject,用来管理项目级别的信号和变量
secondSignal = Signal() # 这是一个项目级别的信号,每秒发出一个信号
def __init__(self):
super().__init__()
self.timer = QTimer() # 一个项目级别的定时器
self.run() # 初始化
self.slot_signal() # 信号与槽
# 项目的初始化
def run(self):
self.timer.start(1000) # 定时器启动
# 信号与槽
def slot_signal(self):
# 定时器超时槽函数
def self_timer_timeout():
self.secondSignal.emit() # 秒信号发射
self.timer.timeout.connect(self_timer_timeout)
# 工作函数
class JOBS:
@staticmethod
# 按钮的动画
def btn_animation(obj, animation, start=50, end=150):
start_size = obj.width()
if obj.width() == start:
end_size = end
else:
end_size = start
animation.setStartValue(start_size)
animation.setEndValue(end_size)
# animation.setEasingCurve(QEasingCurve.Linear)
animation.setEasingCurve(QEasingCurve.InOutQuart)
animation.start()
# 工作函数2
@staticmethod
def Job_todo_2(var):
pass
# #############################主程序##################################
if __name__ == '__main__':
app = QApplication(sys.argv)
# 项目的实例化
ui = UI()
ui.windows = [] # 所有用到的窗口
# 初始化画面
mainWindow = MainWindow() # 主画面实例化
ui.windows.append(mainWindow)
sys.exit(app.exec())
至此,完成了一个小项目的demo。 这里没有像参考范例中那样搞专门的功能脚本文件夹,一方面是因为项目比较小没必要,另一方面,把功能函数放在主函数内更方便,因为可以直接在功能函数中操作一些项目范围内的全局变量,不用传递对象,更方便一些。