当前位置: 首页 > news >正文

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_())  # 运行主循环

相关文章:

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、添加菜单栏、工具栏、状态栏 # 创…...

MySQL 索引失效案例:字符集不匹配的隐蔽影响

引言 在 MySQL 数据库世界里,索引失效往往是性能问题的罪魁祸首。你是否曾遇到过这样的情况:明明加了索引,查询却慢如蜗牛?你是否曾以为小表查询就一定高效?本文将揭示一个真实的案例,一个容易被忽视的“隐…...

MySQL中类似PostgreSQL中的string_agg函数--GROUP_CONCAT函数的使用

文章目录 结论:MySQL没有string_agg,但有GROUP_CONCATGROUP_CONCAT函数的基本用法示例注意事项 系统变量 group_concat_max_len 如何查看和设置查看当前的group_concat_max_len值设置group_concat_max_len值 相关源码相关链接 结论:MySQL没有…...

科普:数据血缘理论中:任务血缘、表血缘、字段血缘

在讨论数据血缘时通常我们提到的是数据库血缘、数据表血缘和数据字段血缘,而“任务血缘”这一术语更多是在特定技术场景(如实时任务运维)中使用。 数据血缘分类 表血缘 表血缘(或数据表血缘)是指数据在不同数据表之…...

凸性相关问题

