Python----PyQt开发(PyQt高级:手搓一个简单的记事本)

一、效果展示

二、设计PyQt界面 

2.1、设置图标

self.setWindowIcon(QIcon('./images/icon/1.png'))  # 窗口图标

 

2.2、设置标题

self.file_name = '无标题-新建文本文档'  # 默认文件名
self.setWindowTitle(self.file_name)  # 窗口标题

 

2.3、添加菜单栏、工具栏、状态栏

# 创建菜单栏
self.menu_bar = QMenuBar(self)
self.setMenuBar(self.menu_bar)
# 创建工具栏
self.tool_bar = QToolBar(self)
self.addToolBar(self.tool_bar)
self.tool_bar.addAction(self.new_action)  # 添加新建操作到工具栏
self.tool_bar.addAction(self.newS_action)  # 添加保存操作到工具栏# 创建字体和颜色按钮
self.font_btn = QToolButton(self)  # 字体按钮
self.font_btn.setIcon(QIcon('./images/icon/font.png'))  # 设置图标
self.tool_bar.addWidget(self.font_btn)self.color_btn = QToolButton(self)  # 颜色按钮
self.color_btn.setIcon(QIcon('./images/icon/color.png'))  # 设置图标
self.tool_bar.addWidget(self.color_btn)# 创建文本编辑区
self.text_edit = QTextEdit(self)
self.setCentralWidget(self.text_edit)

2.4、菜单栏中添加菜单

# 创建文件菜单
self.file_menu = QMenu('文件(F)', self)
self.menu_bar.addMenu(self.file_menu)# 创建编辑菜单
self.edit_menu = QMenu('编辑(E)', self)
self.menu_bar.addMenu(self.edit_menu)

 

2.5、菜单栏中的菜单添加动作(选项)

# 为文件菜单创建操作
self.new_action = QAction('新建(N)', self)  # 新建操作
self.new_action.setIcon(QIcon('./images/icon/new.png'))  # 设置图标
self.new_action.setShortcut(QKeySequence.New)  # 设置快捷键
self.file_menu.addAction(self.new_action)  # 添加到文件菜单self.newO_action = QAction('打开(O)', self)  # 打开操作
self.newO_action.setIcon(QIcon('./images/icon/open.png'))  # 设置图标
self.newO_action.setShortcut(QKeySequence.Open)  # 设置快捷键
self.file_menu.addAction(self.newO_action)self.newS_action = QAction('保存(S)', self)  # 保存操作
self.newS_action.setIcon(QIcon('./images/icon/save.png'))  # 设置图标
self.newS_action.setShortcut(QKeySequence.Save)  # 设置快捷键
self.file_menu.addAction(self.newS_action)self.newA_action = QAction('另保存为(A)', self)  # 另存为操作
self.newA_action.setIcon(QIcon('./images/icon/save.png'))  # 设置图标
self.newA_action.setShortcut(QKeySequence.SaveAs)  # 设置快捷键
self.file_menu.addAction(self.newA_action)# 为编辑菜单创建操作
self.newC_action = QAction('复制(C)', self)  # 复制操作
self.newC_action.setIcon(QIcon('./images/icon/copy.png'))  # 设置图标
self.newC_action.setShortcut(QKeySequence.Copy)  # 设置快捷键
self.edit_menu.addAction(self.newC_action)self.newP_action = QAction('粘贴(P)', self)  # 粘贴操作
self.newP_action.setIcon(QIcon('./images/icon/paste.png'))  # 设置图标
self.newP_action.setShortcut(QKeySequence.Paste)  # 设置快捷键
self.edit_menu.addAction(self.newP_action)self.newT_action = QAction('剪辑(T)', self)  # 剪切操作
self.newT_action.setIcon(QIcon('./images/icon/textitalic.png'))  # 设置图标
self.newT_action.setShortcut(QKeySequence.Cut)  # 设置快捷键
self.edit_menu.addAction(self.newT_action)self.newU_action = QAction('撤销(U)', self)  # 撤销操作
self.newU_action.setIcon(QIcon('./images/icon/undo.png'))  # 设置图标
self.newU_action.setShortcut(QKeySequence.Undo)  # 设置快捷键
self.edit_menu.addAction(self.newU_action)self.newR_action = QAction('反撤销(R)', self)  # 反撤销操作
self.newR_action.setIcon(QIcon('./images/icon/dir.png'))  # 设置图标
self.newR_action.setShortcut(QKeySequence.Redo)  # 设置快捷键
self.edit_menu.addAction(self.newR_action)

 

