MVC(Model-View-Controller)framework using Python ,Tkinter and SQLite

1.项目结构

sql:

CREATE TABLE IF NOT EXISTS School (SchoolId TEXT not null,  SchoolName TEXT NOT NULL,SchoolTelNo TEXT NOT NULL)

整体思路

  • Model:负责与 SQLite 数据库进行交互,包括创建表、插入、删除、更新和查询数据等操作。
  • View:使用 Tkinter 和 ttk.Treeview 创建用户界面,包含输入框、按钮和分页控件,用于显示数据并处理用户的交互。
  • Controller:处理用户界面的事件,调用 Model 中的方法进行数据操作,并更新 View 中的显示。

代码实现:

Model 部分


# encoding: utf-8
# 版权所有 2024 ©涂聚文有限公司
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:
# Author    : geovindu,Geovin Du 涂聚文.
# IDE       : PyCharm 2023.1 python 3.11
# OS        : windows 10
# database  : mysql 9.0 sql server 2019, poostgreSQL 17.0  oracle 11g sqlite
# Datetime  : 2024-11-20 22:35:21
# database  :sql server 2019
# User      : geovindu
# Product   : PyCharm
# Project   : pySQLiteMvcDemo
# File      : bll/School.py
# explain   : 学习
from __future__ import annotations
from abc import ABC, abstractmethod
import os
import sys
from Model.school import SchoolInfo
from Factory.AbstractFactory import AbstractFactoryclass SchoolBll(object):"""学校表                    """ dal = AbstractFactory.createSchool"""类属性 接口DAL"""def __init__(self):""""""self.__name = "SchoolBll"self.createtable()  # 如果不存在,初始化表def __del__(self):""":return:"""print(f"{self.__name} ERASE MEMORY")def Close(cls):"""关闭:return:"""cls.dal().Close()def createtable(self):"""建表"""self.dal().createtable()def selectData(self) -> list:""":return:"""data = self.dal().selectSql()return datadef select(self) -> list[SchoolInfo]:""":return:"""schools = []data = self.dal().selectSql()if len(data) > 0:for SchoolId,SchoolName,SchoolTelNo in data[0]:info = SchoolInfo()info.SchoolId = SchoolIdinfo.SchoolName = SchoolNameinfo.SchoolTelNo = SchoolTelNoschools.append(info)return schoolsdef selectSql(cls) -> list[SchoolInfo]:"""元组数据:return: list 列表"""schools = []data = cls.dal().selectSql()if len(data) > 0:for SchoolId,SchoolName,SchoolTelNo in data[0]:info=SchoolInfo()info.SchoolId = SchoolIdinfo.SchoolName = SchoolNameinfo.SchoolTelNo = SchoolTelNoschools.append(info)return schoolsdef selectSqlCount(cls) -> int:"""查询数据 总数:return:"""#print(cls.dal().selectSqlCount()[0][0])total = cls.dal().selectSqlCount()[0][0]return totaldef Count(self) -> int:"""查询数据 总数:return:"""total = self.dal().selectSqlCount()[0][0]return totaldef getcount(cls, search_query=""):"""计算:param search_query::return:"""return cls.dal().getcount(search_query)def getschools(cls, page, limit, search_query=""):"""查询:param page::param limit::param search_query::return:"""data=cls.dal().getschools(page, limit, search_query)print("data:",data)return datadef selectSqlOrder(cls, order: str) -> list[SchoolInfo]:"""元组数据:param order: SchoolName desc/asc:return:"""schools = []data = cls.dal().selectSqlOrder(order)if len(data) > 0:for SchoolId,SchoolName,SchoolTelNo in data[0]:info=SchoolInfo()info.SchoolId = SchoolIdinfo.SchoolName = SchoolNameinfo.SchoolTelNo = SchoolTelNoschools.append(info)return schoolsdef selectSort(cls,field:str,isOrder:bool)->list[SchoolInfo]:""":param field SchoolId:param order:  desc/asc:return:"""schools = []data = cls.dal().selectSort(field,isOrder)if len(data) > 0:for SchoolId,SchoolName,SchoolTelNo in data[0]:info = SchoolInfo()info.SchoolId = SchoolIdinfo.SchoolName = SchoolNameinfo.SchoolTelNo = SchoolTelNoschools.append(info)return schoolsdef selectIdSql(cls,SchoolId:str) -> list[SchoolInfo]:""":param SchoolId:ID:return:"""schools = []data = cls.dal().selectIdSql(SchoolId)#print(data)if len(data)>0:for SchoolId,SchoolName,SchoolTelNo in data[0]:info = SchoolInfo()info.SchoolId = SchoolIdinfo.SchoolName = SchoolNameinfo.SchoolTelNo = SchoolTelNoschools.append(info)return schoolsdef addSql(cls,info:SchoolInfo) -> int:""":param info:实体类:return:"""return cls.dal().addSql(info)def add(self,info:SchoolInfo) -> int:""":param info:实体类:return:"""return self.dal().addSql(info)def editSql(cls,info:SchoolInfo) -> int:""":param info:实体类:return:"""#print(info)return cls.dal().editSql(info)def edit(self,info:SchoolInfo) -> int:""":param info:实体类:return:"""#print(info)return self.dal().editSql(info)def delSql(cls, SchoolId: str) -> int:""":param SchoolId::return:"""return cls.dal().delSql(SchoolId)def delinfo(self, SchoolId: str) -> int:""":param SchoolId::return:"""return self.dal().delSql(SchoolId)