内容大致上包括: 四边形不等式,决策单调性闵可夫斯基和优化 d p dp dpslope trick 优化 d p dp dp其他凸性相关问题 决策单调性 1.1 一些约定 对于 n m n\times m nm 的矩阵 A A A,定义: 子矩阵 A [ i 1 , . . . , i p …...

WPS计算机二级•文档的文本样式与编号

听说这是目录哦 标题级别❤️新建文本样式 快速套用格式🩷设置标题样式 自定义设置多级编号🧡使用自动编号💛取消自动编号💚设置 页面边框💙添加水印🩵排版技巧怎么分栏💜添加空白下划线&#x…...

开源堡垒机 JumpServer 社区版实战教程:一步步构建企业安全运维环境

文章目录 开源堡垒机 JumpServer 社区版实战教程:一步步构建企业安全运维环境一、访问JumpServer1.1 登录1.2 功能模块1.3 系统设置1.3.1 基本设置1.3.2 邮件设置 二、用户管理2.1 场景2.2 创建用户2.3 用户登录密码重置 三、资产管理3.1 准备工作3.2 登录控制台3.3…...

二、数据类型、运算符

1. 数据的表示详解 1.1 算术运算符 整数在计算机中的存储原理先从最基本的算术运算符开始学习,算术运算符有 - * / % ,其中*表示乘法,/表示除法,%表示取余数 需要我们注意以下几点 /: 两个整数相除,结果也是一个…...

结构形模式---桥接模式

概念 桥接模式是一种结构化模式,是将一个大类或者一系列的紧密相关的类拆分为抽象和现实两个独立部分的层次结构,通过引用独立层次对象的组合实现类。 桥接模式可以将庞杂类拆分为几个类层次结构。 此后, 你可以修改任意一个类层次结构而不…...

计算机网络知识速记:HTTP1.0和HTTP1.1

计算机网络知识速记:HTTP1.0和HTTP1.1 1. 基本概念 1.1 HTTP1.0 HTTP1.0是1996年发布的第一个正式版本,主要用于客户端与服务器之间的简单请求和响应交互。它的设计理念相对简单,适合处理一些基本的网页服务。 1.2 HTTP1.1 HTTP1.1是HTT…...

Windows下查看WIFI密码

目录 命令行查看历史WIFI netsh wlan show profiles 命令行查看某一特定WIFI密码 netsh wlan show profile name “WIFI名” keyclear 打开命令行https://blog.csdn.net/weixin_70822378/article/details/145598560?spm1001.2014.3001.5502 命令行查看历史WIFI nets…...

Android车机DIY开发之软件篇(十二) AOSP12下载编译

Android车机DIY开发之软件篇(十二) AOSP12下载编译 sudo apt-get update sudo apt-get install git-core gnupg flex bison gperf build-essential zip curl zlib1g-dev gcc-multilib gmultilib libc6-dev-i386 lib32ncurses5-dev libx11-dev lib32z-dev ccache libgl1-mesa-…...

Datawhale Ollama教程笔记2

本期学习易错点: 改文件后缀 改了models的存储地址后,把下载和新建的文件存储在什么地方 注册hugging face,找到token. 学习手册:https://datawhalechina.github.io/handy-ollama/#/ 第 3 章 自定义导入模型https://datawhalechina.gith…...

ClickHouse的前世今生

ClickHouse是一款由Yandex开发的高性能列式存储数据库管理系统,专为在线分析处理(OLAP)设计,适用于实时数据分析、大规模数据处理和复杂查询场景。以下是关于ClickHouse的安装、使用及应用场景的详细介绍: 一、ClickHouse的安装 ClickHouse支持多种操作系统,包括Linux、…...

SSH隧道+Nginx:绿色通道详解(SSH Tunnel+nginx: Green Channel Detailed Explanation)

SSH隧道Nginx:内网资源访问的绿色通道 问题背景 模拟生产环境,使用两层Nginx做反向代理,请求公网IP来访问内网服务器的网站。通过ssh隧道反向代理来实现,重点分析一下nginx反代的基础配置。 实验环境 1、启动内网服务器的tomca…...

html文件怎么转换成pdf文件,2025最新教程

将HTML文件转换成PDF文件,可以采取以下几种方法: 一、使用浏览器内置功能 打开HTML文件:在Chrome、Firefox、IE等浏览器中打开需要转换的HTML文件。打印对话框:按下CtrlP(Windows)或CommandP(M…...

大促备战中稳定性建设策略与总结

文章目录 接口流量评估、上下游依赖梳理降级能力建设应急响应预案建设压力测试监控报警建设容灾演练 之前也专门写过日常稳定性建设的一些策略,传送门 -> 日常稳定性建设策略与总结,本文想专门聊聊大促期间做的一些稳定性保障,顺便记录自己…...

vscode/cursor+godot C#中使用socketIO

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

Uniapp 原生组件层级过高问题及解决方案

文章目录 一、引言🏅二、问题描述📌三、问题原因❓四、解决方案💯4.1 使用 cover-view 和 cover-image4.2 使用 subNVue 子窗体4.3 动态隐藏原生组件4.4 使用 v-if 或 v-show 控制组件显示4.5 使用 position: fixed 布局 五、总结&#x1f38…...

jQuery介绍(快速、简洁JavaScript库,诞生于2006年,主要目标是简化HTML文档操作、事件处理、动画和Ajax交互)

文章目录 **核心功能 & 亮点**1. **简化 DOM 操作**2. **链式调用**3. **跨浏览器兼容**4. **便捷的事件绑定**5. **Ajax 封装**6. **动画效果** **现状与适用场景**- **传统项目维护**:许多旧系统(如 WordPress 插件、老企业网站)仍依赖…...

第三节 docker基础之---Commit+Dockerfile制作

docker目前镜像的制作两种方法: 1,基于docker Commit制作镜像 2,基于dockerfile制作镜像,Dockerfile 为主流的制作方式 如果不制作镜像删除容器之后则里面配置的文件也随之删除: [rootdocker ~]# docker images 查看…...

通过openresty和lua实现随机壁纸

效果: 图片存放路径: /home/jobs/webs/imgs/ ├── default/ │ ├── image1.jpg │ ├── image2.png ├── cats/ │ ├── cat1.jpg │ ├── cat2.gif ├── dogs/ │ ├── dog1.jpg访问http://demo.com/imgs/default 随机返回…...

企业网站如何快速实现全站HTTPS安全访问?

当用户访问您的网站时,若您的企业网站仍以HTTP协议运行,浏览器“不安全”警告不仅会吓退潜在客户,还会拖累搜索引擎排名,直接影响业务转化和品牌声誉。实现全站HTTPS安全访问,已成为企业网站运营的必选项。 本文为您详…...

《花未眠》夜间四时醒来,海棠花未眠

《花未眠》夜间四时醒来,海棠花未眠 川端康成(1899-1972)日本作家。新感觉派。1968年以“敏锐的感受,高超的叙事技巧,表现日本人的精神实质”获诺贝尔文学奖。诺贝尔文学奖提名作有《雪国》《千羽鹤》《古都》。 陈德文…...

在nodejs中使用RabbitMQ(三)Routing、Topics、Headers

示例一、Routing exchange类型direct,根据消息的routekey将消息直接转发到指定队列。producer.ts 生产者主要发送消息,consumer.ts负责接收消息,同时也都可以创建exchange交换机,创建队列,为队列绑定exchange&#xff…...

kubeconfig存放内容有哪些

kubeconfig 文件是 Kubernetes 用于配置和认证的核心文件。它包含了关于如何访问 Kubernetes 集群的信息。以下是 kubeconfig 文件中常见的一些内容结构: apiVersion: 指定 kubeconfig 的版本,通常是 v1。clusters: 定义了集群的信息,包括集…...

图神经网络是什么,有什么实际应用

图神经网络是什么 图神经网络(Graph Neural Network,GNN)是一种专门用于处理图结构数据的神经网络,它能对图中的节点、边和整个图进行学习和推理,在社交网络分析、生物信息学、推荐系统等领域应用广泛。以下是其原理及示例说明: 图神经网络原理 节点表示学习:为图中每…...

如何将DeepSeek配置到离线电脑(内网)中?— 附Ollama夸克下载链接

1、在外网和内网电脑中分别安装Ollama 如下载速度较慢,安装包附在本文最后。 下载完成后傻瓜一键安装即可。 2、下载deepseek 在外网电脑中启动命令行输入下载命令。以下载8B为例,其他版本同。 ollama run deepseek-r1:8b 3、资源转移 在外网电脑…...

拯救者Y9000P双系统ubuntu22.04安装4070显卡驱动

拯救者Y9000P双系统ubuntu22.04安装4070显卡驱动 1. 前情: 1TB的硬盘,分了120G作ubuntu22.04。/boot: 300MB, / : 40GB, /home: 75G, 其余作swap area。 2. 一开始按这个教程:对我无效 https://blog.csdn.net/Eric_xkk/article/details/1…...

vue项目 Axios创建拦截器

Axios 1. Axios 和 Ajax 简介2. Axios 和 Ajax 的区别3. 从 按钮 到 Axios请求后端接口的 大致顺序 1. Axios 和 Ajax 简介 Ajax(Asynchronous JavaScript and XML) 不是一种技术,而是一个编程技术概念,核心是通过 XMLHttpReques…...

web前端第三次作业

题目 本期作业 WEB第三次作业 请使用JS实一个网页中登录窗口的显示/隐藏&#xff0c;页面中拖动移动&#xff0c;并且添加了边界判断的网页效 代码图片 效果展示 代码 <!DOCTYPE html> <html lang"zh"> <head> <meta charset"UTF-8&qu…...

滑动窗口算法笔记(C++)

滑动窗口算法是一种基于双指针技巧的高效算法, 常用于解决数组或字符串上的一些特定问题. 算法讲解 基本概念 滑动窗口算法可以想象成在一个数组或字符串上有一个固定大小或者可变大小的窗口, 该窗口在数组或字符串上从左到右滑动. 在滑动的过程中, 根据具体问题的要求, 对窗…...

day02冒泡排序

思路&#xff1a; 外层循环控制循环次数(i<len)&#xff0c;设置swapFlagfalse内层循环j1(j<len-i)&#xff0c;两两(j和j-1)比较&#xff0c;逆序则交换内层每次循环结束&#xff0c;没有交换&#xff0c;则break结束 内层循环j从1开始&#xff0c;小于len&#xff0c;…...

【工业场景】用YOLOv8实现火灾识别

火灾识别任务是工业领域急需关注的重点安全事项,其应用场景和背景意义主要体现在以下几个方面: 应用场景:工业场所:在工厂、仓库等工业场所中,火灾是造成重大财产损失和人员伤亡的主要原因之一。利用火灾识别技术可以及时发现火灾迹象,采取相应的应急措施,保障人员安全和…...

管式超滤膜分离技术都可以应用到哪些行业?

管式超滤膜分离技术由于其高效、稳定和适应性强的特点&#xff0c;在多个行业都有广泛的应用&#xff1a; 1. 生物制药与医药行业 纯化与浓缩&#xff1a;在生物药品的下游处理阶段&#xff0c;管式超滤膜被用来纯化抗体、疫苗、蛋白质等生物大分子&#xff0c;通过精确筛选分子…...

数智百问 | 制造企业如何降低产线检测数据的存储和管理成本?

在《“十四五”智能制造发展规划》等政策的推动下&#xff0c;以及新能源汽车、消费电子等品牌商对产品质量和供应商智能化水平要求的提升&#xff0c;半导体、电子制造、动力电池等先进制造行业企业纷纷推进产线智能化升级&#xff0c;并投入大量机器视觉检测设备以实现自动化…...

Linux中getifaddrs函数

文章目录 **函数原型****参数****返回值****释放资源****`struct ifaddrs` 结构****示例代码****输出示例****相关函数****总结**getifaddrs 是 Linux(以及其他 Unix-like 系统)中用于获取本机网络接口信息的系统调用。它提供了一种简单的方法来获取所有网络接口的地址信息,…...

Barra多因子模型

Barra模型 1. Barra模型概述1.1 Barra模型的历史与发展1.2 Barra模型在全球市场中的应用 2. Barra模型的基本原理2.1 APT理论基础2.2 Barra模型的基本原理&#xff1a;因子模型的核心假设因子暴露 β i j \beta_{ij} βij​的假设因子收益率 f j f_j fj​的假设 3. Barra模型的…...

P5:使用pytorch实现运动鞋识别

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊 我的环境 语言环境&#xff1a;python 3.7.12 编译器&#xff1a;pycharm 深度学习环境&#xff1a;tensorflow 2.7.0 数据&#xff1a;本地数据集-运动鞋 一…...

redis持久化原理相关面试题剖析

一、Redis 持久化的机制是什么&#xff1f; Redis是内存数据库&#xff0c;数据都是存储在内存中&#xff0c;为了避免进程退出导致数据的永久丢失&#xff0c;需要定期将Redis中的数据以某种形式(数据或命令)从内存保存到硬盘&#xff1b;当下次 Redis重启时&#xff0c;利用…...

动态规划LeetCode-1049.最后一块石头的重量Ⅱ

有一堆石头&#xff0c;用整数数组 stones 表示。其中 stones[i] 表示第 i 块石头的重量。 每一回合&#xff0c;从中选出任意两块石头&#xff0c;然后将它们一起粉碎。假设石头的重量分别为 x 和 y&#xff0c;且 x < y。那么粉碎的可能结果如下&#xff1a; 如果 x y&…...

Linux Media 子系统 V4l2

一 创建 V4l2 的 entity 在Linux内核的Media Controller框架中&#xff0c;V4L2设备作为实体&#xff08;entity&#xff09;的注册过程涉及以下步骤&#xff1a; 1. 初始化Media Controller结构 驱动首先创建一个media_device实例&#xff0c;并与V4L2设备&#xff08;如v4…...

民兵装备管理系统DW-S300|支持国产化、自主研发

民兵装备器材管理系统&#xff08;智装备DW-S301&#xff09;是一套成熟系统&#xff0c;依托互3D技术、云计算、大数据、RFID技术、数据库技术、AI、视频分析技术对RFID智能仓库进行统一管理、分析的信息化、智能化、规范化的系统。 装备接收与登记 民兵装备抵达仓库时&#…...

Pro Git --(Windows)总结

Pro Git --Windows 文章目录 Pro Git --Windows知识来源Git入门与进阶 知识来源 廖雪峰的官方网站 Git教程 Git入门与进阶 # 初步学习Git #个人建议先大致过一遍&#xff0c;对Git有个大致的理解&#xff0c;然后在实操项目# 创建一个空目录 $ mkdir learngit $ cd learngit …...

加油口,电梯门的对称性对 TCP/IP 传输协议的启示

春节期间河南穷游屡次加油站排队加油之启示。 不考虑有意的设计因素&#xff0c;汽车加油口概率性分布在车身的左边或者右边&#xff0c;这个偶然的小细节让加油机同时为两辆车加油而无需额外的加油管。 如果所有车辆加油口都在同一侧&#xff0c;加油站的加油机就只能给一边的…...

【进阶】JVM篇

为什么学习jvm 1、面试的需要 学过java的程序员对jvm应该不陌生&#xff0c;程序员为什么要学习jvm呢&#xff1f;其实不懂jvm也可以照样写出优质的代码&#xff0c;但是不懂jvm会被大厂的面试官虐的体无完肤。 2、高级程序员需要了解 jvm作用 jvm负责把编译后的字节码转换…...

【安全靶场】信息收集靶场

靶场&#xff1a;https://app.hackinghub.io/hubs/prison-hack 信息收集 子域名收集 1.subfinder files.jabprisons.com staging.jabprisons.com cobrowse.jabprisons.com a1.top.jabprisons.com cf1.jabprisons.com va.cobrowse.jabprisons.com vs.jabprisons.com c…...

新数据结构(4)——Java继承

基本概念 继承的本质&#xff1a;重复使用已经定义好的方法和域&#xff0c;实现代码的重复利用。 使用继承之后&#xff0c;创建的子类可以方便地调用父类中已经定义的方法。 一个继承的例子&#xff1a; 重载和重写 重载 重载&#xff1a;发生在同一个类里&#xff0c;指…...

大数据学习之SparkStreaming、PB级百战出行网约车项目一

一.SparkStreaming 163.SparkStreaming概述 Spark Streaming is an extension of the core Spark API that enables scalable, high-throughput, fault-tolerant stream processing of live data streams. Spark Streaming 是核心 Spark API 的扩展&#xff0c;支持实时数据…...

介绍两个个电池充电管理芯片(TP4057、ME4069)

第一个是TP4057。 输入电压是4~6.5V TP4056&#xff0c;它们之间最大的区别就是TP4056最高是1A的充电电流&#xff0c;而TP4057是500ma&#xff0c;适用于更小一点的电池。 TP4057停机模式的静态电流也更小&#xff08;上图列的是待机模式&#xff0c;但查看后面的表格发现实际…...