2.6、添加文本编辑区域

# 创建文本编辑区使其设置中心窗口
self.text_edit = QTextEdit(self)
self.setCentralWidget(self.text_edit)

三、菜单栏业务实现 

3.1连接操作与其相应的槽函数

self.new_action.triggered.connect(self.new_action_slot)  # 新建文件
self.newO_action.triggered.connect(self.open_action)  # 打开文件
self.newS_action.triggered.connect(self.save_action_slot)  # 保存文件
self.newA_action.triggered.connect(self.saveAs_action_slot)  # 另存为文件

3.2、连接编辑操作

self.newC_action.triggered.connect(self.text_edit.copy)  # 复制
self.newP_action.triggered.connect(self.text_edit.paste)  # 粘贴
self.newT_action.triggered.connect(self.text_edit.cut)  # 剪切
self.newU_action.triggered.connect(self.text_edit.undo)  # 撤销
self.newR_action.triggered.connect(self.text_edit.redo)  # 反撤销

3.3、新建文件

新建文件这个函数操作的主要逻辑为:

如果当前打开的文件文本内容有被修改:

        弹出消息提示框,是否要对更改进行保存

                保存:

                        如果此时的文件名为 无标题-记事本, 要进行另存为

                        否则:

                                进行保存 (打开原来的文件,把文本框中的内容写入该文件,文件关闭)

                        文本区域清空

                        窗口标题变成了无标题-记事本

                不保存:

                        文本区域清空

                        窗口标题变成了无标题-记事本

                取消:    

                        什么都不做

如果当前打开的文件文本内容没有被修改:

        文本区域清空

        窗口标题变成了无标题-记事本

def new_action_slot(self):# 处理新文件操作rest = self.text_edit.document().isModified()  # 检查文档是否被修改if rest:btn_res = QMessageBox.question(self, '记事本', '是否保存?',QMessageBox.Yes | QMessageBox.No | QMessageBox.Cancel)if btn_res == QMessageBox.Yes:self.save_action_slot()  # 保存文件self.text_edit.clear()  # 清空文本编辑区self.file_name = '无标题记事本'self.setWindowTitle(self.file_name)  # 更新窗口标题elif btn_res == QMessageBox.No:self.text_edit.clear()  # 清空文本编辑区self.file_name = '无标题记事本'self.setWindowTitle(self.file_name)  # 更新窗口标题else:self.text_edit.clear()  # 清空文本编辑区self.file_name = '无标题记事本'self.setWindowTitle(self.file_name)  # 更新窗口标题

3.4、打开文件

如果当前这个文本内容没有做任何修改:

        弹出一个文件选择对话框,选择一个文件并打开,读这个文件的内容,把读到内容设 置到文本编辑框中,文件本身关闭!

        窗口标题变成了打开的这个文件的名字

如果当前这个文本内容有做修改:

        弹出消息对话框,询问是否对修改进行保存。

        保存:  

                如果此时窗口标题为 无标题-记事本

                        进行另存为

                否则:

                        保存

                弹出一个文件选择对话框,选择一个文件并打开,读这个文件的内容,把读到内 容设置到文本编辑框中,文件本身关闭!

                窗口标题变成了打开的这个文件的名字

        不保存:

                弹出一个文件选择对话框,选择一个文件并打开,读这个文件的内容,把读到内 容设置到文本编辑框中,文件本身关闭!

                窗口标题变成了打开的这个文件的名字

        取消:

                说明是误触,什么都不做