View 部分

# encoding: utf-8
# 版权所有 2025 ©涂聚文有限公司
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:
# Author    : geovindu,Geovin Du 涂聚文.
# IDE       : PyCharm 2023.1 python 3.11
# OS        : windows 10
# database  : mysql 9.0 sql server 2019, poostgreSQL 17.0  oracle 21c Neo4j sqlite
# Datetime  : 2025/2/11 20:37
# User      : geovindu
# Product   : PyCharm
# Project   : pySQLiteMvcDemo
# File      : ViewUI/SchoolView.py
# explain   : 学习import tkinter as tk
from tkinter import ttk, messagebox
import sqlite3
from Model.school import SchoolInfoclass SchoolView(tk.Frame):"""View 类:负责创建和管理用户界面"""def __init__(self, master=None):""":param master:"""super().__init__(master)self.master = masterself.pack()self.create_widgets()def create_widgets(self):""":return:"""self.search_frame = tk.Frame(self)self.search_frame.pack(pady=10)# 搜索输入框self.search_label = tk.Label(self.search_frame, text="搜索:")#self.search_label.pack()self.search_label.grid(row=0, column=0)self.search_entry = tk.Entry(self.search_frame)#self.search_entry.pack()self.search_entry.grid(row=0, column=1)# 搜索按钮self.search_button = tk.Button(self.search_frame, text="搜索")#self.search_button.pack()self.search_button.grid(row=0, column=2)self.tree_frame = tk.Frame(self)self.tree_frame.pack(pady=10)# Treeview 控件self.tree = ttk.Treeview(self.tree_frame, columns=('ID', '校名', '电话'), show='headings')self.tree.heading('ID', text='ID')self.tree.heading('校名', text='校名')self.tree.heading('电话', text='电话')self.tree.pack()# Pagination Frameself.pagination_frame = tk.Frame(self)self.pagination_frame.pack(pady=10)# 分页控件self.prev_button = tk.Button(self.pagination_frame, text="上一页")self.prev_button.pack(side=tk.LEFT)self.page_label = tk.Label(self.pagination_frame, text="第 1 页")self.page_label.pack(side=tk.LEFT)self.pagetotal_label = tk.Label(self.pagination_frame, text="/共 1 条")self.pagetotal_label.pack(side=tk.LEFT)self.next_button = tk.Button(self.pagination_frame, text="下一页")self.next_button.pack(side=tk.LEFT)# Add/Update/Delete Frameself.action_frame = tk.Frame(self)self.action_frame.pack(pady=10)self.id_label = tk.Label(self.action_frame, text="編號:")#self.id_label.pack()self.id_label.grid(row=0, column=0)self.id_entry = tk.Entry(self.action_frame)self.id_entry.grid(row=0, column=1)# 校名输入框self.name_label = tk.Label(self.action_frame, text="校名:")self.name_label.grid(row=1, column=0)self.name_entry = tk.Entry(self.action_frame)self.name_entry.grid(row=1, column=1)# 电话输入框self.phone_label = tk.Label(self.action_frame, text="电话:")self.phone_label.grid(row=2, column=0)self.phone_entry = tk.Entry(self.action_frame)self.phone_entry.grid(row=2, column=1)# 添加按钮self.add_button = tk.Button(self.action_frame, text="添加")self.add_button.grid(row=3, column=0)# 修改按钮self.update_button = tk.Button(self.action_frame, text="修改")self.update_button.grid(row=3, column=1)# 删除按钮self.delete_button = tk.Button(self.action_frame, text="删除")self.delete_button.grid(row=3, column=2)def clear_entries(self):""":return:"""self.id_entry.delete(0, tk.END)self.name_entry.delete(0, tk.END)self.phone_entry.delete(0, tk.END)self.search_entry.delete(0, tk.END)def populate_treeview(self, contacts):""":param contacts::return:"""for i in self.tree.get_children():self.tree.delete(i)for contact in contacts:self.tree.insert('', 'end', values=contact)def update_page_label(self, page, total_pages):""":param page::param total_pages::return:"""self.page_label.config(text=f"第 {page} 页/共 {total_pages} 页")def update_page_total(self,tatal):""":param tatal::return:"""self.pagetotal_label.config(text=f"共{tatal} 条")class AddSchoolWindow(tk.Toplevel):"""弹出窗口 - 添加学校"""def __init__(self, master, controller):""":param master::param controller:"""super().__init__(master)self.controller = controllerself.title("添加学校")self.create_widgets()def create_widgets(self):""":return:"""self.action_frame = tk.Frame(self)self.action_frame.pack(pady=10)# 学校 ID 输入框self.id_label = tk.Label(self.action_frame, text="学校 ID:")self.id_label.grid(row=0, column=0)self.id_entry = tk.Entry(self.action_frame)self.id_entry.grid(row=0, column=1)# 学校名称输入框self.name_label = tk.Label(self.action_frame, text="学校名称:")self.name_label.grid(row=1, column=0)self.name_entry = tk.Entry(self.action_frame)self.name_entry.grid(row=1, column=1)# 学校电话输入框self.tel_label = tk.Label(self.action_frame, text="学校电话:")self.tel_label.grid(row=2, column=0)self.tel_entry = tk.Entry(self.action_frame)self.tel_entry.grid(row=2, column=1)# 保存按钮self.save_button = tk.Button(self.action_frame, text="保存", command=self.save_school)self.save_button.grid(row=3, column=0)def save_school(self):""":return:"""school_id = self.id_entry.get()school_name = self.name_entry.get()school_tel = self.tel_entry.get()info = SchoolInfo()info.SchoolId = school_idinfo.SchoolName = school_nameinfo.SchoolTelNo = school_telif school_id and school_name and school_tel:self.controller.add_school(info)self.destroy()else:messagebox.showerror("错误", "所有字段均为必填项")class EditSchoolWindow(tk.Toplevel):"""弹出窗口 - 修改学校"""def __init__(self, master, controller, school_id, school_name, school_tel):""":param master::param controller::param school_id::param school_name::param school_tel:"""super().__init__(master)self.controller = controllerself.school_id = school_idself.title("修改学校")self.create_widgets(school_name, school_tel)def create_widgets(self, school_name, school_tel):""":param school_name::param school_tel::return:"""self.action_frame = tk.Frame(self)self.action_frame.pack(pady=10)# 学校 ID 标签(不可编辑)self.id_label = tk.Label(self.action_frame, text="学校 ID:")self.id_label.grid(row=0, column=0)self.id_entry = tk.Entry(self.action_frame)self.id_entry.insert(0, self.school_id)self.id_entry.config(state='readonly')self.id_entry.grid(row=0, column=1)# 学校名称输入框self.name_label = tk.Label(self.action_frame, text="学校名称:")self.name_label.grid(row=1, column=0)self.name_entry = tk.Entry(self.action_frame)self.name_entry.insert(0, school_name)self.name_entry.grid(row=1, column=1)# 学校电话输入框self.tel_label = tk.Label(self.action_frame, text="学校电话:")self.tel_label.grid(row=2, column=0)self.tel_entry = tk.Entry(self.action_frame)self.tel_entry.insert(0, school_tel)self.tel_entry.grid(row=2, column=1)# 保存按钮self.save_button = tk.Button(self.action_frame, text="保存", command=self.save_school)self.save_button.grid(row=3, column=0)def save_school(self):""":return:"""school_name = self.name_entry.get()school_tel = self.tel_entry.get()if school_name and school_tel:print("edit",self.school_id)info=SchoolInfo()info.SchoolId=self.school_idinfo.SchoolName=school_nameinfo.SchoolTelNo=school_tel#self.controller.update_school(self.school_id, school_name, school_tel)self.controller.update_school(info)self.destroy()else:messagebox.showerror("错误", "所有字段均为必填项")

