我用PYQT5做的第一个实用的上位机项目(三)
基本的程序框架:

因为自己不是专业的程序员,只是一个搞电气控制的“票友”,所以尽量减少手动输入 代码量,能在Qt Dsigner里面完成的组态就不要放在代码里面完成。
在框架的建设方面,尽量做到集中和整合,位于同一画面的部件就集中在一个地方,方便中途增加和删除部件。所有的元素,可以做到“望文知义”,通过代码的组织结构能够迅速找到每一个部件的特征和动作。
如图所示,目前阶段的框架,包含了以下:
公共函数,里面定义了一些通用的特征,比如常规型号的按钮、指示灯。
画面的类,目前创建了两个画面:form0( 主画面)和form_setting(设定值画面),每一个画面对应一个同名首字母大写的类,例如:form0对应的类是Form0,form_setting对应的类是Form_setting。然后在类里面,每一个需要有操作的部件,例如按钮、指示灯等,也都对应一个同名首字母大写的类,这样就可以把所有部件的操作按位置集中整合。
以设定值画面为例,共有三个部件需要操作:btn_OK,btn_cancel,label_setting

所以在Form_setting的函数定义里,有三个对应的子类:

Btn_OK,Btn_cancel,Label_setting,每个部件的定义和信号连接等都位于相应的类里面:

完整代码:
from sys import exit, argv
from PyQt5.QtCore import Qt, QCoreApplication, pyqtSignal
from PyQt5.QtWidgets import QApplication
from PyQt5 import uic
import buttons # 按钮的内嵌图片资源############################################
# 公共的函数
class PublicFunction: # 公共函数@staticmethoddef normal_button_init(button): # 通常规格按钮的初始化button.isEntered = False # 鼠标焦点是否在内button.setImage() # 获取按钮上的图片button.style_normal = f'background-color:#4b5075;border-radius:8px;border:2px solid rgb(43, 78, 140);color:#e6e6e6;image:{button.image};' # 常态stylebutton.style_enter = f'background-color:#4b5075;border-radius:8px;border:3px solid #e6e6e6;color:#e6e6e6;image:{button.image};' # 鼠标悬停后的stylebutton.style_clicked = f'background-color:#4b5075;border:2px solid #039806;border-radius:8px;color:#e6e6e6;image:{button.image};' # 鼠标点击后的stylebutton.style_on = f'background-color:#039806;border:4px solid #e6e6e6;border-radius:8px;color:#e6e6e6;image:{button.image};' # ON状态的stylebutton.style_disable = f'background-color:#767676;border:2px solid rgb(43, 78, 140);border-radius:8px;color:#c6c6c6;image:{button.image};' # 禁用状态下的style@staticmethoddef green_lamp_init(lamp): # 绿色指示灯lamp.rad = str(round(lamp.width() / 2))lamp.off_color = '#767676' # 默认off颜色lamp.on_color = '#039806' # 默认on颜色@staticmethoddef red_lamp_init(lamp): # 红色指示灯lamp.rad = str(round(lamp.width() / 2))lamp.off_color = '#767676' # 默认off颜色lamp.on_color = '#da1c1c' # 默认on颜色@staticmethoddef normal_label_init(label): # 通常标签的初始化label.isEntered = False # 鼠标焦点是否在内label.style_normal = 'background-color:#000d47;border:2px solid #4b5075;border-radius:8px;color:#f3da83;' # 常态stylelabel.style_enter = 'background-color:#4b5075;border-radius:8px;border:3px solid #e6e6e6;color:#e6e6e6;' # 鼠标悬停后的stylelabel.style_clicked = 'background-color:#4b5075;border:2px solid #039806;border-radius:8px;color:#e6e6e6;' # 鼠标点击后的style############################################
# 画面的类,每个画面对应一个同名的首字母大写的类
class Form0: # 画面form0的类(form0是主窗口)def __init__(self):self.items = [form0.btn_exit, form0.btn_setting, form0.btn_user, form0.btn_history,form0.lamp_working_1, form0.label_setting_1] # form0的所有部件self.Classes = [self.Btn_exit(), self.Btn_setting(), self.Btn_user(), self.Btn_history(),self.Lamp_working_1(), self.Label_setting_1()] # self的所有部件的类form0.setWindowFlags(Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint) # 关掉边框,始终最前form0.menuBar().setVisible(False) # 关闭顶部菜单栏form0.statusBar().setVisible(False) # 关闭底部状态栏form0.show() # 主画面显示# 画面中的部件的类,每个部件对应一个同名的首字母大写的类class Btn_exit: # “退出系统”按钮对应的类def __init__(self):PublicFunction.normal_button_init(form0.btn_exit) # 引用通常规格按钮的初始化form0.btn_exit.Clicked.connect(self.clicked)def clicked(self): # “退出系统”按钮点击后的操作for f in forms: # 关闭所有窗口f.close()class Btn_setting: # “参数设置”按钮对应的类def __init__(self):PublicFunction.normal_button_init(form0.btn_setting) # 引用通常规格按钮的初始化class Btn_user: # “用户管理”按钮对应的类def __init__(self):PublicFunction.normal_button_init(form0.btn_user) # 引用通常规格按钮的初始化class Btn_history: # “历史数据”按钮对应的类def __init__(self):PublicFunction.normal_button_init(form0.btn_history) # 引用通常规格按钮的初始化class Lamp_working_1: # “工作指示1”指示灯对应的类def __init__(self):PublicFunction.green_lamp_init(form0.lamp_working_1) # 初始化为绿色指示灯form0.lamp_working_1.color_on_bool(True) # 初始化为on状态class Label_setting_1: # “设置流量”标签对应的类def __init__(self):PublicFunction.normal_label_init(form0.label_setting_1) # 引用通常规格标签的初始化form0.label_setting_1.DoubleClicked.connect(self.double_clicked)def double_clicked(self):form_setting.move(form0.label_setting_1.pos()) # 将数据设置画面移动至标签所在位置form_setting.label_setting.setText(form0.label_setting_1.text()) # 将标签内容显示在设置画面的设置标签内form_setting.show() # 显示设置画面Form_setting.Btn_OK.todo = self.todo1 # 定义数据设置画面“确定”按钮按下后执行的函数def todo1(self): # 定义数据设置画面“确定”按钮按下后执行的函数form0.label_setting_1.setText(form_setting.label_setting.text())class Form_setting: # 画面form_setting的类(form_setting是共用的数据设置窗口)def __init__(self): # 画面form_setting的类的初始化form_setting.setWindowFlags(Qt.WindowStaysOnTopHint) # 始终最前self.items = [form_setting.btn_OK, form_setting.btn_cancel,form_setting.label_setting] # Form_setting的所有部件self.Classes = [self.Btn_OK(), self.Btn_cancel(),self.Label_setting()] # Form_setting的所有部件的类class Btn_OK: # “确定”按钮的类todo = None # 这是一个共用的画面,todo是本画面确定键按下后将要执行的函数args = [] # todo函数的参数def __init__(self):PublicFunction.normal_button_init(form_setting.btn_OK) # 引用通常规格按钮的初始化form_setting.btn_OK.Clicked.connect(self.clicked)form_setting.btn_OK.Clicked.connect(form_setting.close)def clicked(self):self.todo(*self.args) # 点击OK后执行预置的函数class Btn_cancel: # “取消”按钮的类def __init__(self):PublicFunction.normal_button_init(form_setting.btn_cancel) # 引用通常规格按钮的初始化form_setting.btn_cancel.Clicked.connect(form_setting.close)class Label_setting: # “设定值”标签的类def __init__(self):PublicFunction.normal_label_init(form_setting.label_setting) # 引用通常规格标签的初始化############################################
# 主函数
if __name__ == '__main__':app = QApplication(argv)QCoreApplication.setAttribute(Qt.AA_EnableHighDpiScaling) # 解决显示比例不同时的部件变形问题forms = [] # 所有画面显示界面的集合form0 = uic.loadUi('../UIS/form0.ui') # 生成并加载画面,form0是主画面forms.append(form0) # 将画面加入集合Form0 = Form0() # form0对应的类是Form0,将类Form0实体化form_setting = uic.loadUi('../UIS/设定值.ui')forms.append(form_setting)Form_setting = Form_setting()exit(app.exec_())
运行截图:

相关文章:
我用PYQT5做的第一个实用的上位机项目(三)
基本的程序框架: 因为自己不是专业的程序员,只是一个搞电气控制的“票友”,所以尽量减少手动输入 代码量,能在Qt Dsigner里面完成的组态就不要放在代码里面完成。 在框架的建设方面,尽量做到集中和整合,位…...
代谢组学分析平台(二)
GC/MS分析生物样本为何要衍生化处理?有哪些衍生化的方法? GC的流动相为气体(通常为高纯氦),这就要求被分析物必须能够气化,而生物样本中很多内源性代谢物都含有极性基团,具有沸点高、不易气化特…...
【统计学】Top-down自上而下的角度模型召回率recall,精确率precision,特异性specificity,模型评价
最近在学 logistic regression model,又遇见了几个之前的老面孔。 召回率recall, 精确率precision,特异性spcificity,准确率accuracy,True positive rate,false positive rate等等名词在学习之初遇到的困难在于&#x…...
AutoDL使用tensorboard
目录 一,训练形成log文件 二. 切换logs目录 三,在AutoPanel中访问TensorBoard 一,训练形成log文件 例子: from torch.utils.tensorboard import SummaryWriter import numpy as npwriter SummaryWriter() for x in range(1, …...
代谢组学分析手段(一)
核磁共振技术(Nuclear Magnetic Resonance, NMR) 定义:指核磁矩不为零的原子核在外磁场的作用下,核自旋能级发生塞曼分裂,共振吸收某一特定频率的射频辐射的物理过程。 优点: (1)…...
网络基础入门(网络基础概念详解)
本篇文章主要是对网络初学的概念进行解释,可以让你对网络有一个大概整体的认知。 文章目录 一、简单认识网络 1、1 什么是网络 1、2 网络分类 二、网络模型 2、1OSI七层模型 2、1、1 简单认识协议 2、1、2 OSI七层模型解释 2、2 TCP/IP五层(或四层)模型 三、网络传…...
简化任务调度与管理:详解XXL-Job及Docker Compose安装
在现代应用程序开发中,任务调度和管理是至关重要的一部分。XXL-Job是一个强大的分布式任务调度平台,它使得任务的调度和管理变得更加轻松和高效。本文将介绍XXL-Job的基本概念,并详细演示如何使用Docker Compose进行快速安装和配置。 什么是X…...
QByteArray字节数组
QByteArray字节数组 文章目录 QByteArray字节数组1.1 QByteArray类基本使用说明1.2 设置数组字节大小1.3 返回数组大小1.4 将数据转为其他类型1.5 将数据转为C语言的字符指针返回1.6 数组数据追加1.7 清除数组数据为指定值1.8 数组数据插入1.9 删除指定位置指定长度的数据1.10 …...
ubuntu20.04.3中qt程序界面嵌套另一个qt界面
先上代码 #include "mainwindow.h" #include <QApplication> #include <iostream> using namespace std; #ifdef _WIN32// Windows 平台的代码 #include <windows.h> #elif __linux__// Linux 平台的代码// ...#include <X11/Xlib.h> #else…...
【chainlit】使用chainlit部署chatgpt
💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kuan 的首页,持续学…...
测开 | Vue速查知识点
文章目录 Vue知识1. Vue 概述2. Vue 代码格式3. Vue 指令3.1 v-bind & v-model3.2 v-on3.3 v-if和v-show3.4 v-for 4. 生命周期 Vue知识 1. Vue 概述 简介: Vue.js(读音 /vjuː/, 类似于 view) 是一套构建用户界面的 渐进式框架。与其他…...
数据结构——二叉树的基本概念及顺序存储(堆)
目录 一.前言 二.树概念及结构 2.1 树的概念 2.2 树的相关概念 2.3 树的表现 2.4 树在实际中的应用(表示文件系统的目录树结构) 三.二叉树的概念及结构 3.1 概念 3.2 特殊的二叉树 3.3 二叉树的性质 3.4 二叉树的存储结构 3.4.1 顺序存储 3…...
acwing算法基础之基础算法--整数二分算法
目录 1 知识点2 代码模板 1 知识点 有单调性一定可以二分,但在某些情况下,不具有单调性也可以二分。 单调性也可以抽象成某类性质,分界点左边不满足此性质,而右边满足此性质。当然也可以分界点左边满足此性质,而右边不…...
windows C 开发
在win下用C/C开发 非图形界面 应用程序 基础环境包括3个内容1. API : 一般是系统(包括c标准库和其他dll)提供的2. 编译器 : 可以是gnu的,可以是微软提供的3. 编辑器 : 随意都可以 // 不再考虑范围开发方式(API编译器) 原生windows API 使用 Windows API 来编写非视窗代码。…...
C语言——动态内存管理详解(内存结构、动态内存函数、易错题、柔性数组)
本篇概要 本篇文章从基本出发讲述为什么要存在动态内存分配,动态内存函数有哪些,常见的动态内存错误,一些关于内存分配的练习题以及柔性数组的相关知识。 文章目录 本篇概要1.为什么存在动态内存分配1.1为什么要动态分配内存1.2内存结构 2.常…...
2023年全国控制科学与工程学科评估结果 - 自动化考研
考研选择学校时,控制科学与工程考研学校排名情况怎样是广大考研学子十分关心的问题,以下是我们自动化考研联盟为大家整理得最新控制科学与工程学科评估结果情况,还比较权威,供大家参考。 最后祝大家一战成硕,有其他问题欢迎评论区…...
React wangEditor5 使用说明
1、支持包安装 yarn add wangeditor/editor # 或者 npm install wangeditor/editor --saveyarn add wangeditor/editor-for-react # 或者 npm install wangeditor/editor-for-react --save2、使用 import wangeditor/editor/dist/css/style.css // 引入 cssimport { useState…...
vue 实现数字验证码功能
需求:写了一个 手机发送验证码后 输入固定验证码的功能 封装成一个组件,如下: <template><div class"conts"><div class"box"><div class"code_list"><div :class"[ code_item, hideIndex 0 ? co…...
【计算机网络】HTTP协议详解(举例解释,超级详细)
文章目录 一、HTTP协议简单介绍 1、1 什么是HTTP协议 1、2 再次理解“协议” 二、HTTP请求 2、1 HTTP的工作过程 2、1、1 demo代码 2、2 URL 介绍 2、2、1 urlencode 和 urldecode 2、3 HTTP 请求格式 三、HTTP响应 3、1 响应demo 3、2 HTTP 响应格式 四、HTTP 请求和响应中的…...
PCB放置过孔技巧
合理的放置过孔能有效的节约面积。 我们根据嘉立创的pcb工艺能力中写出单双面板最小过孔为0.3mm(内径)/0.5mm(外径) 设置过孔尺寸外直径为24mil(0.61mm))内直径为12mil(0.305mm) 嘉立创PCB工艺加工能力范围说明-嘉立…...
Chapter03-Authentication vulnerabilities
文章目录 1. 身份验证简介1.1 What is authentication1.2 difference between authentication and authorization1.3 身份验证机制失效的原因1.4 身份验证机制失效的影响 2. 基于登录功能的漏洞2.1 密码爆破2.2 用户名枚举2.3 有缺陷的暴力破解防护2.3.1 如果用户登录尝试失败次…...
通过Wrangler CLI在worker中创建数据库和表
官方使用文档:Getting started Cloudflare D1 docs 创建数据库 在命令行中执行完成之后,会在本地和远程创建数据库: npx wranglerlatest d1 create prod-d1-tutorial 在cf中就可以看到数据库: 现在,您的Cloudfla…...
ssc377d修改flash分区大小
1、flash的分区默认分配16M、 / # df -h Filesystem Size Used Available Use% Mounted on /dev/root 1.9M 1.9M 0 100% / /dev/mtdblock4 3.0M...
UDP(Echoserver)
网络命令 Ping 命令 检测网络是否连通 使用方法: ping -c 次数 网址ping -c 3 www.baidu.comnetstat 命令 netstat 是一个用来查看网络状态的重要工具. 语法:netstat [选项] 功能:查看网络状态 常用选项: n 拒绝显示别名&#…...
蓝桥杯 2024 15届国赛 A组 儿童节快乐
P10576 [蓝桥杯 2024 国 A] 儿童节快乐 题目描述 五彩斑斓的气球在蓝天下悠然飘荡,轻快的音乐在耳边持续回荡,小朋友们手牵着手一同畅快欢笑。在这样一片安乐祥和的氛围下,六一来了。 今天是六一儿童节,小蓝老师为了让大家在节…...
华为OD机试-食堂供餐-二分法
import java.util.Arrays; import java.util.Scanner;public class DemoTest3 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseint a in.nextIn…...
苍穹外卖--缓存菜品
1.问题说明 用户端小程序展示的菜品数据都是通过查询数据库获得,如果用户端访问量比较大,数据库访问压力随之增大 2.实现思路 通过Redis来缓存菜品数据,减少数据库查询操作。 缓存逻辑分析: ①每个分类下的菜品保持一份缓存数据…...
相机从app启动流程
一、流程框架图 二、具体流程分析 1、得到cameralist和对应的静态信息 目录如下: 重点代码分析: 启动相机前,先要通过getCameraIdList获取camera的个数以及id,然后可以通过getCameraCharacteristics获取对应id camera的capabilities(静态信息)进行一些openCamera前的…...
C# SqlSugar:依赖注入与仓储模式实践
C# SqlSugar:依赖注入与仓储模式实践 在 C# 的应用开发中,数据库操作是必不可少的环节。为了让数据访问层更加简洁、高效且易于维护,许多开发者会选择成熟的 ORM(对象关系映射)框架,SqlSugar 就是其中备受…...
Java面试专项一-准备篇
一、企业简历筛选规则 一般企业的简历筛选流程:首先由HR先筛选一部分简历后,在将简历给到对应的项目负责人后再进行下一步的操作。 HR如何筛选简历 例如:Boss直聘(招聘方平台) 直接按照条件进行筛选 例如:…...