def open_action(self):# 处理打开文件操作rest = self.text_edit.document().isModified()if rest:btn_res = QMessageBox.question(self, '记事本', '是否保存?',QMessageBox.Yes | QMessageBox.No | QMessageBox.Cancel)if btn_res == QMessageBox.Yes:self.save_action_slot()  # 保存文件self.open_file()  # 打开文件elif btn_res == QMessageBox.No:self.open_file()  # 打开文件else:self.open_file()  # 直接打开文件
def open_file(self):# 打开文件对话框,选择文件进行打开self.file_path = QFileDialog.getOpenFileName(self, '打开', './', '记事本TXT(*.txt)')[0]print(self.file_path)fs = QFile(self.file_path)  # 创建QFile对象fs.open(QFile.ReadOnly)  # 以只读方式打开文件if fs.isOpen():data = fs.readAll()  # 读取文件内容print(data)self.text_edit.setText(bytearray(data).decode('utf-8'))  # 将内容设置到文本编辑区self.file_name = QFileInfo(self.file_path).fileName()  # 获取文件名self.setWindowTitle(self.file_name)  # 更新窗口标题fs.close()  # 关闭文件else:print('文件未打开')  # 打开失败的提示

3.5、保存文件

如果当前操作的文件 文件名为 无标题-记事本

        进行另存为

否则:

        打开当前的这个文件,获取文本框中的内容,写入到文件中,文件关闭!

        窗口标题变成了当前打开文件的文件字

        修改文本框中的文本状态为 未修改

def save_action_slot(self):# 保存文件操作if self.file_name == '无标题':self.saveAs_action_slot()  # 如果没有文件名,则执行另存为else:fs = QFile(self.file_path)  # 创建QFile对象fs.open(QFile.WriteOnly)  # 以写入方式打开文件if fs.isOpen():text = self.text_edit.toPlainText()  # 获取文本编辑区中的纯文本fs.write(text.encode('utf-8'))  # 写入文件self.file_name = QFileInfo(self.file_path).fileName()  # 更新文件名self.setWindowTitle(self.file_name)  # 更新窗口标题fs.close()  # 关闭文件self.text_edit.document().setModified(False)  # 重置文档修改状态else:print('文件打开失败')  # 写入失败的提示

3.6、文件另存为

根据window中记事本的另存为动作,

分析:

        弹出一个文件选择对话框,输入新保存的文件名字,保存

        打开文件,获取文本框中的内容, 写入文件中, 文件关闭

        窗口标题变成新保存文件的名字!

        修改文本框中的文本状态为 未修改

def saveAs_action_slot(self):# 另存为文件操作self.file_path = QFileDialog.getSaveFileName(self, '另存为', './', '记事本TXT(*.txt)')[0]fs = QFile(self.file_path)  # 创建QFile对象fs.open(QFile.WriteOnly)  # 以写入方式打开文件if fs.isOpen():text = self.text_edit.toPlainText()  # 获取文本编辑区中的纯文本fs.write(text.encode('utf-8'))  # 写入文件self.file_name = QFileInfo(self.file_path).fileName()  # 更新文件名self.setWindowTitle(self.file_name)  # 更新窗口标题fs.close()  # 关闭文件self.text_edit.document().setModified(False)  # 重置文档修改状态else:print('文件另存为失败')  # 另存为失败的提示

3.7 、文本的复制、粘贴、剪切、撤销、恢复

在QTextEdit中查找 都有对应的槽函数 copy()、paste()、cut()、undo()、redo() 

self.newC_action.triggered.connect(self.text_edit.copy)  # 复制
self.newP_action.triggered.connect(self.text_edit.paste)  # 粘贴
self.newT_action.triggered.connect(self.text_edit.cut)  # 剪切
self.newU_action.triggered.connect(self.text_edit.undo)  # 撤销
self.newR_action.triggered.connect(self.text_edit.redo)  # 反撤销