Controller 部分

# encoding: utf-8
# 版权所有 2025 ©涂聚文有限公司
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:
# Author    : geovindu,Geovin Du 涂聚文.
# IDE       : PyCharm 2023.1 python 3.11
# OS        : windows 10
# database  : mysql 9.0 sql server 2019, poostgreSQL 17.0  oracle 21c Neo4j sqlite
# Datetime  : 2025/2/11 20:36
# User      : geovindu
# Product   : PyCharm
# Project   : Controller/pySQLiteMvcDemo
# File      : SchoolController.py
# explain   : 学习
import tkinter as tk
from tkinter import ttk, messagebox
import sqlite3
from Model.school import SchoolInfo
from BLLModel.school import SchoolBll
from ViewUI.SchoolView import AddSchoolWindow
from ViewUI.SchoolView import EditSchoolWindowclass SchoolController(object):"""Controller 类:负责处理用户输入和更新模型和视图"""def __init__(self, model, view):""":param model::param view:"""self.model = SchoolInfo()self.view = viewself.current_page = 1self.limit = 10self.search_query = ""# 绑定按钮点击事件到相应的处理方法self.view.add_button.config(command=self.addschools)#self.view.add_button.config(command=self.open_add_window)self.view.update_button.config(command=self.updateschools)self.view.delete_button.config(command=self.deleteschools)self.view.search_button.config(command=self.searchschools)self.view.prev_button.config(command=self.prev_page)self.view.next_button.config(command=self.next_page)self.view.tree.bind("<Double-1>", self.open_edit_window)self.showschools()self.bll = SchoolBll()def open_add_window(self):""":return:"""AddSchoolWindow(self.view.master, self)def open_edit_window(self, event):""":param event::return:"""selected_item = self.view.tree.selection()if selected_item:values = self.view.tree.item(selected_item)['values']school_id = values[0]school_name = values[1]school_tel = values[2]EditSchoolWindow(self.view.master, self, school_id, school_name, school_tel)def add_school(self, info:SchoolInfo):""":param info::return:"""self.bll.addSql(info)self.show_schools()def delete_school(self):""":return:"""selected_item = self.view.tree.selection()if selected_item:school_id = self.view.tree.item(selected_item)['values'][0]self.bll.delSql(school_id)self.show_schools()else:messagebox.showerror("错误", "请选择要删除的学校")def update_school(self, info):""":param info::return:"""self.bll.editSql(info)self.show_schools()def search_schools(self):""":return:"""self.search_query = self.view.search_entry.get()self.current_page = 1self.show_schools()def show_schools(self):""":return:"""total_count = self.bll.getcount(self.search_query)[0][0]print(total_count)if total_count >= 1:total_pages = (total_count + self.limit - 1) // self.limitcontacts = self.bll.getschools(self.current_page, self.limit, self.search_query)self.view.populate_treeview(contacts)self.view.update_page_label(self.current_page, total_pages)self.view.update_page_total(total_count)def addschools(self):""":return:"""id = self.view.id_entry.get()name = self.view.name_entry.get()phone = self.view.phone_entry.get()self.model.SchoolId=idself.model.SchoolName=nameself.model.SchoolTelNo=phone;if name and phone:self.bll.add(self.model)self.view.clear_entries()self.showschools()else:messagebox.showerror("错误", "校名和电话不能为空")def deleteschools(self):""":return:"""selected_item = self.view.tree.selection()if selected_item:id = str(self.view.tree.item(selected_item)['values'][0])print("id",id)self.bll.delSql(id)self.showschools()else:messagebox.showerror("错误", "请选择要删除的学校")def updateschools(self, event):""":return:"""selected_item = self.view.tree.selection()if selected_item:id = str(self.view.tree.item(selected_item)['values'][0])#values = self.view.tree.item(selected_item)['values']name = self.view.name_entry.get()phone = self.view.phone_entry.get()self.model.SchoolId = idself.model.SchoolName = nameself.model.SchoolTelNo = phoneif name and phone:self.bll.editSql(self.model)self.view.clear_entries()self.showschools()else:messagebox.showerror("错误", "校名和电话不能为空")else:messagebox.showerror("错误", "请选择要修改的学校")def searchschools(self):""":return:"""self.search_query = self.view.search_entry.get()self.current_page = 1self.showschools()def prev_page(self):""":return:"""if self.current_page > 1:self.current_page -= 1self.showschools()def next_page(self):""":return:"""total_count = self.bll.getcount(self.search_query)[0][0]total_pages = (total_count + self.limit - 1) // self.limitif self.current_page < total_pages:self.current_page += 1self.showschools()def showschools(self):""":return:"""bll=SchoolBll()total_count = bll.getcount(self.search_query)[0][0]print(total_count)if total_count >= 1:total_pages = (total_count + self.limit - 1) // self.limitcontacts = bll.getschools(self.current_page, self.limit, self.search_query)self.view.populate_treeview(contacts)self.view.update_page_label(self.current_page, total_pages)self.view.update_page_total(total_count)

