热门文章
最新发布
-
免费分享基于ThinkPHP在线证书查询系统源码 - 多端证书管理查询工具 基于ThinkPHP在线证书查询系统源码:免费开源资源分享 给大家免费分享一款实用的证书管理类资源——基于ThinkPHP开发的在线证书查询系统源码!无需付费,教育机构、培训机构或任何需要管理和查询证书信息的组织都能免费获取,不管是搭建官方证书查询平台,还是规范证书数据管理流程,都能轻松满足需求,妥妥的高效管理工具资源! mju39ijg.png图片 一、核心资源信息 核心定位(资源核心价值):专注在线证书查询与管理全需求,支持证书信息快速查询、后台统一管理,解决证书真伪核验、数据规范存储等问题,让用户便捷查询证书详情,组织高效管控证书数据,适配各类需要公开或内部查询证书的场景。 技术与适配(资源实用性):基于ThinkPHP框架开发,采用PHP+MySQL作为核心技术组合,技术成熟稳定,易维护易扩展;采用响应式设计,完美适配PC端和手机端,不同设备访问都能获得良好体验,兼容主流浏览器,使用无门槛。 二、核心功能与特色(免费解锁高效证书管理体验) 证书查询与管理:用户可通过证书编号等相关信息快速查询证书详情,核验真伪;管理员在后台能全面管理证书信息,包括添加、修改、删除等操作,流程简洁高效。 批量数据操作:支持JSON、CSV、Excel等多种格式的数据批量导入和导出,不用逐个录入或整理数据,大幅提升证书数据处理效率,节省人力成本。 权限与数据安全:支持多管理员角色设置,可给不同角色分配专属权限,避免数据误操作或泄露;通过加密传输和严格权限控制,全方位保障证书数据和用户信息安全。 界面与体验优化:前端查询界面和后台管理界面都精心设计,清新简洁,操作直观易懂,新手也能快速上手;特别修复了之前版本中证书照片错位、遮挡证件号码的问题,确保证书信息准确可读。 三、资源适用场景(免费资源适配多需求) 这款免费分享的源码用途十分广泛: 教育机构:用于学生毕业证、资格证书等信息管理,方便学生和用人单位在线查询核验,提升管理规范性。 培训机构:管理培训结业证书、技能证书数据,学员可自行查询证书信息,机构高效维护数据,降低沟通成本。 企业/行业组织:针对内部认证证书、职业资格证书等进行管理,实现证书信息公开查询,提升公信力。 其他组织:任何需要集中管理证书数据、提供在线查询服务的场景,都能直接部署使用或二次开发适配。 源码下载 多端证书管理查询工具 下载地址:https://pan.quark.cn/s/877adf53a2b8 提取码: 免费又实用,功能全面且体验流畅,不管是直接搭建使用,还是根据需求二次开发,这款基于ThinkPHP的在线证书查询系统源码都值得入手! -
免费分享酷瓜云课堂PHP源码 - 开源在线教育网校知识付费系统 酷瓜云课堂PHP源码:免费在线教育开源资源分享 mju2gi6m.png图片 给大家免费分享一款超实用的在线教育类资源——酷瓜云课堂PHP开源免费在线教育系统源码!无需付费,教育机构、企业、有知识分享需求的个人或开发者都能免费获取,不管是搭建网课平台、网校系统,还是做知识付费、企业内部培训平台,都能轻松实现,妥妥的低成本高效解决方案! 一、核心资源信息 核心定位(资源核心价值):专注在线教育全场景需求,提供开源的网课、网校、知识付费一体化系统,支持教学全流程管理——从课程发布、直播授课,到作业布置、考试考核、学习进度跟踪,一站式满足线上教学与培训需求,全功能可免费商用,不用顾虑版权问题。 技术与部署(资源实用性):基于高性能C扩展Phalcon框架开发,遵循GPL-2.0开源协议,运行响应快速且安全可靠;采用容器化部署方式,屏蔽环境差异,不用复杂配置,快速就能搭建起专属在线教育平台,依托MySQL数据库存储数据,技术成熟易维护。 二、核心功能与特色(免费解锁优质教育平台体验) 多端无缝适配:支持PC、H5、微信小程序、安卓和苹果端,学员可随时随地通过不同设备学习,打破时间和空间限制,提升学习便利性与灵活性,覆盖更多用户场景。 安全稳定高性能:依托Phalcon框架的C扩展优势,系统响应迅速,就算多用户同时在线学习、观看直播,也能保持流畅体验;具备完善的数据安全保护机制,保障教学数据和用户隐私安全。 全场景教学支持:教育机构可实现线上教学全流程管理,教师能上传教学资料、直播授课、布置作业与考试;企业可开展线上培训,跟踪员工学习进度并考核;个人可发布课程、提供在线辅导,实现知识变现。 低成本无套路:开源免费且支持商业使用,无需支付高额授权费,大幅降低搭建在线教育平台的成本;容器化部署简化操作,不用专业技术团队也能快速上线,省心省力。 三、资源适用场景(免费资源适配多需求) 这款免费分享的源码用途十分广泛: 教育机构:利用自身师资力量搭建专属网课平台,开展线上教学,实现教学全流程数字化管理,拓展教学边界。 企业单位:搭建内部培训平台,发布培训课程,跟踪员工学习进度并进行考核,结合线下培训形成多元化培训模式。 平台用户:针对积累的粉丝群体,搭建自主运营的知识付费平台,将粉丝转化为付费用户,实现商业转型。 个人用户:凭借专业知识或优质资源,搭建个人知识变现平台,通过发布课程、在线辅导等方式,将知识转化为收益。 资源下载 下载 下载地址:https://pan.quark.cn/s/d5f9dd35f8d3 提取码: 免费又实用,功能全面且部署便捷,不管是机构规模化运营,还是个人小范围分享,这款酷瓜云课堂PHP源码都能满足需求,强烈推荐有在线教育需求的用户获取使用! -
免费分享 PHP 码蚁成绩管理系统源码 - 教育机构学生成绩统计管理工具 PHP码蚁成绩管理系统源码:免费教育类开源资源分享 给大家免费分享一款专为教育机构打造的实用管理资源——PHP码蚁成绩管理系统源码!无需付费,学校、培训机构、老师都能免费获取,不管是优化成绩管理流程、减轻教务工作负担,还是规范学生成绩统计分析,都能轻松满足需求,妥妥的教育行业高效工具资源! mju0trbs.png图片 一、核心资源信息 核心定位(资源核心价值):聚焦教育机构的成绩管理需求,由一线小学教师结合实际工作场景开发,功能设计贴合教学日常——从学生信息维护、考试安排,到成绩录入、统计分析,再到权限管控,一站式解决成绩管理全流程问题,不用再依赖Excel手动统计,大幅提升工作效率。 技术适配(资源实用性):基于PHP开发,采用ThinkPHP框架,前端搭配X-adminV2.2界面,后端负责数据处理与逻辑运算,技术成熟稳定;依托MySQL数据库存储数据,支持常规服务器部署,安装配置流程简单,教育机构IT人员或有基础的老师都能操作。 二、核心功能资源(免费解锁全能管理体验) 完善的基础管理:支持学期、班级、班主任、学科管理,可维护学生、教师、管理员信息,还能设置单位信息、类别管理等系统基础配置,满足不同教育机构的组织架构需求。 灵活的考试与成绩管理:可自定义考试信息,设置各学科满分、优秀、良好、及格分数线及人数占比;能生成学生考试号、试卷标签和成绩采集表,方便考试组织;支持多种成绩录入方式——在线手动录入、表格批量录入、扫码枪快速录入,还能随时修改成绩,操作灵活。 全面的成绩统计分析:能查看成绩列表和多类型图表(柱形图、折线图、雷达图、箱体图等),直观呈现班级、年级成绩分布;可统计单个学生历次成绩,用表格+折线图展示成绩变化趋势;还能自定义统计项目,生成详细成绩报告,助力教学分析与决策。 精准的权限管控:支持教师、学生、管理员不同身份登录,按职务(教研组长、班主任、普通教师)分工分配数据权限,确保成绩数据安全,避免信息泄露;管理员可统一管理角色、权限,规范系统使用流程。 实用的数据保障功能:支持数据备份与恢复,防止意外丢失;可下载成绩列表、成绩条、班级/年级成绩统计表等,方便线下存档或分享;还能设置网页统计结果显示项目,按需展示关键数据。 三、资源特色(免费资源优势突出) 操作简便易上手:界面简洁明了,符合教育工作者使用习惯;优化后的操作流程,三步就能到达核心功能位置,不用复杂学习,老师快速就能熟练使用。 功能贴合教学实际:由一线教师开发,精准命中成绩管理痛点——比如扫码枪录入适配考试后快速登分场景,多图表统计满足教学分析需求,比通用管理系统更实用。 数据安全可靠:具备权限分级、数据加密等安全措施,同时支持数据备份恢复,保障成绩数据的完整性和保密性,教育机构可放心使用。 可扩展性强:基于成熟框架开发,代码结构清晰,教育机构可根据自身需求二次开发,比如添加特色统计项目、适配个性化教学管理流程。 四、资源适用场景(免费工具适配多需求) 这款免费分享的源码用途十分广泛: 中小学:用于班级、年级成绩统一管理,快速完成成绩录入、统计分析,生成成绩单和教学分析报告,减轻教务和老师工作量。 培训机构:针对各类考试(随堂测、阶段考、结业考)进行成绩管理,跟踪学员成绩变化,向家长反馈学习情况。 教研部门:汇总多所学校或多个班级成绩数据,进行跨班级、跨年级对比分析,为教学质量评估提供数据支持。 一线教师:个人管理所带班级成绩,快速统计平均分、优秀率、及格率,分析学生薄弱环节,精准调整教学策略。 资源下载 下载 下载地址:https://pan.quark.cn/s/e46b8a706785 提取码: 免费又实用,功能全面还贴合教育场景,不管是直接部署使用,还是二次开发适配个性化需求,这款PHP码蚁成绩管理系统源码都值得教育行业从业者获取! -
2025最新易支付开源模板前台+用户中心+后台三合一 这是一款开源模板,是2025年刚推出的最新类型,属于易支付范畴,它具备三部分,分别是前台部分,还有用户中心部分,以及后台部分,这三套UI呈现出很不错的状态,要是有喜欢的话那就自行去进行部署吧! 20250611131528379-1-1024x531.webp图片 20250611131534981-2-1024x534.webp图片 20250611131539867-3-1024x586.webp图片 20250611131545648-4-1024x514.webp图片 2025最新易支付开源模板前台+用户中心+后台三合一 下载地址:https://pan.quark.cn/s/701197be9878 提取码:AwHt -
全新二级域名分发系统网站源码 这是一套二级域名分发系统的网站源码,还是终极最强版本,还附带教程。字节耀未对其进行测试,若你喜欢这套源码,可自行部署。 20250610212310970-1-1024x731.webp图片 20250610212317251-2-1024x666.webp图片 20250610212325594-3-1024x576.webp图片 全新二级域名分发系统网站源码 – 终极最强版 下载地址:https://pan.baidu.com/s/1w1h2cHLaHE1XFRmK_vokbA?pwd=6t80 提取码:6t80 全新二级域名分发系统网站源码 – 终极最强版 下载地址:https://pan.quark.cn/s/2f7100873992 提取码:72NE -
Python 微信自动回复工具 | 带 PyQt5 图形界面 支持 Excel 关键词配置 微信自动回复工具(带PyQt界面) 最近帮朋友处理微信客服消息,重复回复太费时间,干脆写了个带图形界面的自动回复工具。不用记命令,填个Excel路径点按钮就能跑,还能实时看日志,日常用着挺顺手。下面把完整代码和用法贴出来,有需要的可以直接拿去改。 mjr3m247.png图片 先说说要准备的东西 环境:Python 3.8+(版本太高可能和pywin32不兼容) 要装的库:直接复制下面的命令到cmd里跑 pip install pywin32 pandas pyqt5 openpyxlmjr3dd3v.png图片 Excel回复表:建个Excel文件,第一列叫“关键词”,第二列叫“回复内容”,比如这样: 关键词回复内容你好您好~有什么可以帮您?下班时间我们18点下班,急事可留言~价格具体报价请发需求给我哦~mjr3ggkk.png图片 没有的朋友们不要急,我提供了默认数据文件下载,方便测试 微信自动回复表 下载地址:https://pan.quark.cn/s/75a06eed928c 提取码: 完整代码 import sys import time import win32gui import win32api import win32con import pandas as pd from PyQt5.QtWidgets import (QApplication, QMainWindow, QWidget, QLabel, QLineEdit, QPushButton, QTextEdit, QVBoxLayout, QHBoxLayout, QFileDialog) from PyQt5.QtCore import QThread, pyqtSignal, Qt from PyQt5.QtGui import QFont, QPalette, QColor # 消息监听线程:单独开线程是为了不让界面卡住 class ReplyWorker(QThread): # 用来给界面发日志的信号 log_send = pyqtSignal(str) # 用来告诉界面线程是否正常启动 thread_status = pyqtSignal(bool) def __init__(self, excel_path): super().__init__() self.excel_path = excel_path self.reply_rules = {} # 存关键词和回复的对应关系 self.wechat_handle = 0 # 微信窗口的句柄 self.running = False # 控制线程运行的开关 def load_excel_rules(self): """加载Excel里的关键词和回复""" try: # 用openpyxl读xlsx格式,避免编码问题 df = pd.read_excel(self.excel_path, engine='openpyxl') # 转成字典,查起来快 self.reply_rules = dict(zip(df['关键词'], df['回复内容'])) self.log_send.emit(f"回复表加载成功!共{len(self.reply_rules)}条规则") return True except Exception as e: # 捕获各种错误:文件没找到、格式不对、列名错 err_msg = f"加载Excel失败:{str(e)}" self.log_send.emit(err_msg) return False def find_wechat(self): """找到微信窗口,返回是否找到""" # 微信PC端的窗口名一般是“微信”,类名留空不限制 self.wechat_handle = win32gui.FindWindow(None, "微信") if self.wechat_handle == 0: self.log_send.emit("没找到微信窗口!请先打开微信并登录") return False # 把微信窗口提到最前面 win32gui.SetForegroundWindow(self.wechat_handle) self.log_send.emit(f"找到微信啦!窗口句柄:{self.wechat_handle}") return True def find_child(self, parent_handle, class_name=None): """找窗口里的子控件(比如输入框、发送按钮)""" child_handles = [] # 递归遍历所有子控件 def _enum_child(hwnd, extra): if class_name is None or win32gui.GetClassName(hwnd) == class_name: extra.append(hwnd) return True win32gui.EnumChildWindows(parent_handle, _enum_child, child_handles) # 返回第一个找到的控件(一般够用) return child_handles[0] if child_handles else 0 def get_last_msg(self, chat_panel): """获取聊天面板里最后一条消息""" # 微信聊天面板的文本就是所有消息,按换行分割取最后一行 all_msg = win32gui.GetWindowText(chat_panel) if all_msg: return all_msg.split("\n")[-1].strip() return "" def send_reply(self, input_box, send_btn, reply_content): """模拟输入并发送回复""" # 先清空输入框:选中所有文本再删除 win32gui.SendMessage(input_box, win32con.EM_SETSEL, 0, -1) win32gui.SendMessage(input_box, win32con.WM_CLEAR, 0, 0) # 逐个字符输入(太快会乱码,加个小延迟) for char in reply_content: win32gui.SendMessage(input_box, win32con.WM_CHAR, ord(char), 0) time.sleep(0.02) # 点击发送按钮 win32gui.SendMessage(send_btn, win32con.BM_CLICK, 0, 0) def run(self): """线程主逻辑:启动后一直监听""" self.running = True # 先加载规则和找微信,有一个失败就退出 if not self.load_excel_rules() or not self.find_wechat(): self.thread_status.emit(False) self.running = False return self.thread_status.emit(True) # 定位微信的核心控件(不同版本可能要改class_name,用Spy++看) session_list = self.find_child(self.wechat_handle, "ContactPanel") # 会话列表 input_box = self.find_child(self.wechat_handle, "Edit") # 输入框 send_btn = self.find_child(self.wechat_handle, "Button") # 发送按钮 chat_panel = self.find_child(self.wechat_handle, "ChatPanel") # 聊天面板 # 检查控件是否都找到 if not all([session_list, input_box, send_btn, chat_panel]): self.log_send.emit("没找到微信的核心控件!可能版本不兼容") self.running = False return self.log_send.emit("所有控件已定位,开始监听消息...") # 循环监听未读消息 while self.running: # 遍历所有会话找带“未读”的 sessions = [] win32gui.EnumChildWindows(session_list, lambda hwnd, extra: extra.append(hwnd), sessions) for session in sessions: session_text = win32gui.GetWindowText(session) if "未读" in session_text: # 点击未读会话,切换到聊天界面 win32gui.SendMessage(session, win32con.BM_CLICK, 0, 0) time.sleep(0.5) # 等消息加载出来 # 提取联系人(去掉“未读”字样) contact = session_text.replace("未读", "").strip() # 提取最后一条消息 last_msg = self.get_last_msg(chat_panel) if not last_msg: continue self.log_send.emit(f"\n收到[{contact}]的消息:{last_msg}") # 匹配关键词找回复 reply = "抱歉呀,我暂时没理解你的意思~" for keyword, content in self.reply_rules.items(): if keyword in last_msg: reply = content break self.log_send.emit(f"准备回复:{reply}") # 发送回复 self.send_reply(input_box, send_btn, reply) self.log_send.emit("回复发送成功!") # 每2秒查一次,别占太多CPU time.sleep(2) def stop(self): """停止线程""" self.running = False self.log_send.emit("\n监听已停止") # 主界面窗口 class ReplyWindow(QMainWindow): def __init__(self): super().__init__() self.worker = None # 监听线程对象 self.init_ui() # 初始化界面 def init_ui(self): """画界面:布局、按钮、输入框这些""" # 窗口基本设置 self.setWindowTitle("微信自动回复工具 v1.0 - 作者:寒烟似雪 2025/12/29发布在字节曜www.ziyeyao.com博客") self.setFixedSize(1200, 1000) # 固定大小,不允许拉伸 self.setStyleSheet("background-color: #f5f5f5;") # 中心部件(主窗口必须有个中心部件才能放内容) central_widget = QWidget() self.setCentralWidget(central_widget) # 主布局(垂直排列:路径输入→按钮→日志) main_layout = QVBoxLayout(central_widget) main_layout.setSpacing(15) # 控件之间的间距 main_layout.setContentsMargins(25, 25, 25, 25) # 边距 # 1. Excel路径选择区域(水平排列:标签→输入框→选择按钮) path_layout = QHBoxLayout() # 路径标签 path_label = QLabel("回复表路径:") path_label.setFont(QFont("微软雅黑", 10)) # 路径输入框 self.path_edit = QLineEdit() self.path_edit.setFont(QFont("微软雅黑", 9)) self.path_edit.setPlaceholderText("点击右侧按钮选择Excel文件") self.path_edit.setStyleSheet(""" QLineEdit { padding: 6px; border: 1px solid #ddd; border-radius: 4px; background-color: white; } """) # 路径选择按钮 self.select_btn = QPushButton("选择文件") self.select_btn.setFont(QFont("微软雅黑", 9)) self.select_btn.setStyleSheet(""" QPushButton { padding: 6px 12px; border: none; border-radius: 4px; background-color: #4285f4; color: white; } QPushButton:hover { background-color: #3367d6; } """) self.select_btn.clicked.connect(self.select_excel) # 绑定选择文件事件 # 把三个控件加到水平布局里 path_layout.addWidget(path_label) path_layout.addWidget(self.path_edit, stretch=1) # 输入框占满剩余空间 path_layout.addWidget(self.select_btn, stretch=0) main_layout.addLayout(path_layout) # 2. 启动/停止按钮区域(水平排列) btn_layout = QHBoxLayout() # 启动按钮 self.start_btn = QPushButton("启动监听") self.start_btn.setFont(QFont("微软雅黑", 10)) self.start_btn.setStyleSheet(""" QPushButton { padding: 8px 0; border: none; border-radius: 4px; background-color: #34a853; color: white; } QPushButton:disabled { background-color: #a0d9a0; } QPushButton:hover:enabled { background-color: #2d8d46; } """) self.start_btn.clicked.connect(self.start_listen) # 绑定启动事件 # 停止按钮 self.stop_btn = QPushButton("停止监听") self.stop_btn.setFont(QFont("微软雅黑", 10)) self.stop_btn.setStyleSheet(""" QPushButton { padding: 8px 0; border: none; border-radius: 4px; background-color: #ea4335; color: white; } QPushButton:disabled { background-color: #e8a098; } QPushButton:hover:enabled { background-color: #d33526; } """) self.stop_btn.clicked.connect(self.stop_listen) # 绑定停止事件 self.stop_btn.setEnabled(False) # 初始状态:停止按钮禁用 # 两个按钮平分宽度 btn_layout.addWidget(self.start_btn, stretch=1) btn_layout.addSpacing(10) # 按钮之间的间距 btn_layout.addWidget(self.stop_btn, stretch=1) main_layout.addLayout(btn_layout) # 3. 日志显示区域 # 日志标签 log_label = QLabel("运行日志:") log_label.setFont(QFont("微软雅黑", 10)) main_layout.addWidget(log_label) # 日志文本框(只读) self.log_edit = QTextEdit() self.log_edit.setFont(QFont("Consolas", 9)) self.log_edit.setReadOnly(True) self.log_edit.setStyleSheet(""" QTextEdit { padding: 8px; border: 1px solid #ddd; border-radius: 4px; background-color: white; color: #333; } """) main_layout.addWidget(self.log_edit, stretch=1) # 日志框占满剩余空间 def select_excel(self): """选择Excel文件,把路径填到输入框""" # 打开文件选择对话框,只显示Excel文件 file_path, _ = QFileDialog.getOpenFileName( self, "选择回复表", "", "Excel Files (*.xlsx; *.xls)" ) if file_path: self.path_edit.setText(file_path) def start_listen(self): """启动监听线程""" # 先检查路径是否填了 excel_path = self.path_edit.text().strip() if not excel_path: self.add_log("请先选择Excel回复表!") return # 检查线程是否已经在跑了 if self.worker and self.worker.isRunning(): self.add_log(" 监听已经在运行啦,不用重复启动") return # 创建线程对象,绑定信号 self.worker = ReplyWorker(excel_path) self.worker.log_send.connect(self.add_log) # 接收日志信号 self.worker.thread_status.connect(self.set_btn_status) # 接收线程状态信号 self.worker.finished.connect(self.thread_finished) # 线程结束时的信号 # 启动线程 self.worker.start() # 暂时禁用启动按钮 self.start_btn.setEnabled(False) self.add_log("正在初始化监听...") def stop_listen(self): """停止监听线程""" if self.worker and self.worker.isRunning(): self.worker.stop() # 禁用停止按钮,启用启动按钮 self.stop_btn.setEnabled(False) self.start_btn.setEnabled(True) else: self.add_log(" 监听还没启动呢,不用停止") def add_log(self, msg): """往日志框里加内容,自动滚到最下面""" # 加个时间戳,方便看什么时候发生的 time_str = time.strftime("[%H:%M:%S]", time.localtime()) self.log_edit.append(f"{time_str} {msg}") # 自动滚动到最后一行 self.log_edit.moveCursor(self.log_edit.textCursor().End) def set_btn_status(self, is_running): """根据线程状态设置按钮是否可用""" self.start_btn.setEnabled(not is_running) self.stop_btn.setEnabled(is_running) def thread_finished(self): """线程结束时的处理""" self.set_btn_status(False) self.add_log("监听线程已结束") def closeEvent(self, event): """窗口关闭时,确保线程也停了""" if self.worker and self.worker.isRunning(): self.worker.stop() self.worker.wait() # 等线程彻底结束 event.accept() def add_log(self, msg): """往日志里加内容(单独写个方法,方便调用)""" time_str = time.strftime("[%H:%M:%S]", time.localtime()) self.log_edit.append(f"{time_str} {msg}") self.log_edit.ensureCursorVisible() # 自动滚屏 # 程序入口 if __name__ == "__main__": app = QApplication(sys.argv) window = ReplyWindow() window.show() sys.exit(app.exec_()) 怎么用? 先建好转发的Excel表(列名必须是“关键词”和“回复内容”) 运行代码,会弹出一个窗口 点击“选择文件”,找到你建的Excel表 点击“启动监听”,然后打开微信(必须是PC端,登录状态) 有人发消息含关键词,就会自动回复了,日志里能看到过程 不想用了就点“停止监听”,或者直接关窗口 mjr3et38.png图片 注意事项 微信版本兼容问题 这个工具是靠pywin32识别微信窗口控件来实现的,不同版本的微信,控件的类名(比如ContactPanel、ChatPanel)可能不一样。如果运行时提示“没找到核心控件”,可以用Spy++(VS自带工具)查看你电脑上微信的控件类名,然后修改代码里find_child方法传入的class_name参数。 必须打开微信PC端 工具没法模拟微信登录,运行前一定要手动打开微信PC端并登录账号,而且最好不要最小化微信窗口,否则可能识别不到控件。 Excel格式要求 Excel文件里必须有两列,列名严格对应“关键词”和“回复内容”,建议保存为.xlsx格式,避免编码问题。如果提示“加载Excel失败”,检查一下文件路径有没有中文或特殊字符,或者是不是被其他软件占用了。 避免重复回复 工具默认每2秒扫描一次未读消息,如果你担心同一条消息被重复回复,可以在代码里加一个“已处理消息列表”,把已经回复过的消息内容存进去,下次扫描时先判断是否在列表里。 权限问题 运行程序时,如果遇到“权限不足”的提示,右键点击Python.exe,选择“以管理员身份运行”,或者给当前用户授予窗口控制的权限。 常见问题解决 问题1:启动后提示“没找到微信窗口” 解决:确认微信PC端已经打开,并且窗口标题是“微信”(不是其他自定义标题);如果微信在任务栏隐藏,先点击显示出来。 问题2:能找到微信,但提示“没找到核心控件” 解决:用Spy++查看微信的会话列表、输入框、发送按钮的类名,替换代码里对应的class_name;比如有些版本的微信输入框类名是RichEdit20W。 问题3:回复内容发送乱码 解决:在send_reply方法里,延长字符输入的延迟时间,把time.sleep(0.02)改成time.sleep(0.05);同时确保Excel文件的编码是UTF-8。 问题4:线程启动后,界面卡死 解决:检查是不是把监听逻辑写在了主线程里——这个工具的监听代码在ReplyWorker线程里,和界面线程分离,不会卡界面;如果还是卡,大概率是控件识别耗时太长,可以减少扫描频率,把time.sleep(2)改成time.sleep(5)。 结语 这便是我制作的微信自动回复工具啦,有bug可以在评论区留言。有动手能力的朋友们可以尝试添加以下功能: 添加黑白名单:可以在Excel里加一列“是否启用”,或者单独建一个黑白名单文件,指定哪些联系人需要自动回复,哪些不需要。 支持多关键词匹配:现在是匹配到第一个关键词就回复,可以改成支持多个关键词同时匹配,比如“价格”和“优惠”同时出现时,回复特定内容。 定时启停:添加一个时间选择控件,设置每天的监听时间段,比如只在9:00-18:00运行,其他时间自动停止。 回复记录导出:把收到的消息和发送的回复记录到本地文件(比如CSV),方便后续查看和统计。 -
免费分享HTML在线扫雷游戏网页源码 - 经典益智Web游戏开发素材 HTML在线扫雷游戏网页源码:免费开源资源分享 给大家免费分享一款经典又耐玩的Web游戏资源——HTML在线扫雷游戏网页源码!无需付费,玩家、开发者都能免费获取,不用复杂安装,打开浏览器就能直接玩,不管是日常休闲打发时间,还是学习Web开发技术,都是性价比超高的优质资源! mjr1mfvo.png图片 一、核心资源信息 技术架构(资源核心配置):基于HTML+CSS+JavaScript开发,是单页小游戏源码,包含完整的游戏逻辑,代码结构清晰,拿来就能直接部署使用,也方便后续按需修改。 部署使用便捷性(资源优势):无需安装任何软件,不用配置复杂环境,直接在浏览器中打开就能玩;不管是PC、平板还是手机浏览器,都能顺畅运行,跨平台体验无压力。 二、核心功能资源(免费解锁经典扫雷体验) 多难度自由选择:内置初级、中级、高级三种预设难度,满足不同水平玩家需求——新手可以从初级上手,熟悉规则;老玩家能挑战高级难度,享受推理乐趣;还支持自定义雷区尺寸和地雷数量,想玩多大规模、多少地雷都能自己设置,玩法更灵活。 友好界面设计:界面简洁明了,色彩搭配和谐不刺眼,游戏区域和控制按钮一目了然,就算是第一次玩扫雷的用户,也能快速找到操作入口,上手无难度。 流畅稳定体验:源码经过精心优化,资源占用少、加载速度快,游戏过程中不会出现卡顿、延迟的情况,点击排查、标记地雷等操作响应迅速,保障沉浸式游戏体验。 三、资源特色(免费资源优势突出) 经典玩法复刻:完美还原传统扫雷的核心逻辑,通过点击排查方块、标记地雷,锻炼推理能力和反应速度,勾起童年回忆,休闲解压超合适。 可定制性强:支持自定义难度参数,开发者还能基于源码修改界面风格、添加特效或拓展新功能,满足个性化需求。 轻量化无负担:单页源码设计,加载快、不占设备内存,打开浏览器就能启动游戏,碎片时间随时能玩。 学习价值高:代码逻辑清晰,涵盖Web开发基础技能(如事件处理、界面交互、逻辑判断等),适合Web开发初学者作为学习案例,也能给有经验的开发者提供项目参考灵感。 四、资源适用场景(免费资源适配多需求) 这款免费分享的扫雷游戏源码,用途十分广泛: 普通玩家:日常休闲解压、打发碎片时间,不管是通勤路上、午休间隙,打开浏览器就能玩一局,轻松放松。 Web开发初学者:学习HTML、CSS、JavaScript的实际应用,通过分析源码理解游戏逻辑搭建、界面交互实现等基础技能,提升编程实践能力。 开发者/团队:作为项目参考素材,借鉴代码优化、轻量化设计的思路,或嵌入自己的网站、小程序中,丰富平台娱乐功能。 教学场景:作为编程教学案例,帮助学员直观理解前端开发的核心逻辑和操作流程,提升学习兴趣。 获取资源 H5扫雷源码 下载地址:https://pan.quark.cn/s/3839123b35bd 提取码: 免费无套路,经典又实用,不管是直接玩还是用来学习开发,这款HTML在线扫雷游戏网页源码都值得入手! -
免费分享变声器大师APP - 安卓聊天游戏短视频变声工具(萝莉御姐音) 变声器大师APP:安卓端免费变声工具,聊天游戏短视频都能用 给大家免费分享一款超有意思的手机变声工具——变声器大师APP!它是专为安卓用户设计的手机变声软件,不管是和好友微信QQ聊天整蛊、游戏开黑互动,还是在快手抖音做短视频配音,都能轻松切换声线,让声音玩出花样,妥妥的趣味工具资源! mjr1giec.png图片 一、核心资源信息 核心定位(资源核心价值):专注手机端实时变声与语音处理,支持微信、QQ、快手、抖音等主流社交/娱乐平台,不用切换APP,开悬浮窗就能随时变声;内置超多声线和语音包,从少女、御姐、萝莉、正太,到大叔、搞怪音效(比如海绵宝宝、机器人),甚至还有四川话、东北话、粤语等方言声线,满足不同场景的趣味需求。 使用门槛(资源便捷性):界面简洁直观,没有复杂操作步骤——不管是新手还是长辈,打开APP就能找到变声功能;不用注册登录,保护隐私的同时,省去繁琐流程,直接上手就能玩。 二、核心功能资源(免费解锁趣味变声体验) 丰富变声效果:采用全新变声算法,效果自然不生硬,预设了小男孩、小女孩、男青年、女青年等基础声线,还有萝莉、御姐、正太、大叔等热门类型,支持自定义调节变声参数(比如音调、语速),DIY专属个性声音;还自带火爆的海量语音包,适合LOL、吃鸡、王者荣耀等热门游戏,开黑时发一句“有人吗”“你在干嘛鸭”,瞬间活跃氛围。 实时变声互动:支持悬浮窗模式,开启后不用退出聊天或游戏APP——按住悬浮窗“按住说话”录完音,就能直接切换变声类型,点击播放试听效果,再同步到微信QQ发语音,全程不用来回切换,实时变声超方便;快手录短视频时也能这么操作,计时结束直接对接录音功能,配音变声一步到位。 清晰录音与管理:录音音质清晰,能完整保留声音细节,变声后也不模糊;还有完善的本地录音文件管理功能,录好的变声音频能分类保存,想找的时候一目了然,不怕丢失。 便捷分享传播:处理好的变声语音或录音,能直接分享到微信、QQ、微博、抖音等平台,不用额外保存再上传;不管是给好友发“土味情话”,还是分享游戏变声片段,都能快速完成,互动更有乐趣。 三、资源特色(免费工具优势突出) 效果自然不生硬:新变声算法比传统工具更细腻,不会有“机械感”,比如萝莉音软萌不刺耳,御姐音沉稳有质感,日常聊天或配音都不违和。 多场景无缝适配:不管是微信QQ实时聊天、游戏开黑语音,还是短视频录制配音,悬浮窗功能都能让变声“不打断操作”,不用频繁切APP,体验流畅。 免费无套路:核心变声功能完全免费,没有隐藏收费,也不用强制看广告才能用;录音和分享功能也不限制,普通用户日常使用完全够。 兼顾实用与趣味:除了变声,还能当清晰录音机用,课堂、会议记笔记也合适;语音包覆盖游戏、聊天、整蛊等场景,既好玩又实用。 四、资源适用场景(免费工具适配多需求) 这款免费的变声器大师APP,用途特别广: 游戏玩家:吃鸡、王者荣耀开黑时,用萝莉或御姐音和队友互动,让开黑更有氛围; 日常聊天:微信QQ和好友开玩笑,切换搞怪声线发语音,比如用海绵宝宝声说“你是不是不想理我呀”,增添互动趣味; 短视频创作者:抖音、快手做搞笑视频或配音时,用不同声线演绎角色,让作品更有特色; 普通用户:给家人发语音时换可爱声线,或者录“土味情话”分享,让日常沟通更有意思。 APP下载 变声器下载 下载地址:https://www.123865.com/s/WVrQvd-uHB6H?pwd=cytK# 提取码:cytK 免费又好玩,操作简单还不用费流量,不管是临时整蛊还是长期用,这款变声器大师APP都值得试试! -
免费分享水印抹布APP - 安卓视频图片去水印工具(多平台解析) 水印抹布APP:免费视频图片去水印工具,安卓端实用资源分享 给大家免费分享一款超实用的多媒体处理工具——水印抹布APP!它是专为去除视频和图片水印设计的手机应用,安卓用户可直接获取使用,不管是日常想保存无水印素材,还是自媒体创作者处理素材、普通用户编辑照片视频,都能轻松满足需求,妥妥的高效工具资源! mjr1bdpv.png图片 一、核心资源信息 核心定位(资源核心价值):专注解决视频、图片水印问题,能快速识别并去除各类水印——不管是社交媒体平台(如抖音、快手、小红书等)的平台水印,还是相机拍摄自带的水印,甚至支持YouTube、Instagram等国外主流平台素材的去水印与下载,输入素材链接就能自动处理,让素材恢复纯净质感。 使用门槛(资源便捷性):界面简洁直观,操作没有复杂步骤,就算是第一次用去水印工具的新手,也能快速上手;不用登录账号,保护隐私的同时,减少操作流程,打开APP就能直接处理素材。 二、核心功能资源(免费解锁全能处理体验) 高效去水印能力:采用先进的图像处理算法,几秒钟就能识别并抹除水印,还能精准定位复杂水印;支持“快速去除”“精细去除”“局部去除”等多种模式,按需选择更贴合需求;去除水印后还能保持视频图片的高清质量,不损失细节,画面依旧清晰。 批量与多平台支持:可一次性选择多个视频或图片批量处理,不用逐个操作,节省大量时间;不仅能处理本地素材,还支持解析抖音、快手、小红书、B站,以及YouTube、Instagram等国内外热门平台的素材链接,一键下载无水印版本,还能保存视频封面、字幕信息。 丰富编辑工具:除了去水印,还自带超多实用编辑功能——视频方面支持裁剪(自由比例/固定比例)、裁剪时长(剪片头片尾)、拼接多个片段、转GIF动图、变速;图片方面可裁剪尺寸、旋转角度、调整亮度对比度;还提供多种滤镜效果,能给素材加创意滤镜,打造个性化视觉风格。 安全与便捷辅助:处理过程会自动备份,防止意外丢失数据;采用数据加密技术,保护个人信息和素材安全,所有处理基本在本地执行,不泄露隐私;处理完成后能直接分享到社交平台,不用额外保存再上传,一步到位。 三、资源特色(免费工具优势突出) 功能全面无短板:不只是单纯去水印,还整合了下载、编辑、分享功能,一站式解决素材处理需求,不用再装多个工具。 操作简单易上手:界面模块化布局,功能按钮清晰,从解析素材、去水印到编辑保存,几步就能完成,新手也能轻松驾驭。 多场景适配:不管是自媒体创作者收集素材、处理作品,还是普通用户保存喜欢的视频图片、编辑生活记录,甚至是团队处理设计素材,都能满足。 免费友好:无订阅陷阱,不会自动扣费,低频用户还能通过观看广告、签到获取免费处理次数,不用花钱也能正常使用核心功能。 四、资源适用场景(免费工具适配多需求) 这款免费的水印抹布APP,用途特别广: 自媒体/内容创作者:快速收集各平台无水印素材,编辑后用于短视频、Vlog创作,提升内容质量。 日常用户:保存社交媒体上喜欢的视频图片(如教程、美景、生活片段),去除水印后收藏或分享给亲友。 设计/项目团队:批量处理设计素材中的水印,调整尺寸、拼接片段,高效完成设计方案或作品集。 海外内容爱好者:下载YouTube、Instagram等平台的优质内容,无水印保存,方便离线观看或二次创作(需注意版权)。 APP下载 水印抹布_1.0.3.zip 下载地址:https://pan.quark.cn/s/433c1619f03d 提取码:Advu 免费又好用,功能全还安全,不管是临时处理素材,还是长期使用,这款水印抹布APP都值得试试! -
免费分享多功能实用工具箱微信小程序源码 - 可变现工具类小程序资源 多功能实用工具箱微信小程序源码:免费开源资源分享 给大家免费分享一款超实用的微信小程序资源——多功能实用工具箱大全微信小程序源码!无需付费,个人开发者、小型团队都能免费获取,不管是学习小程序开发、快速搭建工具类产品,还是做创业项目孵化、个人副业变现,都是性价比超高的优质资源! mjr16vnj.png图片 一、核心资源信息 技术架构(资源核心配置):基于微信小程序原生开发,是综合性工具集合类项目,源码结构清晰、模块化设计合理,维护和二次开发都很方便,拿来就能按需调整功能。 部署便捷性(资源使用优势):不用配置服务器,也不用购买域名,直接在微信开发者工具中导入就能运行;数据可存在本地缓存,也能通过小程序云开发实现轻量级后端,零成本就能上线,技术门槛极低。 二、核心功能资源(免费解锁全能工具体验) 丰富工具集合:内置超多日常生活常用工具,比如单位换算、天气查询、快递查询、二维码生成器、日历提醒,还有手机清灰、震动手机、闪光灯、水平尺、各种计算器(房贷、工资、血型、亲戚关系等)、垃圾分类查询、网络测速等实用功能;还支持自定义添加新工具模块,后续想扩展功能也很灵活。 变现与推广功能:支持接入微信小程序官方流量主广告(包括Banner广告、激励视频广告等),能通过广告变现赚收益,特别适合个人副业或商业项目;首页可自定义轮播图,能用来做宣传推广、活动引导,轮播图还能配置跳转链接(内部页面或第三方小程序),支持跨平台导流,方便搭建小程序矩阵。 灵活扩展特性:所有功能模块都是独立封装的,提供详细注释和文档说明,就算是新手也能轻松上手二次开发;UI界面也是模块化设计,能根据需求重新设计主题风格,满足个性化需求。 三、资源特色(免费资源优势拉满) 免费可商用:源码完全开源,没有加密、没有使用限制,开发者能自由使用、修改和发布,不管是学习、教学演示,还是创业项目都能用。 低门槛零成本:不依赖服务器和数据库,省去运营成本;支持微信云开发,进一步简化后端逻辑,新手也能快速上线。 变现能力突出:快速接入流量主广告,轻松实现商业变现,是个人副业赚钱、小型团队创业的好选择。 高度可定制:功能模块能按需增删改查,界面风格可自由调整,灵活适配不同使用场景和需求。 体验友好:界面简洁直观,操作流程符合微信小程序用户使用习惯,工具分类清晰、搜索便捷,能提升用户留存率。 四、资源适用场景(免费资源适配多需求) 这款免费分享的源码用途特别广: 新手开发者:用来学习微信小程序开发技巧,熟悉模块化设计和功能封装; 个人用户:搭建专属工具类小程序,自用或分享给好友,提升生活效率; 创业者/小型团队:快速孵化工具类创业项目,借助广告变现和导流功能实现盈利; 教学场景:作为教学演示案例,帮助学员理解小程序开发逻辑和变现模式; 副业刚需:打造能赚钱的工具类小程序,利用流量主广告实现被动收入。 获取源码 微信实用工具箱集...程序源码.zip 下载地址:https://pan.quark.cn/s/045b6d30fcd8 提取码:1hb5 免费无套路,功能丰富又好部署,不管是直接使用还是二次开发,都能满足各类需求,强烈推荐大家获取体验! -
免费分享PHP仿微信即时聊天系统源码 - 支持音视频的多端通讯资源 PHP仿微信即时聊天系统源码:免费开源资源分享 给大家免费分享一款功能超全面的即时通讯资源——PHP仿微信即时聊天系统源码!无需付费,企业、开发者或有社交/沟通需求的用户都能免费获取,高度还原微信核心交互体验,不管是搭建内部沟通平台、社交社区,还是做在线客服、教育医疗行业的即时通讯解决方案,都是性价比拉满的优质资源! mjr13q1b.png图片 一、核心资源信息 技术架构(资源核心配置):基于PHP技术栈构建,采用前后端分离架构,后端通过PHP + MySQL + Redis + Workerman组合实现消息服务与业务逻辑,技术成熟稳定,拿来就能按需部署或二次开发。 服务器环境要求(资源部署适配):需搭配Linux OS(推荐CentOS 7.9)、Nginx(推荐最新稳定版)、PHP 7.3(兼容7.1及以上,不支持7.4+)、MySQL 5.7+、Redis 5.0+(推荐7.0)、Workerman 4.0+、Node.js 14.0+(推荐16.x)及npm 7.0+,满足配置即可稳定运行。 二、核心功能资源(免费解锁全能通讯体验) 全能聊天功能:单聊支持发送表情、图片、语音、视频、文件等多媒体消息,显示消息已读/未读状态和用户在线状态;群聊可创建/解散群组、管理成员(添加/移除)、设置群公告与禁言,管理员能撤回成员消息,还能限制群成员互加好友,保护隐私。 音视频通话:支持一对一音视频通话,已打通Web端与移动端,实现跨平台互通(小程序暂不支持该功能),满足实时沟通需求。 灵活消息设置:支持联系人置顶、消息免打扰、新消息声音提醒和浏览器通知推送,还能自定义消息接收方式,适配不同使用场景。 媒体与文件预览:支持文件、图片及大部分媒体格式在线预览,不用下载就能查看,大幅提升使用体验。 多端适配支持:兼容Web端、H5页面、原生APP安装使用,也支持小程序访问(部分功能受限),随时随地都能使用。 双模式自由切换:企业模式强调权限管理和信息保密,适合公司或组织内部使用;社区模式支持开放注册、用户自主加好友,适合搭建社交类平台。 消息推送与后台管理:APP支持单聊消息在线/离线推送(需自行配置Unipush服务);自带简易实用的后台管理界面,可实现用户管理、群组管理、系统设置、权限控制等功能。 三、资源特色(免费资源优势突出) 多端兼容性强:覆盖Web、H5、APP、小程序(部分功能),满足多样化部署需求,不管是电脑还是手机,都能顺畅使用。 微信风格UI设计:界面简洁直观,操作逻辑和微信高度契合,用户不用额外学习就能上手,降低使用门槛。 即时通信性能优异:基于Workerman构建实时消息服务,响应迅速且稳定,不会出现消息延迟、卡顿等问题。 数据安全有保障:支持群成员互加限制、消息撤回、权限分级等安全管理措施,兼顾隐私保护与信息管控。 易于二次开发:代码结构清晰,文档完整,不用复杂改动就能定制功能或扩展业务场景,适配不同需求。 四、资源适用场景(免费资源适配多需求) 这款免费分享的源码用途十分广泛: 企业/组织:搭建内部沟通平台,强调权限管理和信息保密,提升协作效率; 创业者/开发者:打造社交社区平台,支持用户注册、加好友、群聊等功能,快速落地社交项目; 行业解决方案:用于在线客服、教育辅导、医疗咨询等场景,实现实时沟通互动; 个性化需求:基于源码二次开发,定制专属即时通讯功能,适配更多细分场景。 源码获取 PHP仿微信聊天源码 下载地址:https://pan.quark.cn/s/77907e4d3481 提取码:V38p 免费无套路,功能全面且易部署,不管是直接使用还是二次开发,都能满足各类即时通讯需求,强烈推荐大家获取体验! -
免费分享HTML白色大气SEO优化公司网站源码 - 响应式企业建站模板 HTML白色大气SEO优化公司网站源码:免费开源资源分享 给大家免费分享一款超适合SEO相关企业的网站源码——HTML白色大气专业SEO排名优化公司网站模板!无需付费,SEO优化服务公司、网络营销机构、数字广告公司等企业,或是开发者、设计师,都能免费获取使用,不管是搭建企业官网、展示服务案例,还是对外宣传推广,都是实用性拉满的优质资源! mjr0xyjo.png图片 一、核心资源信息 技术架构(资源核心配置):基于HTML5 + CSS3 + JavaScript原生技术构建,不依赖复杂框架,上手门槛低;支持灵活扩展jQuery或Bootstrap插件,还能模块化开发,后续二次开发和维护都很方便,拿来就能按需调整。 适配与兼容(资源使用便捷性):采用响应式布局,能完美适配PC、平板、手机等多终端设备,满足移动端流量需求;同时兼容Chrome、Firefox、Safari、Edge等主流浏览器,确保不同用户访问体验一致,无需担心兼容性问题。 二、核心资源特色(免费解锁优质体验) 视觉风格专业大气:以纯白色为主色调,搭配深紫等色系,整体设计简洁利落,既显科技感又能传递信任感;动画过渡自然流畅,视觉吸引力强,配色方案统一,契合企业品牌调性,用作对外展示门面超合适。 SEO优化友好:页面结构采用语义化设计,利于搜索引擎收录;页面标题、关键词、描述标签可自定义设置,方便针对性优化;还做了静态资源优化(比如压缩CSS、JS、图片懒加载等),进一步提升SEO效果。 技术简洁高效:原生技术栈不冗余,开发和部署都很便捷;支持模块化扩展,想要添加更多交互功能也能轻松实现,不用额外投入过多技术成本。 mjr0wy4o.png图片 三、资源适用场景(免费资源适配多需求) 这款免费分享的网站源码,适用场景十分广泛: SEO优化服务公司搭建官方网站,展示企业形象和服务; 数字营销机构、网络推广公司制作展示站点,呈现业务范围和案例; 内容营销团队打造作品集,对外展示成果; 各类需要宣传数字营销、Web设计开发等业务的企业,用作宣传站点。 获取源码 HTML 白色大气 SEO 优化公司网站源码 下载地址:https://pan.quark.cn/s/1fe495a2d51a 提取码:67CQ 结语 不管是直接部署使用,还是基于源码二次开发定制专属功能,都能满足需求,免费无套路,是企业建站的高性价比选择! -
源支付V7 – V1.9.8免授权版安装包 行业聚合免签系统,凭借出色的系统性能、个性化的后台操作以及丰富多样的系统功能,攻克个人站长在知识付费与运营赞助方面的难关。其全新的轻量化界面 UI 能带来更为便捷高效的浏览感受,感兴趣的朋友可自行部署! 文字文档 文字文档 - https://umil.yuque.com/hqp3qz/wlewvo 20251228171126618-1-1024x549.webp图片 源支付V7 – V1.9.8免授权版安装包 下载地址:https://pan.baidu.com/s/1z84otQWkJw9N-llOqTdusw?pwd=040n 提取码:040n 源支付V7 – V1.9.8免授权版安装包 下载地址:https://pan.quark.cn/s/caa5d79a59e0 提取码:YDE8 -
NetworkPanel开源资源免费分享 - Vue3网速测速+IP查询Docker部署工具 NetworkPanel开源资源免费分享:Vue3网速测速+IP查询实用工具 给大家免费分享一款超实用的开源网络工具资源——NetworkPanel!它是基于Vue3技术栈开发的网速测速与IP地址查询工具,无需付费,个人、企业或开发者都能免费获取使用,不管是日常测网速、查IP,还是搭建专属网络工具平台,都是性价比超高的优质资源! mjr0paze.png图片 一、核心资源信息 技术架构(资源核心配置):前端采用Vue3 + TypeScript组合,搭配Vite + pnpm构建工具,不仅代码结构清晰、类型安全,开发和构建效率也大幅提升;还支持腾讯EdgeOne CDN优化加载速度,自带PWA离线访问能力,就算没网络也能应急使用,技术配置拉满且拿来即用。 部署支持(资源使用便捷性):提供多种零门槛部署方案,新手也能轻松上手——静态部署解压就能直接上线;Docker部署只需执行简单命令docker run -d --rm -p 8080:80 netart/network-panel:latest,一键就能启动;还支持腾讯云等云平台一键部署,不用复杂配置,快速就能用起来。 项目结构(资源二次开发友好):采用模块化设计,核心目录划分清晰,包含核心源码、静态资源、CI/CD配置、Docker构建配置等,还附带详细的说明文档,免费分享的源码支持自由二次开发和功能扩展,轻松满足个性化需求。 二、核心功能资源(免费解锁实用工具) 网速测速功能:支持设定测速数据量完成定量测试,多线程并发测速让测试效率更高,还能兼容iOS后台运行,移动端使用也顺畅不中断,免费获取就能拥有专业级测速体验。 IP地址查询功能:可查询多出口IP信息,适配多运营商网络环境,能清晰显示IP对应的地理位置、ISP、经纬度等详细内容,不管是排查网络问题还是了解IP归属,都特别实用。 自定义节点管理:支持添加自定义测速节点,还能动态切换和管理节点,灵活扩展测速网络覆盖范围,适配不同地区、不同网络场景的使用需求。 灵活配置功能:运行过程中能随时调整线程数量,不用重启就能生效;后台运行开关状态会自动保存,下次使用无需重新设置,使用体验更便捷。 三、资源特色(免费资源优势突出) 技术栈优质:基于Vue3 + TypeScript开发,代码质量有保障,后续维护和扩展也方便,免费资源也能拥有高品质体验; 可定制性强:支持自定义测速节点、灵活配置线程数和后台运行状态,不管是个人简单使用,还是企业定制化部署,都能满足; 部署零门槛:多种部署方式任选,无需复杂技术知识,静态部署、Docker部署或云平台部署都能快速完成,上手无压力; 体验出色:界面设计简洁直观,操作逻辑清晰,还删除了冗余统计脚本,加载速度更快;PWA特性让移动端访问更流畅,不管是电脑还是手机用都舒服。 源码下载 点击打开演示站 下载 下载地址:https://pan.quark.cn/s/ced31eb95857 提取码:kgHx 四、资源适用场景(免费资源适配多需求) 这款免费分享的NetworkPanel开源资源,用途特别广:个人用户可用来测试网络速度、查询IP详细信息,解决日常网络使用疑问;企业可借助它搭建多出口网络监控平台,实时掌握网络状态;开发者可基于源码二次开发,扩展更多个性化功能。无套路免费获取,实用性拉满,强烈推荐大家试试! -
WordPress插件 – 高级前端访问控制插件 此乃一款功能强劲、界面精美的WordPress插件,专为企业内部网站量身打造,可提供专业的前端访问控制解决办法。该插件借助密码保护、会话管理以及IP限制等安全功能,保障仅授权人员可访问网站内容。 20251228172038898-1-1024x477.webp图片 20251228172042848-2-1024x518.webp图片 20251228172045615-3-1024x521.webp图片 WordPress插件 – 高级前端访问控制插件 下载地址:https://pan.quark.cn/s/68d0fcc1dc7e 提取码:CNME -
阶段一实战项目:仿照记事本开发简易文本编辑器(PyQt5完整代码) 阶段一实战项目:仿照记事本界面开发简易文本编辑器 哈喽~ 欢迎来到PyQt5系列的第5篇——阶段一实战项目!经过前4篇的学习,我们已经掌握了QWidget基础窗口、线性布局(QVBoxLayout/QHBoxLayout)、核心基础控件(标签、按钮、输入框、复选框等)以及信号与槽的基础用法。今天我们将把这些知识点整合起来,仿照Windows记事本的核心界面与基础功能,开发一个简易文本编辑器,实现“新建、打开、保存文本”“文本编辑”“字体加粗”等核心功能,让你快速掌握知识点的综合应用! mjr0cjri.png图片 一、项目需求分析:仿照记事本核心功能 我们聚焦Windows记事本的核心功能,本次项目实现以下需求: 界面需求:仿照记事本布局,包含“功能按钮区”(新建、打开、保存、字体加粗)和“文本编辑区”(多行文本输入/显示); 核心功能:新建空白文本、打开本地文本文件、保存文本到本地、文本加粗编辑; 交互需求:按钮点击反馈、打开/保存文件弹窗提示、文本编辑实时响应; 适配需求:窗口缩放时,文本编辑区自适应调整大小。 【界面参考】Windows记事本核心布局:顶部功能按钮区 + 中间大面积文本编辑区,我们简化实现核心按钮,保证界面简洁且功能完整。 mjr06wos.png图片 二、技术选型:贴合阶段一知识点 本次项目严格基于阶段一所学知识点,不引入新的复杂组件,技术栈如下: 窗口组件:QWidget(主窗口); 布局管理器:QVBoxLayout(垂直布局,管理按钮区和编辑区)、QHBoxLayout(水平布局,排列功能按钮); 核心控件:QPushButton(功能按钮)、QTextEdit(多行文本编辑区)、QCheckBox(字体加粗选择框); 交互核心:信号与槽(按钮点击、复选框状态变化绑定对应功能); 文件操作:基础文件读写(结合Python内置open函数)。 三、界面设计与实现步骤 我们采用“先搭框架,再填功能”的思路,分3步实现: 搭建主窗口与布局(垂直布局+水平布局组合); 添加控件(功能按钮、复选框、文本编辑区)并绑定布局; 实现控件信号与槽绑定,编写功能逻辑。 四、完整代码实现(可直接运行) mjr0a9z8.png图片 import sys import os from PyQt5.QtWidgets import ( QApplication, QWidget, QPushButton, QTextEdit, QCheckBox, QVBoxLayout, QHBoxLayout, QFileDialog ) from PyQt5.QtGui import QFont from PyQt5.QtCore import Qt class SimpleNotepad(QWidget): def __init__(self): super().__init__() # 初始化窗口基础属性 self.init_window() # 初始化控件与布局结构 self.init_widgets_layout() # 绑定信号与槽函数 self.init_signals_slots() # 记录当前打开的文件路径,初始为None表示新文件 self.current_file_path = None def init_window(self): """初始化窗口的标题、大小和位置""" self.setWindowTitle("简易文本编辑器(仿照记事本)") # 设置窗口初始尺寸 self.resize(800, 600) # 计算并设置窗口居中显示 screen_geometry = QApplication.desktop().availableGeometry() x = (screen_geometry.width() - self.width()) // 2 y = (screen_geometry.height() - self.height()) // 2 self.move(x, y) def init_widgets_layout(self): """创建所有界面控件并设置布局""" # 创建主垂直布局,设置控件间距和窗口内边距 self.main_layout = QVBoxLayout() self.main_layout.setSpacing(10) self.main_layout.setContentsMargins(15, 15, 15, 15) # 创建按钮区水平布局 self.button_layout = QHBoxLayout() self.button_layout.setSpacing(10) # 创建功能按钮并设置固定尺寸 self.new_btn = QPushButton("新建") self.open_btn = QPushButton("打开") self.save_btn = QPushButton("保存") btn_size = (80, 30) self.new_btn.setFixedSize(*btn_size) self.open_btn.setFixedSize(*btn_size) self.save_btn.setFixedSize(*btn_size) # 创建字体加粗复选框,设置文本居中显示 self.bold_check = QCheckBox("字体加粗") self.bold_check.setStyleSheet("text-align: center;") # 将按钮添加到水平布局 self.button_layout.addWidget(self.new_btn) self.button_layout.addWidget(self.open_btn) self.button_layout.addWidget(self.save_btn) # 添加伸缩项,将复选框推至布局右侧 self.button_layout.addStretch() self.button_layout.addWidget(self.bold_check) # 创建文本编辑区域,设置默认字体和占位提示文本 self.text_edit = QTextEdit() self.text_edit.setFont(QFont("微软雅黑", 12)) self.text_edit.setPlaceholderText("请输入文本内容...(支持新建、打开、保存文件)") # 将按钮布局和文本编辑区添加到主布局 self.main_layout.addLayout(self.button_layout) self.main_layout.addWidget(self.text_edit) # 设置窗口的主布局 self.setLayout(self.main_layout) def init_signals_slots(self): """绑定控件的信号与对应的槽函数""" self.new_btn.clicked.connect(self.on_new_click) self.open_btn.clicked.connect(self.on_open_click) self.save_btn.clicked.connect(self.on_save_click) self.bold_check.stateChanged.connect(self.on_bold_check_change) def on_new_click(self): """新建文件:清空编辑区,重置文件路径""" # 若有未保存内容,先提示保存 if self.text_edit.toPlainText() and not self.current_file_path: reply = QFileDialog.getSaveFileName(self, "保存当前内容", "", "Text Files (*.txt)") if reply[0]: self.save_text_to_file(reply[0]) # 清空编辑区内容 self.text_edit.clear() # 重置当前文件路径 self.current_file_path = None # 更新窗口标题 self.setWindowTitle("简易文本编辑器(仿照记事本)- 未保存文件") def on_open_click(self): """打开文件:选择txt文件并读取内容到编辑区""" # 弹出文件选择对话框,筛选文本文件 file_path, _ = QFileDialog.getOpenFileName( self, "打开文本文件", "", "Text Files (*.txt);;All Files (*.*)" ) # 验证文件路径有效性并读取内容 if file_path and os.path.exists(file_path): with open(file_path, "r", encoding="utf-8") as f: content = f.read() self.text_edit.setText(content) self.current_file_path = file_path # 更新窗口标题显示当前文件名 self.setWindowTitle(f"简易文本编辑器(仿照记事本)- {os.path.basename(file_path)}") def on_save_click(self): """保存文件:已有路径则直接保存,无路径则弹出保存对话框""" if self.current_file_path: # 直接保存到当前路径 self.save_text_to_file(self.current_file_path) else: # 弹出保存对话框选择路径 file_path, _ = QFileDialog.getSaveFileName( self, "保存文本文件", "", "Text Files (*.txt)" ) if file_path: # 自动补充txt后缀 if not file_path.endswith(".txt"): file_path += ".txt" self.save_text_to_file(file_path) self.current_file_path = file_path self.setWindowTitle(f"简易文本编辑器(仿照记事本)- {os.path.basename(file_path)}") def save_text_to_file(self, file_path): """将编辑区内容写入指定路径的文件""" content = self.text_edit.toPlainText() with open(file_path, "w", encoding="utf-8") as f: f.write(content) def on_bold_check_change(self, state): """根据复选框状态切换编辑区文本的加粗样式""" current_font = self.text_edit.font() # Qt.Checked对应值为2,Qt.Unchecked对应值为0 current_font.setBold(state == Qt.Checked) self.text_edit.setFont(current_font) if __name__ == "__main__": # 创建应用程序实例 app = QApplication(sys.argv) # 创建记事本窗口实例 notepad = SimpleNotepad() # 显示窗口 notepad.show() # 启动应用程序主循环 sys.exit(app.exec_())五、代码逐行解析(核心部分) 1. 类结构与初始化流程 我们将所有功能封装到SimpleNotepad类(继承QWidget),初始化流程分3步: init_window():设置窗口标题、大小、居中显示,提升用户体验; init_widgets_layout():核心布局搭建,用“垂直布局+水平布局”组合实现记事本风格,按钮区在上、编辑区在下,保证窗口缩放时编辑区自适应; init_signals_slots():绑定所有控件的信号与槽,实现“点击按钮触发功能”“复选框变化触发字体调整”。 2. 布局核心逻辑 采用“嵌套布局”思路,解决控件排列问题: 主布局(QVBoxLayout):垂直方向排列“按钮布局”和“文本编辑区”,addStretch()未使用,让编辑区占满剩余空间; 按钮布局(QHBoxLayout):水平方向排列3个功能按钮,添加addStretch()伸缩空间将“字体加粗”复选框推到右侧,让布局更美观。 3. 核心功能实现 (1)新建文件(on_new_click) 逻辑:先判断当前是否有未保存的内容,如果有则弹出保存对话框;清空编辑区,重置current_file_path(标记为新文件),更新窗口标题。 (2)打开文件(on_open_click) 逻辑:用QFileDialog.getOpenFileName()弹出文件选择框,筛选txt文件;读取选中文件的内容并显示到QTextEdit,更新current_file_path和窗口标题(显示文件名)。 (3)保存文件(on_save_click) 逻辑:如果已打开文件(current_file_path不为None),直接保存;否则弹出保存对话框,让用户选择路径,补充.txt后缀,保存内容后更新路径和标题。 (4)字体加粗(on_bold_check_change) 逻辑:监听复选框状态变化,用QFont.setBold()切换字体加粗状态,直接作用于QTextEdit的当前字体。 六、运行效果与测试步骤 1. 运行方式 将代码保存为simple_notepad.py,确保已安装PyQt5,终端运行命令: python simple_notepad.py # Windows python3 simple_notepad.py # macOS/Linux2. 测试步骤 测试新建:点击“新建”,编辑区清空,标题显示“未保存文件”; 测试打开:点击“打开”,选择本地txt文件,内容正常显示,标题显示文件名; 测试保存:编辑内容后点击“保存”,如果是新文件则弹出保存对话框,保存后可在对应路径找到txt文件; 测试字体加粗:勾选“字体加粗”,编辑区文本变为加粗;取消勾选则恢复正常。 七、常见问题排查 问题1:打开文件后中文乱码 → 解决:读取文件时指定encoding="utf-8",保存时也用utf-8编码; 问题2:窗口缩放时编辑区不自适应 → 解决:确保主布局是QVBoxLayout,且QTextEdit直接添加到主布局(未设置固定大小); 问题3:保存文件后没有.txt后缀 → 解决:代码中已添加判断,自动补充.txt后缀,无需手动输入; 问题4:按钮点击无反应 → 解决:检查信号与槽绑定是否正确(如self.new_btn.clicked.connect(self.on_new_click)是否写错函数名)。 八、功能拓展思路(阶段一知识点范围内) 如果想进一步练习,可以基于当前代码拓展以下功能: 添加“撤销/重做”按钮:利用QTextEdit.undo()和QTextEdit.redo()实现; 添加“清空”按钮:绑定self.text_edit.clear(); 添加“字体大小调整”:用QComboBox下拉选择字体大小,绑定信号修改QFont的setPointSize(); 添加“换行/不换行”复选框:用QTextEdit.setLineWrapMode()控制换行模式。 总结 本次项目完美整合了阶段一的核心知识点:窗口设置、线性布局、基础控件使用、信号与槽绑定。通过仿照记事本界面开发,你应该能深刻理解“布局管理器解决控件排列”“信号与槽实现交互”的核心逻辑。 下一篇我们将进入阶段二,学习网格布局、表单布局等进阶布局管理器,为更复杂的界面开发打基础。如果在项目实操中遇到问题,或者有拓展功能的想法,欢迎在评论区留言讨论~ -
PyQt5常用控件(二):复选框单选框下拉框 PyQt5常用基础控件(二):复选框、单选框与下拉框 哈喽~ 欢迎来到PyQt5从入门到精通的第四篇!上一篇我们掌握了标签、按钮、输入框这三个核心基础控件,这一篇聚焦进阶基础控件——QCheckBox复选框、QRadioButton单选框、QComboBox下拉框,这三类控件是“选择类交互”的核心(比如选择性别、爱好、职业),全程代码完整可直接运行,还会做一个“个人信息选择”综合案例,新手也能轻松掌握! mjqzsti2.png图片 一、核心控件详解:每个控件的用法+完整代码 这三类控件的核心作用是让用户做选择,但适用场景不同:单选框(二选一/多选一)、复选框(多选多)、下拉框(大量选项的精简选择),我们逐个拆解。 1. QCheckBox:复选框(多选多) QCheckBox用于允许多选的场景(比如选择爱好:读书、运动、听歌),支持“选中/未选中”状态,还能监听状态变化。 完整代码:QCheckBox常用用法 mjqzttv2.png图片 import sys from PyQt5.QtWidgets import ( QApplication, QWidget, QCheckBox, QVBoxLayout, QLabel, QPushButton ) from PyQt5.QtCore import Qt class CheckBoxDemo(QWidget): def __init__(self): super().__init__() self.init_ui() def init_ui(self): self.setWindowTitle("QCheckBox复选框演示") self.resize(350, 250) layout = QVBoxLayout() layout.setSpacing(15) layout.setContentsMargins(50, 40, 50, 40) # 提示标签 self.tip_label = QLabel("请选择你的爱好(可多选):") layout.addWidget(self.tip_label) # 1. 创建复选框 self.check1 = QCheckBox("读书") self.check2 = QCheckBox("运动") self.check3 = QCheckBox("听歌") self.check4 = QCheckBox("编程") # 可选:设置默认选中状态 self.check4.setChecked(True) # 绑定状态变化信号(选中/取消选中时触发) self.check1.stateChanged.connect(self.on_check_change) self.check2.stateChanged.connect(self.on_check_change) self.check3.stateChanged.connect(self.on_check_change) self.check4.stateChanged.connect(self.on_check_change) # 添加到布局 layout.addWidget(self.check1) layout.addWidget(self.check2) layout.addWidget(self.check3) layout.addWidget(self.check4) # 按钮:获取选中的爱好 get_btn = QPushButton("获取选中的爱好") get_btn.clicked.connect(self.get_checked_hobbies) layout.addWidget(get_btn) # 结果显示标签 self.result_label = QLabel("已选中:编程") layout.addWidget(self.result_label) self.setLayout(layout) # 复选框状态变化槽函数 def on_check_change(self, state): # state:2=选中,0=未选中 sender = self.sender() # 获取触发信号的复选框 if state == Qt.Checked: print(f"选中了:{sender.text()}") else: print(f"取消选中:{sender.text()}") # 获取所有选中的爱好 def get_checked_hobbies(self): hobbies = [] if self.check1.isChecked(): hobbies.append(self.check1.text()) if self.check2.isChecked(): hobbies.append(self.check2.text()) if self.check3.isChecked(): hobbies.append(self.check3.text()) if self.check4.isChecked(): hobbies.append(self.check4.text()) if hobbies: self.result_label.setText(f"已选中:{', '.join(hobbies)}") else: self.result_label.setText("未选中任何爱好") if __name__ == "__main__": app = QApplication(sys.argv) window = CheckBoxDemo() window.show() sys.exit(app.exec_())QCheckBox关键方法解析 方法作用setChecked(True)设置默认选中状态(False为未选中)isChecked()判断是否选中(返回True/False)stateChanged.connect(槽函数)监听状态变化(选中/取消选中)text()获取复选框的文本内容sender()在槽函数中获取触发信号的控件(区分多个复选框)2. QRadioButton:单选框(多选一) QRadioButton用于只能选一个的场景(比如性别:男/女),核心是必须分组(QButtonGroup),否则多个单选框不会互斥(能同时选中)。 完整代码:QRadioButton常用用法 mjqzusvk.png图片 import sys from PyQt5.QtWidgets import ( QApplication, QWidget, QRadioButton, QVBoxLayout, QLabel, QPushButton, QButtonGroup ) class RadioButtonDemo(QWidget): def __init__(self): super().__init__() self.init_ui() def init_ui(self): self.setWindowTitle("QRadioButton单选框演示") self.resize(350, 200) layout = QVBoxLayout() layout.setSpacing(15) layout.setContentsMargins(50, 40, 50, 40) # 提示标签 self.tip_label = QLabel("请选择你的性别(只能选一个):") layout.addWidget(self.tip_label) # 1. 创建单选框分组(核心!否则单选框不互斥) self.radio_group = QButtonGroup(self) # 2. 创建单选框 self.radio1 = QRadioButton("男") self.radio2 = QRadioButton("女") self.radio3 = QRadioButton("保密") # 3. 将单选框加入分组 self.radio_group.addButton(self.radio1, 1) # 第二个参数是自定义ID,可选 self.radio_group.addButton(self.radio2, 2) self.radio_group.addButton(self.radio3, 3) # 可选:设置默认选中 self.radio3.setChecked(True) # 绑定选中变化信号 self.radio_group.buttonClicked.connect(self.on_radio_click) # 添加到布局 layout.addWidget(self.radio1) layout.addWidget(self.radio2) layout.addWidget(self.radio3) # 按钮:获取选中的性别 get_btn = QPushButton("获取选中的性别") get_btn.clicked.connect(self.get_checked_gender) layout.addWidget(get_btn) # 结果显示标签 self.result_label = QLabel("已选中:保密") layout.addWidget(self.result_label) self.setLayout(layout) # 单选框点击槽函数 def on_radio_click(self, radio_btn): # radio_btn是被点击的单选框对象 print(f"选中了性别:{radio_btn.text()}") # 获取选中的性别 def get_checked_gender(self): # 方式1:通过分组获取选中的按钮 checked_btn = self.radio_group.checkedButton() if checked_btn: self.result_label.setText(f"已选中:{checked_btn.text()}") else: self.result_label.setText("未选中任何性别") # 方式2:逐个判断(不推荐,分组更高效) # if self.radio1.isChecked(): # self.result_label.setText("已选中:男") # elif self.radio2.isChecked(): # self.result_label.setText("已选中:女") # elif self.radio3.isChecked(): # self.result_label.setText("已选中:保密") if __name__ == "__main__": app = QApplication(sys.argv) window = RadioButtonDemo() window.show() sys.exit(app.exec_())QRadioButton关键要点 必须分组:用QButtonGroup管理单选框,否则多个单选框可同时选中; 核心方法: 方法作用QButtonGroup.addButton(单选框, ID)将单选框加入分组radio_group.checkedButton()获取分组中选中的单选框setChecked(True)设置默认选中isChecked()判断是否选中 3. QComboBox:下拉选择框(精简多选一) QComboBox用于选项较多、需要精简界面的场景(比如选择职业、城市),支持下拉展开选择,也能设置可编辑(允许用户输入)。 完整代码:QComboBox常用用法 mjqzvsjb.png图片 import sys from PyQt5.QtWidgets import ( QApplication, QWidget, QComboBox, QVBoxLayout, QLabel, QPushButton ) class ComboBoxDemo(QWidget): def __init__(self): super().__init__() self.init_ui() def init_ui(self): self.setWindowTitle("QComboBox下拉框演示") self.resize(350, 200) layout = QVBoxLayout() layout.setSpacing(15) layout.setContentsMargins(50, 40, 50, 40) # 提示标签 self.tip_label = QLabel("请选择你的职业:") layout.addWidget(self.tip_label) # 1. 创建下拉框 self.combo = QComboBox() # 2. 添加选项(三种方式) # 方式1:逐个添加 self.combo.addItem("学生") self.combo.addItem("程序员") self.combo.addItem("教师") # 方式2:批量添加 self.combo.addItems(["设计师", "医生", "自由职业者"]) # 方式3:添加带自定义数据的选项(文本+值) self.combo.addItem("其他", "other") # 可选设置 self.combo.setCurrentIndex(1) # 设置默认选中第2个选项(索引从0开始) # self.combo.setEditable(True) # 允许用户输入自定义内容 # 绑定选中变化信号 self.combo.currentIndexChanged.connect(self.on_combo_change) # 索引变化 # self.combo.currentTextChanged.connect(self.on_text_change) # 文本变化 layout.addWidget(self.combo) # 按钮:获取选中的职业 get_btn = QPushButton("获取选中的职业") get_btn.clicked.connect(self.get_checked_job) layout.addWidget(get_btn) # 结果显示标签 self.result_label = QLabel("已选中:程序员") layout.addWidget(self.result_label) self.setLayout(layout) # 下拉框索引变化槽函数 def on_combo_change(self, index): # index是选中项的索引 text = self.combo.itemText(index) # 通过索引获取文本 data = self.combo.itemData(index) # 获取自定义数据(没有则返回None) print(f"选中索引:{index},职业:{text},自定义数据:{data}") # # 文本变化槽函数(当setEditable=True时常用) # def on_text_change(self, text): # print(f"选中/输入的职业:{text}") # 获取选中的职业 def get_checked_job(self): # 方式1:获取选中的文本 text = self.combo.currentText() # 方式2:获取选中的索引 index = self.combo.currentIndex() # 方式3:获取自定义数据 data = self.combo.currentData() self.result_label.setText(f"职业:{text}(索引:{index},自定义数据:{data})") if __name__ == "__main__": app = QApplication(sys.argv) window = ComboBoxDemo() window.show() sys.exit(app.exec_())QComboBox关键方法 方法作用addItem("文本", 自定义数据)添加单个选项addItems(["选项1", "选项2"])批量添加选项setCurrentIndex(索引)设置默认选中项(索引从0开始)currentText()获取选中的文本currentIndex()获取选中的索引setEditable(True)允许用户输入自定义内容二、综合案例:个人信息选择窗口(完整代码) 结合复选框、单选框、下拉框,做一个实用的“个人信息填写窗口”——包含性别单选、爱好复选、职业下拉,点击“提交”按钮后显示所有选中的信息,界面美化且逻辑完整。 mjqzxjc5.png图片 import sys from PyQt5.QtWidgets import ( QApplication, QWidget, QLabel, QRadioButton, QCheckBox, QComboBox, QPushButton, QVBoxLayout, QHBoxLayout, QGroupBox, QButtonGroup ) from PyQt5.QtGui import QFont from PyQt5.QtCore import Qt class InfoWindow(QWidget): def __init__(self): super().__init__() self.init_ui() def init_ui(self): # 窗口基础设置 self.setWindowTitle("个人信息选择窗口") self.resize(450, 400) self.setStyleSheet(""" QWidget { font-size: 14px; color: #2c3e50; } QGroupBox { font-weight: bold; border: 1px solid #bdc3c7; border-radius: 6px; margin-top: 10px; padding-top: 10px; } QPushButton { background-color: #27ae60; color: white; padding: 8px 16px; border: none; border-radius: 4px; } QPushButton:hover { background-color: #219653; } """) # 主布局(垂直) main_layout = QVBoxLayout() main_layout.setSpacing(20) main_layout.setContentsMargins(40, 30, 40, 30) # 1. 性别分组(QGroupBox美化分组) gender_group = QGroupBox("性别") gender_layout = QHBoxLayout() # 单选框分组 self.gender_btn_group = QButtonGroup() self.radio_male = QRadioButton("男") self.radio_female = QRadioButton("女") self.radio_secret = QRadioButton("保密") self.gender_btn_group.addButton(self.radio_male) self.gender_btn_group.addButton(self.radio_female) self.gender_btn_group.addButton(self.radio_secret) # 默认选中保密 self.radio_secret.setChecked(True) # 添加到性别布局 gender_layout.addWidget(self.radio_male) gender_layout.addWidget(self.radio_female) gender_layout.addWidget(self.radio_secret) gender_group.setLayout(gender_layout) main_layout.addWidget(gender_group) # 2. 爱好分组 hobby_group = QGroupBox("爱好(可多选)") hobby_layout = QHBoxLayout() # 复选框 self.check_read = QCheckBox("读书") self.check_sport = QCheckBox("运动") self.check_music = QCheckBox("听歌") self.check_code = QCheckBox("编程") # 添加到爱好布局 hobby_layout.addWidget(self.check_read) hobby_layout.addWidget(self.check_sport) hobby_layout.addWidget(self.check_music) hobby_layout.addWidget(self.check_code) hobby_group.setLayout(hobby_layout) main_layout.addWidget(hobby_group) # 3. 职业分组 job_group = QGroupBox("职业") job_layout = QHBoxLayout() # 下拉框 self.combo_job = QComboBox() self.combo_job.addItems(["学生", "程序员", "教师", "设计师", "医生", "其他"]) job_layout.addWidget(QLabel("选择:")) job_layout.addWidget(self.combo_job) job_group.setLayout(job_layout) main_layout.addWidget(job_group) # 4. 提交按钮 submit_btn = QPushButton("提交信息") submit_btn.clicked.connect(self.submit_info) main_layout.addWidget(submit_btn, alignment=Qt.AlignCenter) # 5. 结果显示标签 self.result_label = QLabel("") self.result_label.setStyleSheet("color: #e67e22; margin-top: 10px;") self.result_label.setAlignment(Qt.AlignCenter) main_layout.addWidget(self.result_label) # 绑定主布局 self.setLayout(main_layout) # 提交信息槽函数 def submit_info(self): # 1. 获取性别 gender = self.gender_btn_group.checkedButton().text() # 2. 获取爱好 hobbies = [] if self.check_read.isChecked(): hobbies.append(self.check_read.text()) if self.check_sport.isChecked(): hobbies.append(self.check_sport.text()) if self.check_music.isChecked(): hobbies.append(self.check_music.text()) if self.check_code.isChecked(): hobbies.append(self.check_code.text()) hobby_text = ", ".join(hobbies) if hobbies else "无" # 3. 获取职业 job = self.combo_job.currentText() # 4. 显示结果 result = f""" 提交的信息: 性别:{gender} 爱好:{hobby_text} 职业:{job} """ self.result_label.setText(result) if __name__ == "__main__": app = QApplication(sys.argv) window = InfoWindow() window.show() sys.exit(app.exec_())综合案例亮点 用QGroupBox对控件分组,界面更规整、易读; 结合了三类选择控件,覆盖“单选、多选、下拉选”所有常用选择场景; 加入样式美化(按钮悬停、分组边框、字体颜色); 逻辑完整:提交后整合所有选中信息并显示,新手可直接复用。 三、常见问题排查 单选框不互斥: 未使用QButtonGroup分组,只需将所有单选框加入同一个分组即可; 分组时误将单选框加入不同分组(比如创建了多个QButtonGroup)。 复选框无法获取选中状态: 槽函数中未正确调用isChecked(),或控件实例名写错(比如check1写成check_1); 复选框被禁用(setDisabled(True)),导致无法选中。 下拉框选项不显示: 忘记调用addItem()/addItems()添加选项; 下拉框尺寸太小(可通过setMinimumWidth(100)设置最小宽度)。 提交后结果不显示: 槽函数未绑定到按钮的clicked信号; 结果标签被布局遮挡(可调整setContentsMargins或spacing)。 总结 三类选择控件的核心场景:QRadioButton(单选)、QCheckBox(多选)、QComboBox(精简单选); 单选框必须用QButtonGroup分组,否则无法实现互斥; 复选框通过isChecked()判断状态,下拉框通过currentText()获取选中内容; 实际开发中用QGroupBox分组控件,可提升界面可读性; 下一篇我们会讲解阶段一实战项目:仿照记事本界面开发简易文本编辑器,记得关注字节曜博客哦~ 如果在实操中遇到问题,欢迎在评论区留言讨论! -
PyQt5常用控件(一):标签按钮输入框+信号与槽入门(完整代码) PyQt5常用基础控件(一):标签、按钮与输入框+信号与槽入门(附完整代码) 哈喽~ 欢迎来到PyQt5从入门到精通的第三篇!上一篇我们搞定了QWidget窗口属性和线性布局,这一篇聚焦最常用的3个基础控件(QLabel标签、QPushButton按钮、QLineEdit输入框),再加上PyQt5交互的核心——信号与槽(Signal & Slot) 基础,手把手教你实现控件之间的互动,全程代码完整可直接运行,新手也能轻松拿捏! mjqzambw.png图片 一、核心控件详解:每个控件的用法+完整代码 这三个控件是PyQt5开发中最基础也最常用的,几乎所有桌面应用都会用到(比如登录窗口的用户名输入框、确认按钮、提示标签)。我们逐个拆解,先讲用法,再上代码,最后看效果。 1. QLabel:标签控件(显示文本/图片) QLabel的核心作用是显示内容,支持文本、图片、超链接等,是界面中的“信息展示员”。 完整代码:QLabel常用用法 import sys from PyQt5.QtWidgets import QApplication, QWidget, QLabel, QVBoxLayout from PyQt5.QtGui import QPixmap, QFont from PyQt5.QtCore import Qt class LabelDemo(QWidget): def __init__(self): super().__init__() self.init_ui() def init_ui(self): self.setWindowTitle("QLabel标签控件演示") self.resize(400, 350) # 创建布局(垂直布局,让控件从上到下排列) layout = QVBoxLayout() # 1. 显示普通文本 label1 = QLabel("这是普通文本标签") # 设置文本居中对齐 label1.setAlignment(Qt.AlignCenter) layout.addWidget(label1) # 2. 显示带样式的文本(字体大小、颜色) label2 = QLabel("这是带样式的文本") # 用StyleSheet设置样式(类似CSS) label2.setStyleSheet("font-size: 16px; color: #e74c3c; font-weight: bold;") label2.setAlignment(Qt.AlignCenter) layout.addWidget(label2) # 3. 显示图片(替换为你的图片路径,支持png/jpg等格式) label3 = QLabel() # 加载图片并缩放(保持比例) pixmap = QPixmap("test.png") # 图片放在代码同目录,直接写文件名 label3.setPixmap(pixmap.scaled(200, 200, Qt.KeepAspectRatio)) label3.setAlignment(Qt.AlignCenter) # 图片居中 layout.addWidget(label3) # 4. 显示超链接(可点击跳转) label4 = QLabel('<a href="https://www.ziyeyao.com">点击访问字节曜博客</a>') label4.setAlignment(Qt.AlignCenter) label4.setOpenExternalLinks(True) # 允许打开外部链接 layout.addWidget(label4) # 绑定布局到窗口 self.setLayout(layout) if __name__ == "__main__": app = QApplication(sys.argv) window = LabelDemo() window.show() sys.exit(app.exec_())mjqxgqbv.png图片 QLabel关键方法解析 方法作用setAlignment(Qt.AlignCenter)设置内容对齐(居中/左对齐/右对齐)setStyleSheet("样式")自定义样式(字体、颜色、背景等)setPixmap(QPixmap("图片路径"))显示图片,scaled() 用于缩放图片setOpenExternalLinks(True)启用超链接点击跳转2. QPushButton:按钮控件(触发交互) QPushButton是交互核心控件,用户点击按钮后会触发特定操作(比如登录、保存、关闭窗口),必须结合“信号与槽”使用才能实现交互。 完整代码:QPushButton常用用法+信号与槽基础 import sys from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QVBoxLayout, QLabel from PyQt5.QtCore import Qt class ButtonDemo(QWidget): def __init__(self): super().__init__() self.init_ui() def init_ui(self): self.setWindowTitle("QPushButton按钮控件演示") self.resize(300, 200) layout = QVBoxLayout() # 创建标签(用于显示按钮点击状态) self.status_label = QLabel("未点击按钮", alignment=Qt.AlignCenter) layout.addWidget(self.status_label) # 1. 普通按钮 btn1 = QPushButton("普通按钮") # 绑定信号与槽:按钮点击(信号)→ 执行on_btn1_click函数(槽) btn1.clicked.connect(self.on_btn1_click) layout.addWidget(btn1) # 2. 带图标+文本的按钮(图标路径替换为你的文件) btn2 = QPushButton("带图标按钮") btn2.setIcon(QPixmap("icon.png").scaled(20, 20, Qt.KeepAspectRatio)) btn2.clicked.connect(self.on_btn2_click) layout.addWidget(btn2) # 3. 禁用状态的按钮(无法点击) btn3 = QPushButton("禁用按钮") btn3.setDisabled(True) # 禁用按钮 layout.addWidget(btn3) self.setLayout(layout) # 槽函数:btn1点击后执行 def on_btn1_click(self): self.status_label.setText("点击了普通按钮!") self.status_label.setStyleSheet("color: #2ecc71;") # 槽函数:btn2点击后执行 def on_btn2_click(self): self.status_label.setText("点击了带图标按钮!") self.status_label.setStyleSheet("color: #3498db;") if __name__ == "__main__": app = QApplication(sys.argv) window = ButtonDemo() window.show() sys.exit(app.exec_())mjqz3lir.png图片 关键解析:信号与槽(核心!) 信号(Signal):控件的某个动作(比如按钮点击clicked、输入框内容变化textChanged); 槽(Slot):信号触发后执行的函数(比如on_btn1_click); 绑定方式:控件.信号.connect(槽函数),这是PyQt5交互的核心逻辑,记住这个公式! QPushButton关键方法 方法作用clicked.connect(槽函数)绑定点击信号与槽函数setIcon(QPixmap("图标路径"))设置按钮图标setDisabled(True)禁用按钮(False为启用)setText("按钮文本")动态修改按钮文本3. QLineEdit:单行输入框(获取用户输入) QLineEdit用于获取用户单行输入(比如用户名、密码、验证码),支持限制输入长度、密码隐藏、提示文本等功能。 完整代码:QLineEdit常用用法 import sys from PyQt5.QtWidgets import QApplication, QWidget, QLineEdit, QVBoxLayout, QLabel, QPushButton class LineEditDemo(QWidget): def __init__(self): super().__init__() self.init_ui() def init_ui(self): self.setWindowTitle("QLineEdit输入框演示") self.resize(350, 250) layout = QVBoxLayout() layout.setSpacing(20) layout.setContentsMargins(50, 50, 50, 50) # 1. 普通输入框(带提示文本) self.edit1 = QLineEdit() self.edit1.setPlaceholderText("请输入用户名(最多10个字符)") self.edit1.setMaxLength(10) # 限制输入长度 layout.addWidget(self.edit1) # 2. 密码输入框(输入内容隐藏) self.edit2 = QLineEdit() self.edit2.setPlaceholderText("请输入密码") self.edit2.setEchoMode(QLineEdit.Password) # 密码隐藏模式 layout.addWidget(self.edit2) # 3. 只读输入框(无法编辑) edit3 = QLineEdit("只读文本,无法修改") edit3.setReadOnly(True) layout.addWidget(edit3) # 按钮:获取输入框内容 btn = QPushButton("获取输入内容") btn.clicked.connect(self.get_input_value) layout.addWidget(btn) # 标签:显示获取到的内容 self.result_label = QLabel("") layout.addWidget(self.result_label) self.setLayout(layout) # 槽函数:获取输入框内容并显示 def get_input_value(self): username = self.edit1.text() # 获取输入框1的内容 password = self.edit2.text() # 获取输入框2的内容 self.result_label.setText(f"用户名:{username},密码:{password}") # 清空输入框(可选) self.edit1.clear() self.edit2.clear() if __name__ == "__main__": app = QApplication(sys.argv) window = LineEditDemo() window.show() sys.exit(app.exec_())mjqz66bs.png图片 QLineEdit关键方法 方法作用setPlaceholderText("提示文本")设置输入提示(未输入时显示)setMaxLength(数字)限制最大输入长度setEchoMode(QLineEdit.Password)密码模式(输入内容显示为圆点)setReadOnly(True)设置为只读(无法编辑)text()获取输入框中的内容clear()清空输入框内容二、综合案例:用户名密码输入验证窗口(完整代码) 结合上面三个控件和信号与槽,做一个实用的“登录验证窗口”——输入用户名和密码后,点击按钮验证是否正确(模拟登录逻辑)。 import sys from PyQt5.QtWidgets import ( QApplication, QWidget, QLabel, QLineEdit, QPushButton, QVBoxLayout, QHBoxLayout ) from PyQt5.QtGui import QFont, QPixmap from PyQt5.QtCore import Qt class LoginWindow(QWidget): def __init__(self): super().__init__() self.init_ui() def init_ui(self): # 窗口基础设置 self.setWindowTitle("模拟登录窗口") self.resize(400, 300) self.setStyleSheet("background-color: #f8f9fa;") # 主布局(垂直布局) main_layout = QVBoxLayout() main_layout.setSpacing(25) main_layout.setContentsMargins(60, 50, 60, 50) # 1. 标题区域(图标+文本) title_layout = QHBoxLayout() # 标题图标 title_icon = QLabel() title_icon.setPixmap(QPixmap("login_icon.png").scaled(30, 30, Qt.KeepAspectRatio)) # 标题文本 title_label = QLabel("用户登录") title_label.setStyleSheet("font-size: 20px; font-weight: bold; color: #2c3e50;") # 添加到标题布局 title_layout.addWidget(title_icon) title_layout.addWidget(title_label) title_layout.setAlignment(Qt.AlignCenter) main_layout.addLayout(title_layout) # 2. 用户名输入区域 user_layout = QHBoxLayout() user_label = QLabel("用户名:") user_label.setStyleSheet("font-size: 14px; color: #34495e;") self.user_edit = QLineEdit() self.user_edit.setPlaceholderText("请输入用户名") self.user_edit.setStyleSheet("padding: 6px; border: 1px solid #bdc3c7; border-radius: 4px;") user_layout.addWidget(user_label) user_layout.addWidget(self.user_edit) main_layout.addLayout(user_layout) # 3. 密码输入区域 pwd_layout = QHBoxLayout() pwd_label = QLabel("密 码:") pwd_label.setStyleSheet("font-size: 14px; color: #34495e;") self.pwd_edit = QLineEdit() self.pwd_edit.setPlaceholderText("请输入密码") self.pwd_edit.setEchoMode(QLineEdit.Password) self.pwd_edit.setStyleSheet("padding: 6px; border: 1px solid #bdc3c7; border-radius: 4px;") pwd_layout.addWidget(pwd_label) pwd_layout.addWidget(self.pwd_edit) main_layout.addLayout(pwd_layout) # 4. 验证结果标签 self.result_label = QLabel("") self.result_label.setAlignment(Qt.AlignCenter) main_layout.addWidget(self.result_label) # 5. 登录按钮 login_btn = QPushButton("登录") login_btn.setStyleSheet(""" background-color: #3498db; color: white; padding: 8px; border: none; border-radius: 4px; font-size: 14px; """) # 鼠标悬停时改变颜色 login_btn.setStyleSheet(""" QPushButton { background-color: #3498db; color: white; padding: 8px; border: none; border-radius: 4px; font-size: 14px; } QPushButton:hover { background-color: #2980b9; } """) login_btn.clicked.connect(self.check_login) main_layout.addWidget(login_btn) # 绑定主布局 self.setLayout(main_layout) # 登录验证槽函数 def check_login(self): # 模拟正确的用户名和密码 correct_user = "admin" correct_pwd = "123456" # 获取用户输入 input_user = self.user_edit.text().strip() # strip()去除前后空格 input_pwd = self.pwd_edit.text().strip() # 验证逻辑 if not input_user or not input_pwd: self.result_label.setText("用户名或密码不能为空!") self.result_label.setStyleSheet("color: #e74c3c; font-size: 12px;") elif input_user == correct_user and input_pwd == correct_pwd: self.result_label.setText("登录成功!") self.result_label.setStyleSheet("color: #2ecc71; font-size: 12px;") else: self.result_label.setText("用户名或密码错误!") self.result_label.setStyleSheet("color: #e74c3c; font-size: 12px;") # 清空密码输入框 self.pwd_edit.clear() if __name__ == "__main__": app = QApplication(sys.argv) window = LoginWindow() window.show() sys.exit(app.exec_())mjqz6yqo.png图片 综合案例亮点 结合了QLabel(标题、提示)、QLineEdit(输入)、QPushButton(登录)三个核心控件; 使用嵌套布局(QVBoxLayout+QHBoxLayout),界面更规整; 加入了样式美化(背景色、边框、按钮悬停效果); 实现了完整的登录验证逻辑(非空判断、正确/错误提示)。 三、常见问题排查 按钮点击后没反应: 忘记绑定clicked.connect(槽函数); 槽函数名称写错(比如on_btn_click写成on_btn_click1); 按钮被设置为禁用状态(setDisabled(True))。 输入框无法获取内容: 没有用text()方法获取内容,或获取的是其他输入框的实例; 输入内容有前后空格,可加strip()方法去除(如self.user_edit.text().strip())。 图片/图标不显示: 图片路径错误(建议放在代码同目录,直接写文件名); 图片尺寸太大,未用scaled()缩放导致超出窗口范围。 样式设置不生效: StyleSheet语法错误(比如少写分号、引号不匹配); 控件样式被布局或父控件样式覆盖,可针对性调整。 总结 三个核心控件的核心用途:QLabel显示、QPushButton触发、QLineEdit输入; 信号与槽是PyQt5交互的核心,记住控件.信号.connect(槽函数)的绑定方式; 实际开发中建议用布局管理器组织控件,配合StyleSheet美化界面; 下一篇我们会讲解复选框、单选框、下拉框等进阶基础控件,以及更复杂的信号与槽用法,记得关注字节曜博客哦~ 如果在实操中遇到问题,欢迎在评论区留言讨论! -
PyQt5核心基础:QWidget窗口属性与线性布局入门 PyQt5核心基础:QWidget基础窗口与布局入门(附完整可运行代码) 哈喽~欢迎来到PyQt5从入门到精通的第二篇!上一篇我们搞定了环境搭建和第一个空白窗口,这一篇我们聚焦QWidget基础窗口的进阶属性和布局管理器入门——解决新手最头疼的“控件位置混乱、窗口缩放后控件错位”问题,全程代码完整可直接运行,新手也能轻松跟上! mjqx9i5t.png图片 一、先回顾:QWidget是什么? QWidget是PyQt5中所有可视化控件的基类(可以理解为“所有窗口/控件的老祖宗”),我们上一篇创建的空白窗口就是QWidget的实例。它不仅能作为独立窗口使用,还能作为其他控件的容器,掌握它的属性设置是PyQt5界面开发的核心基础。 二、QWidget窗口进阶属性设置(完整代码) 上一篇我们只设置了窗口标题、大小、位置,这一节我们拓展更多实用属性:设置窗口图标、固定窗口大小、窗口置顶、自定义背景色、监听关闭事件等,先上完整代码,再逐行解析。 完整代码:QWidget窗口进阶属性 import sys # 导入必要控件:QWidget(窗口)、QApplication(应用)、QIcon(图标) from PyQt5.QtWidgets import QApplication, QWidget from PyQt5.QtGui import QIcon from PyQt5.QtCore import Qt class MyWindow(QWidget): def __init__(self): # 继承QWidget的初始化方法 super().__init__() # 调用自定义的窗口设置方法 self.init_ui() def init_ui(self): # 1. 基础属性(复习) self.setWindowTitle("QWidget进阶窗口") # 窗口标题 self.resize(400, 300) # 初始大小(宽×高) self.move(300, 200) # 初始位置(屏幕坐标:左×上) # 2. 进阶属性:设置窗口图标 # 注意:替换为你本地的图标路径(支持.ico/png/jpg格式) # 新手提示:可先找一张小图片(比如16×16/32×32像素),放在代码同目录下 self.setWindowIcon(QIcon("icon.png")) # 3. 进阶属性:固定窗口大小(禁止用户缩放) # 取消注释以下行,窗口将固定为400×300,无法拖动边缘缩放 # self.setFixedSize(400, 300) # 4. 进阶属性:窗口置顶(始终显示在其他窗口上方) self.setWindowFlags(Qt.WindowStaysOnTopHint) # 5. 进阶属性:设置窗口背景色(浅灰色) self.setStyleSheet("background-color: #f0f0f0;") # 6. 进阶:监听窗口关闭事件(比如关闭前弹出提示) def closeEvent(self, event): # 这里先简单打印提示,后续会讲弹窗提示 print("你点击了关闭按钮!") # 允许窗口关闭(如果想阻止关闭,可调用event.ignore()) event.accept() if __name__ == "__main__": # 创建应用实例 app = QApplication(sys.argv) # 创建自定义窗口实例 window = MyWindow() # 显示窗口 window.show() # 启动主循环 sys.exit(app.exec_())mjqxa0yu.png图片 代码关键解析 类的封装:我们把窗口逻辑封装到MyWindow类中(继承QWidget),这是PyQt5开发的标准写法,便于后续拓展功能; 窗口图标:setWindowIcon(QIcon("图标路径")),新手注意路径要正确(代码和图标同目录可直接写文件名); 固定大小:setFixedSize() 适合不需要缩放的工具窗口,取消注释即可生效; 窗口置顶:Qt.WindowStaysOnTopHint 是Qt的内置常量,实现窗口始终在最上层; 关闭事件:重写closeEvent()方法,可在窗口关闭前执行自定义逻辑(比如保存数据、弹出确认弹窗)。 运行效果 运行代码后,会弹出一个浅灰色、置顶显示、带自定义图标的窗口,关闭窗口时控制台会打印“你点击了关闭按钮!”。 三、布局管理器入门:解决控件排列混乱问题 新手最容易踩的坑:直接用setGeometry()手动设置控件位置,窗口缩放后控件会错位、重叠。PyQt5提供布局管理器自动管理控件位置,核心是: 无需手动设置控件坐标,布局会自动分配空间; 窗口缩放时,控件会按比例自适应。 我们先学最基础的两种线性布局: QVBoxLayout:垂直布局(控件从上到下排列); QHBoxLayout:水平布局(控件从左到右排列)。 完整代码:线性布局实操(带按钮+标签) import sys from PyQt5.QtWidgets import ( QApplication, QWidget, QLabel, QPushButton, QVBoxLayout, QHBoxLayout # 导入布局管理器 ) class LayoutWindow(QWidget): def __init__(self): super().__init__() self.init_ui() def init_ui(self): self.setWindowTitle("线性布局示例") self.resize(400, 300) # 1. 创建控件 label = QLabel("这是一个标签") btn1 = QPushButton("按钮1") btn2 = QPushButton("按钮2") # 2. 方式1:垂直布局(控件从上到下) # 创建垂直布局实例 layout = QVBoxLayout() # 向布局中添加控件(可添加多个) layout.addWidget(label) layout.addWidget(btn1) layout.addWidget(btn2) # 设置布局的间距(控件之间的距离,可选) layout.setSpacing(20) # 设置布局的边距(布局和窗口边缘的距离,可选) layout.setContentsMargins(50, 50, 50, 50) # 2. 方式2:水平布局(控件从左到右) # 取消注释以下代码,替换垂直布局 # layout = QHBoxLayout() # layout.addWidget(label) # layout.addWidget(btn1) # layout.addWidget(btn2) # 3. 将布局设置到窗口上(核心步骤,否则布局不生效) self.setLayout(layout) if __name__ == "__main__": app = QApplication(sys.argv) window = LayoutWindow() window.show() sys.exit(app.exec_())代码关键解析 布局使用三步法: 创建布局实例(QVBoxLayout()/QHBoxLayout()); 用addWidget()向布局中添加控件; 用setLayout()将布局绑定到窗口; 间距/边距设置: setSpacing():控件之间的间距(单位:像素); setContentsMargins(左, 上, 右, 下):布局和窗口边缘的距离; 自适应效果:运行后拖动窗口边缘缩放,控件会自动调整位置,不会错位。 对比:手动布局 vs 布局管理器 如果用手动布局(label.setGeometry(50,50,100,30)),窗口放大后标签和按钮仍停留在原地;而布局管理器会让控件均匀分布在窗口中,这是开发中必须掌握的核心技巧。 四、综合案例:带布局的多功能窗口(完整代码) 结合本节所有知识点,做一个带图标、置顶、垂直布局的完整窗口: import sys from PyQt5.QtWidgets import ( QApplication, QWidget, QLabel, QPushButton, QVBoxLayout ) from PyQt5.QtGui import QIcon from PyQt5.QtCore import Qt class ComprehensiveWindow(QWidget): def __init__(self): super().__init__() self.init_ui() def init_ui(self): # 窗口基础属性 self.setWindowTitle("综合布局窗口") self.setWindowIcon(QIcon("icon.png")) # 替换为你的图标路径 self.setWindowFlags(Qt.WindowStaysOnTopHint) self.resize(400, 300) # 创建控件 title_label = QLabel("PyQt5布局演示") # 设置标签字体大小(简单美化) title_label.setStyleSheet("font-size: 18px; font-weight: bold;") btn_ok = QPushButton("确认") btn_cancel = QPushButton("取消") # 创建垂直布局 layout = QVBoxLayout() layout.addWidget(title_label) layout.addWidget(btn_ok) layout.addWidget(btn_cancel) layout.setSpacing(30) layout.setContentsMargins(80, 80, 80, 80) # 绑定布局 self.setLayout(layout) def closeEvent(self, event): print("窗口即将关闭!") event.accept() if __name__ == "__main__": app = QApplication(sys.argv) window = ComprehensiveWindow() window.show() sys.exit(app.exec_())运行效果:一个置顶的窗口,内部有大号标题标签和两个按钮,垂直排列且间距均匀,窗口缩放时控件自动适配。 mjqxbt56.png图片 五、常见问题排查 布局不生效:忘记调用setLayout(),或布局添加控件后未绑定到窗口; 图标不显示:图标路径错误(建议将图标放在代码同目录,直接写文件名); 窗口无法置顶:部分系统(如macOS)对窗口置顶有权限限制,属正常现象; 控件重叠:未使用布局,手动设置的控件坐标重复,优先用布局管理器解决。 总结 QWidget是PyQt5所有控件的基类,掌握setWindowIcon()/setFixedSize()等属性可自定义窗口样式; 布局管理器(QVBoxLayout/QHBoxLayout)是解决控件排列的核心,无需手动设置坐标,支持自适应; PyQt5开发建议封装成类,便于后续拓展功能(如监听事件、添加更多控件)。 下一篇我们会深入讲解PyQt5常用基础控件(标签、按钮、输入框)和信号与槽的核心逻辑,记得关注哦~如果有任何问题,评论区留言讨论!