3.8、工具栏业务实现 

def font_slot(self):# 字体选择操作font = QFontDialog.getFont(self)[0]  # 弹出字体选择对话框print(font)self.text_edit.setCurrentFont(font)  # 设置文本编辑区的当前字体def color_slot(self):# 颜色选择操作color = QColorDialog.getColor(QColor(), self)  # 弹出颜色选择对话框self.text_edit.setTextColor(color)  # 设置文本编辑区的文本颜色

四、用到的库函数

QMainWinodw      

        setWindowTitle() 修改窗口标题      

        setWindowIcon() 设置窗口图标      

        setMenuBar()        

        addToolBar()        

        setStatusBar() 设置菜单栏 添加工具栏 设置状态栏      

        setCentralWidget() 设置核心区域

QMenuBar 菜单栏      

        addMenu()   添加菜单

QMenu      

        setTitle() 设置标题      

        addAction() 添加动作

QAction        

        setText()        设置文本

        setIcon()        设置图标

        setShortCut()        设置快捷按键

        triggered()     信号

QToolBar  工具栏      

        addAction()          添加动作

        addWidget()     添加其他控件

QToolButton        工具按钮

        setIcon()        设置图标

        clicked()        点击信号

QStatusBar        状态栏

QTextEdit

        document()文本文档的获取

        toPlainText()内容的获取

        clear()内容的清空

        textChanged()文本修改的内容

        setText()设置内容

QTextDocument

        isModified()是否有被修改

        setModified(bool)修改状态

QMessageBox

        question()询问

QFileDialog

        getOpenFileName() 获取选择打开的文件完整路径名      

        getSaveFileName() 获取另存为的文件的完整路径名

QFile

        open()          打开文件

        isOpened()      是否打开成功

        write()          写数据

        readAll()        读数据

        close()    关闭文件

QFileInfo      

        fileName() 获取文件名 

        

五、完整代码