调用:

# encoding: utf-8
# 版权所有 2025 ©涂聚文有限公司
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:
# Author    : geovindu,Geovin Du 涂聚文.塗聚文
# IDE       : PyCharm Community Edition 2024.3 python 3.11
# OS        : windows 10
# database  : mysql 9.0 sql server 2019, postgreSQL 17.0  oracle 11g oracle 20c  Neo4j  sqlite
# Datetime  : 2025/2/11 20:11
# User      : geovindu
# Product   : PyCharm
# Project   : pySQLiteMVCDemo
# File      : main.py
# explain   : 学习import tkinter as tk
from tkinter import ttk, messagebox
from BLLModel.school import SchoolBll
from ViewUI.SchoolView import SchoolView
from Controller.SchoolController import SchoolControllerif __name__ == '__main__':""""""root = tk.Tk()bllmodel = SchoolBll()view = SchoolView(master=root)controller = SchoolController(bllmodel, view)root.title("School Management")root.iconbitmap('favicon.ico')root.mainloop()

输出:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/16976.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MongoDB 扩缩容实战:涵盖节点配置、服务启动与移除操作

#作者&#xff1a;任少近 文章目录 一、扩容在245节点上配置配置config server&#xff1a;配置mongos启动config server安装工具mongosh添加245新节点到副本集配置分片副本集启动路由并分片 二、缩容Conf server上去掉server4shard上去掉server4mongos上去掉server4 一、扩容…

AGI时代的认知重塑:人类文明的范式转移与思维革命

文章目录 引言:站在文明转型的临界点一、认知危机:当机器开始理解世界1.1 AGI的本质突破:从模式识别到世界建模1.2 人类认知的脆弱性暴露二、认知革命:重构思维的四个维度2.1 元认知升级:从直觉思维到二阶观察2.2 混合智能:人机认知回路的构建2.3 认知安全:防御机器思维…

Java学习进阶路线

Java基础 Java Web 前端HTML/css/js&#xff0c;J2EE&#xff08;Servlet/jsp&#xff09;&#xff0c;数据库&#xff08;Mysql/oracle&#xff09; Java开发框架 Spring MVC/Mybatis/Herbernate/maven 《Java编程思想》 深入了解java基础 Java设计模式 《Effective j…

cursor接入deepseek

cursor安装 cursor下载地址&#xff1a; https://www.cursor.com/ Cursor为新用户提供14天的免费试ai。在这段时间内&#xff0c;你可以使用所有权限内的功能&#xff0c;并享受500次高级模型的快速请求。 额度用完或到期无法使用ai功能&#xff0c;不影响继续使用软件&#…

vscode/cursor+godot C#中使用socketIO

在 Visual Studio Code(VS Code)中安装 NuGet 包&#xff08;例如SocketIOClient&#xff09;&#xff0c;你可以通过以下几种方法&#xff1a; 方法 1&#xff1a;使用dotnet cli 打开终端&#xff1a;在 VS Code 中按下Ctrl 或者通过菜单View -> Terminal打开终端。 导…