import sys  
from PyQt5.QtWidgets import QMainWindow, QApplication, QMenuBar, \QMenu, QAction, QToolBar, QToolButton, QTextEdit, \QMessageBox, QFileDialog, QFontDialog, QColorDialog  
from PyQt5.QtGui import QIcon, QKeySequence, QColor  
from PyQt5.QtCore import QFile, QFileInfo  class My_QMW(QMainWindow):  def __init__(self):  super().__init__()  self.file_name = '无标题-新建文本文档'  # 默认文件名  self.file_path = ''  # 当前文件路径  self.ui_init()  # 初始化UI组件  self.solt_init()  # 初始化信号与槽的连接  def ui_init(self):  # 设置主窗口的基本属性  self.setGeometry(700, 300, 1200, 800)  # 窗口位置和大小  self.setWindowTitle(self.file_name)  # 窗口标题  self.setWindowIcon(QIcon('./images/icon/1.png'))  # 窗口图标  # 创建菜单栏  self.menu_bar = QMenuBar(self)  self.setMenuBar(self.menu_bar)  # 创建文件菜单  self.file_menu = QMenu('文件(F)', self)  self.menu_bar.addMenu(self.file_menu)  # 创建编辑菜单  self.edit_menu = QMenu('编辑(E)', self)  self.menu_bar.addMenu(self.edit_menu)  # 为文件菜单创建操作  self.new_action = QAction('新建(N)', self)  # 新建操作  self.new_action.setIcon(QIcon('./images/icon/new.png'))  # 设置图标  self.new_action.setShortcut(QKeySequence.New)  # 设置快捷键  self.file_menu.addAction(self.new_action)  # 添加到文件菜单  self.newO_action = QAction('打开(O)', self)  # 打开操作  self.newO_action.setIcon(QIcon('./images/icon/open.png'))  # 设置图标  self.newO_action.setShortcut(QKeySequence.Open)  # 设置快捷键  self.file_menu.addAction(self.newO_action)  self.newS_action = QAction('保存(S)', self)  # 保存操作  self.newS_action.setIcon(QIcon('./images/icon/save.png'))  # 设置图标  self.newS_action.setShortcut(QKeySequence.Save)  # 设置快捷键  self.file_menu.addAction(self.newS_action)  self.newA_action = QAction('另保存为(A)', self)  # 另存为操作  self.newA_action.setIcon(QIcon('./images/icon/save.png'))  # 设置图标  self.newA_action.setShortcut(QKeySequence.SaveAs)  # 设置快捷键  self.file_menu.addAction(self.newA_action)  # 为编辑菜单创建操作  self.newC_action = QAction('复制(C)', self)  # 复制操作  self.newC_action.setIcon(QIcon('./images/icon/copy.png'))  # 设置图标  self.newC_action.setShortcut(QKeySequence.Copy)  # 设置快捷键  self.edit_menu.addAction(self.newC_action)  self.newP_action = QAction('粘贴(P)', self)  # 粘贴操作  self.newP_action.setIcon(QIcon('./images/icon/paste.png'))  # 设置图标  self.newP_action.setShortcut(QKeySequence.Paste)  # 设置快捷键  self.edit_menu.addAction(self.newP_action)  self.newT_action = QAction('剪辑(T)', self)  # 剪切操作  self.newT_action.setIcon(QIcon('./images/icon/textitalic.png'))  # 设置图标  self.newT_action.setShortcut(QKeySequence.Cut)  # 设置快捷键  self.edit_menu.addAction(self.newT_action)  self.newU_action = QAction('撤销(U)', self)  # 撤销操作  self.newU_action.setIcon(QIcon('./images/icon/undo.png'))  # 设置图标  self.newU_action.setShortcut(QKeySequence.Undo)  # 设置快捷键  self.edit_menu.addAction(self.newU_action)  self.newR_action = QAction('反撤销(R)', self)  # 反撤销操作  self.newR_action.setIcon(QIcon('./images/icon/dir.png'))  # 设置图标  self.newR_action.setShortcut(QKeySequence.Redo)  # 设置快捷键  self.edit_menu.addAction(self.newR_action)  # 创建工具栏并添加操作  self.tool_bar = QToolBar(self)  self.addToolBar(self.tool_bar)  self.tool_bar.addAction(self.new_action)  # 添加新建操作到工具栏  self.tool_bar.addAction(self.newS_action)  # 添加保存操作到工具栏  # 创建字体和颜色按钮  self.font_btn = QToolButton(self)  # 字体按钮  self.font_btn.setIcon(QIcon('./images/icon/font.png'))  # 设置图标  self.tool_bar.addWidget(self.font_btn)  self.color_btn = QToolButton(self)  # 颜色按钮  self.color_btn.setIcon(QIcon('./images/icon/color.png'))  # 设置图标  self.tool_bar.addWidget(self.color_btn)  # 创建文本编辑区  self.text_edit = QTextEdit(self)  self.setCentralWidget(self.text_edit)  def solt_init(self):  # 连接操作与其相应的槽函数  self.new_action.triggered.connect(self.new_action_slot)  # 新建文件  self.newO_action.triggered.connect(self.open_action)  # 打开文件  self.newS_action.triggered.connect(self.save_action_slot)  # 保存文件  self.newA_action.triggered.connect(self.saveAs_action_slot)  # 另存为文件  # 连接编辑操作  self.newC_action.triggered.connect(self.text_edit.copy)  # 复制  self.newP_action.triggered.connect(self.text_edit.paste)  # 粘贴  self.newT_action.triggered.connect(self.text_edit.cut)  # 剪切  self.newU_action.triggered.connect(self.text_edit.undo)  # 撤销  self.newR_action.triggered.connect(self.text_edit.redo)  # 反撤销  self.font_btn.clicked.connect(self.font_slot)  # 字体按钮点击  self.color_btn.clicked.connect(self.color_slot)  # 颜色按钮点击  # 当文本更改时更新窗口标题  self.text_edit.textChanged.connect(self.update_title)  def new_action_slot(self):  # 处理新文件操作  rest = self.text_edit.document().isModified()  # 检查文档是否被修改  if rest:  btn_res = QMessageBox.question(self, '记事本', '是否保存?', QMessageBox.Yes | QMessageBox.No | QMessageBox.Cancel)  if btn_res == QMessageBox.Yes:  self.save_action_slot()  # 保存文件  self.text_edit.clear()  # 清空文本编辑区  self.file_name = '无标题记事本'  self.setWindowTitle(self.file_name)  # 更新窗口标题  elif btn_res == QMessageBox.No:  self.text_edit.clear()  # 清空文本编辑区  self.file_name = '无标题记事本'  self.setWindowTitle(self.file_name)  # 更新窗口标题  else:  self.text_edit.clear()  # 清空文本编辑区  self.file_name = '无标题记事本'  self.setWindowTitle(self.file_name)  # 更新窗口标题  def open_action(self):  # 处理打开文件操作  rest = self.text_edit.document().isModified()  if rest:  btn_res = QMessageBox.question(self, '记事本', '是否保存?', QMessageBox.Yes | QMessageBox.No | QMessageBox.Cancel)  if btn_res == QMessageBox.Yes:  self.save_action_slot()  # 保存文件  self.open_file()  # 打开文件  elif btn_res == QMessageBox.No:  self.open_file()  # 打开文件  else:  self.open_file()  # 直接打开文件  def open_file(self):  # 打开文件对话框,选择文件进行打开  self.file_path = QFileDialog.getOpenFileName(self, '打开', './', '记事本TXT(*.txt)')[0]  print(self.file_path)  fs = QFile(self.file_path)  # 创建QFile对象  fs.open(QFile.ReadOnly)  # 以只读方式打开文件  if fs.isOpen():  data = fs.readAll()  # 读取文件内容  print(data)  self.text_edit.setText(bytearray(data).decode('utf-8'))  # 将内容设置到文本编辑区  self.file_name = QFileInfo(self.file_path).fileName()  # 获取文件名  self.setWindowTitle(self.file_name)  # 更新窗口标题  fs.close()  # 关闭文件  else:  print('文件未打开')  # 打开失败的提示  def save_action_slot(self):  # 保存文件操作  if self.file_name == '无标题':  self.saveAs_action_slot()  # 如果没有文件名,则执行另存为  else:  fs = QFile(self.file_path)  # 创建QFile对象  fs.open(QFile.WriteOnly)  # 以写入方式打开文件  if fs.isOpen():  text = self.text_edit.toPlainText()  # 获取文本编辑区中的纯文本  fs.write(text.encode('utf-8'))  # 写入文件  self.file_name = QFileInfo(self.file_path).fileName()  # 更新文件名  self.setWindowTitle(self.file_name)  # 更新窗口标题  fs.close()  # 关闭文件  self.text_edit.document().setModified(False)  # 重置文档修改状态  else:  print('文件打开失败')  # 写入失败的提示  def saveAs_action_slot(self):  # 另存为文件操作  self.file_path = QFileDialog.getSaveFileName(self, '另存为', './', '记事本TXT(*.txt)')[0]  fs = QFile(self.file_path)  # 创建QFile对象  fs.open(QFile.WriteOnly)  # 以写入方式打开文件  if fs.isOpen():  text = self.text_edit.toPlainText()  # 获取文本编辑区中的纯文本  fs.write(text.encode('utf-8'))  # 写入文件  self.file_name = QFileInfo(self.file_path).fileName()  # 更新文件名  self.setWindowTitle(self.file_name)  # 更新窗口标题  fs.close()  # 关闭文件  self.text_edit.document().setModified(False)  # 重置文档修改状态  else:  print('文件另存为失败')  # 另存为失败的提示  def font_slot(self):  # 字体选择操作  font = QFontDialog.getFont(self)[0]  # 弹出字体选择对话框  print(font)  self.text_edit.setCurrentFont(font)  # 设置文本编辑区的当前字体  def color_slot(self):  # 颜色选择操作  color = QColorDialog.getColor(QColor(), self)  # 弹出颜色选择对话框  self.text_edit.setTextColor(color)  # 设置文本编辑区的文本颜色  def update_title(self):  # 文本更改时更新窗口标题  self.setWindowTitle('*' + self.file_name)  # 在标题前添加*表示文档被修改过  if __name__ == '__main__':  app = QApplication(sys.argv)  # 创建应用程序  windows = My_QMW()  # 创建主窗口实例  windows.show()  # 显示主窗口  sys.exit(app.exec_())  # 运行主循环

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

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