LabVIEW 用户界面设计基础原则

在设计LabVIEW VI的用户界面时&#xff0c;前面板的外观和布局至关重要。良好的设计不仅提升用户体验&#xff0c;还能提升界面的易用性和可操作性。以下是设计用户界面时的一些关键要点&#xff1a; 1. 前面板设计原则 交互性&#xff1a;组合相关的输入控件和显示控件&#x…

git服务器搭建,gitea服务搭建,使用systemclt管理服务

文章目录 页面展示使用二进制文件安装git服务下载选择架构使用wget下载安装 验证 GPG 签名服务器设置准备环境创建systemctl文件 备份与恢复备份命令 (dump)恢复命令 (restore) 页面展示 使用二进制文件安装git服务 所有打包的二进制程序均包含 SQLite&#xff0c;MySQL 和 Po…

Kotlin Lambda

Kotlin Lambda 在探索Kotlin Lambda之前&#xff0c;我们先回顾下Java中的Lambda表达式&#xff0c;Java 的 Lambda 表达式是 Java 8 引入的一项强大的功能&#xff0c;它使得函数式编程风格的代码更加简洁和易于理解。Lambda 表达式允许你以一种更简洁的方式表示实现接口&…

Wpf美化按钮,输入框,下拉框,dataGrid

Wpf美化按钮&#xff0c;输入框&#xff0c;下拉框&#xff0c;dataGrid 引用代码后 引用资源 <ControlTemplate x:Key"CustomProgressBarTemplate" TargetType"ProgressBar"><Grid><Border x:Name"PART_Track" CornerRadius&q…

音视频协议

1. 多媒体信息 1.1 多媒体信息的两个主要特点&#xff1a; 信息量很大 标准语音&#xff1a;64Kbits(8KHz采样&#xff0c;8位编码)高质量音频&#xff1a;3Mbps(100KHz采样&#xff0c;12位编码) 在传输多媒体数据时&#xff0c;对时延和时延抖动均有较高要求 1.2 处理时延…

第一天:爬虫介绍

每天上午9点左右更新一到两篇文章到专栏《Python爬虫训练营》中&#xff0c;对于爬虫有兴趣的伙伴可以订阅专栏一起学习&#xff0c;完全免费。 键盘为桨&#xff0c;代码作帆。这趟为期30天左右的Python爬虫特训即将启航&#xff0c;每日解锁新海域&#xff1a;从Requests库的…