相关文章

Java 大视界 -- 大数据伦理与法律:Java 技术在合规中的作用与挑战(87)

💖亲爱的朋友们,热烈欢迎来到 青云交的博客!能与诸位在此相逢,我倍感荣幸。在这飞速更迭的时代,我们都渴望一方心灵净土,而 我的博客 正是这样温暖的所在。这里为你呈上趣味与实用兼具的知识,也…

什么是AI Agent、Chat、RAG、MoE

什么是AI Agent、Chat、RAG、MoE 目录 什么是AI Agent、Chat、RAG、MoE定义与原理功能特点应用场景AI Agent有哪些关键组成部分感知模块决策模块知识模块行动模块学习模块AI Agent、Chat、RAG、MoE是人工智能领域中不同的概念和技术,它们在功能、原理和应用等方面存在一些区别…

在 debian 12 上安装 mysqlclient 报错

报错如下 Looking in indexes: https://pypi.tuna.tsinghua.edu.cn/simple Collecting mysqlclientUsing cached https://pypi.tuna.tsinghua.edu.cn/packages/61/68/810093cb579daae426794bbd9d88aa830fae296e85172d18cb0f0e5dd4bc/mysqlclient-2.2.7.tar.gz (91 kB)Installi…

自反馈与流量震荡:从 TCP/IP 路由到交通导航

为什么不能基于流量或时延做路由度量,而不仅仅基于跳数。原因在于这里存在一个自反馈: 路由决策导致流量变化;时延由流量变化而变化;流量时延影响路由决策。 当某条链路流量减少时,路由协议会将其度量调低&#xff0…

Jtti:centos主机如何搭建lnmp环境

在 CentOS 主机上搭建 LNMP(Linux Nginx MySQL/MariaDB PHP)环境是构建高性能 Web 服务器的常见选择。以下是搭建 LNMP 环境的详细步骤: 步骤 1: 更新系统 首先,更新系统的包列表和安装的包,以确保你的系统是最新的: sudo y…

如果需要保护多个域名怎么办?

随着企业和个人在网上的存在越来越重要,管理和保护多个域名变得尤为关键,那么如果需要保护这些域名,应该采取什么样的措施呢? 许多企业会选择注册与其品牌相关的不同后缀,或者与其产品、服务相关的域名。这不仅可以防…

从Sora到有言:3D视频生成技术的突破与应用

近年来,AIGC领域飞速发展,这个词也越来越高频地出现在了大家的生活中。AIGC 能完成的任务也越来越多,大模型的能力飞速增长 —— 从Deepseek生成文字,到StableDiffusion生成图像,再到Sora可以生成视频。 而现在&#x…

Apollo 9.0 控制算法 -- lon based pid controller

文章目录 1. 纵向控制算法1.1 算法结构1.1.1 外环:位置环1.1.2 内环:速度环 1.2 参数整定 2. 代码解析2.1 控制器初始化 LonController::Init()2.1.1 PID控制参数和标定表参数加载2.1.2 PID控制器初始化2.1.3 超前/滞后控制器初始化2.1.4 俯仰角滤波器初…

【JavaScript】《JavaScript高级程序设计 (第4版) 》笔记-Chapter12-BOM