稀土抑烟剂——为汽车火灾安全增添防线

一、稀土抑烟剂的基本概念 稀土抑烟剂是一类基于稀土元素&#xff08;如稀土氧化物和稀土金属化合物&#xff09;开发的高效阻燃材料。它可以显著提高汽车内饰材料的阻燃性能&#xff0c;减少火灾发生时有毒气体和烟雾的产生。稀土抑烟剂不仅能提升火灾时的安全性&#xff0c;…

计算机网络-MPLS转发原理

在上一篇关于 MPLS 基础的文章中&#xff0c;我们了解了 MPLS 的基本概念、术语以及它在网络中的重要性。今天&#xff0c;我们将深入探讨 MPLS 转发的原理与流程&#xff0c;帮助大家更好地理解 MPLS 是如何在实际网络中工作的。 一、MPLS 转发概述 MPLS 转发的本质是将数据…

网络安全 | SNI介绍及F5中的配置应用

关注&#xff1a;CodingTechWork SNI介绍 SNI&#xff08;Server Name Indication&#xff09;是 TLS/SSL 协议中的一个重要扩展&#xff0c;旨在解决同一 IP 地址上托管多个网站时&#xff0c;如何选择正确的 SSL/TLS 证书进行加密通信的问题。SNI 通过在 TLS 握手初期传递客…

ARM Cortex-M3/M4 权威指南 笔记【二】架构

一、架构 1.1 架构简介 Cortex-M3/M4 处理器都基于 ARMv7-M 架构。最初的 ARMv7-M 架构是随着 Cortex-M3 处理器一同引入的&#xff0c;而在 Cortex-M4 发布时&#xff0c;架构中又额外增加了新的指令和特性&#xff0c;改进后的架构有时也被称为 ARMV7E-M。要了解 ARM7-M 和…

LabVIEW软件需求开发文档参考

在项目开发的工作历程中&#xff0c;精准把握项目需求无疑是成功打造整个项目的首要关键步骤&#xff0c;同时也是一个至关重要且不可忽视的核心环节。明确且详尽的项目需求就如同建筑的基石&#xff0c;为后续的设计、开发、测试等一系列工作提供了坚实的支撑和清晰的指引。倘…

Linux内核实时机制x - 中断响应测试 Cyclictest分析1

Linux内核实时机制x - 中断响应测试Cyclitest 1 实时性测试工具 rt-test 1.1 源码下载 1.下载源码&#xff1a; ~/0-code/5.15$ git clone git://git.kernel.org/pub/scm/utils/rt-tests/rt-tests.git 正克隆到 rt-tests... remote: Enumerating objects: 5534, done. remot…

Unity 代码优化记录

文档 unity 代码优化分析&#xff1a;https://docs.unity3d.com/Manual/analysis.html Unity 修复性能问题&#xff1a;https://learn.unity.com/tutorial/fixing-performance-problems-2019-3?courseId5c87de35edbc2a091bdae346#604586d7edbc2a5b4345d249 实例 具体枚举转En…

Arcgis/GeoScene API for JavaScript 三维场景底图网格设为透明

项目场景&#xff1a; 有时候加载的地图服务白色区域会露底&#xff0c;导致在三维场景时&#xff0c;露出了三维网格&#xff0c;影响效果&#xff0c;自此&#xff0c;我们需要将三维场景的底图设为白色或透明。 问题描述 如图所示&#xff1a; 解决方案&#xff1a; 提示…

snort3.0-ubuntu18.04 64入侵检测安装与使用ailx10ailx10​​知乎知识会员

在日常生活中&#xff0c;很多人怀疑自己的手机、电脑被监控了&#xff0c;担心自己的隐私泄漏&#xff0c;实际上最佳的检测方式就是终端检测&#xff0c;也就是EDR&#xff0c;但是就是有那么多的人在网上大放厥词&#xff0c;说任何EDR杀毒软件都检测不到监控&#xff0c;毕…