十二、BOM 虽然 ECMAScript 把浏览器对象模型(BOM,Browser Object Model)描述为 JavaScript 的核心,但实际上 BOM 是使用 JavaScript 开发 Web 应用程序的核心。BOM 提供了与网页无关的浏览器功能对象。 HTML5 规范中有一部分涵盖…

Qt信号槽调用出错:Qt: Dead lock detected while activating a BlockingQueuedConnection

目录 1.现象和原因分析 2. 总结 1.现象和原因分析 就在最近的开发过程中,程序一运行在控制台就打印: Qt: Dead lock detected while activating a BlockingQueuedConnection: 咋一看,怎么出现死锁了呢?仔细看下…

Jenkins项目CICD流程

Jenkins项目流程:1.配置git环境 git config --...2.把前后端的目录初始化位本地工作目录 #git init3.提交到本地git #git add ./ git commit -m "" git tag v14.然后提交到远程git(通过,用户,群组,项目,管理项目)git remote add origin http://...git push -…

Springboot_实战

项目开发 lombok使用 自动为实体类提供get、set、toString方法 引入依赖 实体类上添加注解 统一响应结果 注意要写get、set方法;下面是错误的,因此要加上Data注解 一个注册的接口的示例 Controller层 Service层 Mapper层 参数校验 但是同样存在一…

C++自研游戏引擎-碰撞检测组件-八叉树AABB检测算法实现

八叉树碰撞检测是一种在三维空间中高效处理物体碰撞检测的算法,其原理可以类比为一个管理三维空间物体的智能系统。这个示例包含两个部分:八叉树部分用于宏观检测,AABB用于微观检测。AABB可以更换为均值或节点检测来提高检测精度。 八叉树的…

Spring框架中都用到了哪些设计模式?

大家好,我是锋哥。今天分享关于【Spring框架中都用到了哪些设计模式?】面试题。希望对大家有帮助; Spring框架中都用到了哪些设计模式? 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 Spring框架中使用了大量的设计模…

Day1 25/2/14 FRI

【一周刷爆LeetCode,算法大神左神(左程云)耗时100天打造算法与数据结构基础到高级全家桶教程,直击BTAJ等一线大厂必问算法面试题真题详解(马士兵)】https://www.bilibili.com/video/BV13g41157hK?p3&v…

软考高级《系统架构设计师》知识点(一)

计算机硬件 校验码 码距:就单个编码A:00而言,其码距为1,因为其只需要改变一位就变成另一个编码。在两个编码中,从A码到B码转换所需要改变的位数称为码距,如A:00要转换为B:11,码距为2。一般来说,…

DeepSeek免费部署到WPS或Office

部署到WPS - 通过OfficeAI插件接入: - 准备工作:安装最新版本的WPS Office软件;访问DeepSeek官网,点击右上角的“API开放平台”,登录账号(若无账号需先注册),登录成功后,…

基于vue3实现的课堂点名程序

设计思路 采用vue3实现的课堂点名程序&#xff0c;模拟课堂座位布局&#xff0c;点击开始点名按钮后&#xff0c;一朵鲜花在座位间传递&#xff0c;直到点击结束点名按钮&#xff0c;鲜花停留的座位被点名。 课堂点名 座位组件 seat.vue <script setup>//组合式APIimpo…

C语言的物联网

C语言在物联网中的应用 物联网&#xff08;Internet of Things&#xff0c;IoT&#xff09;是一个通过网络将各种物理设备连接起来的系统&#xff0c;使其能够收集和交换数据。随着技术的进步&#xff0c;物联网已经走入了我们的日常生活&#xff0c;并在智能家居、智能城市、…

数论补充 之 前后缀分解问题

文章目录 [0,i-1] 和 [i1,n-1] 共同作用3334,数组的最大因子得分238.除自身以外数组的乘积 对于前缀分解问题&#xff0c;我愿把它分为几个大问题&#xff1a;[0,i] 或 [i,n-1] 或 [l,r],或 [0,i-1] 和 [i1,n-1] 共同作用的问题 一般都是求解区间的和&#xff0c;乘积&#xff…