十五、【文本编辑器(一)】代码框架

 


目录

一、QMainWindow基本构成

二、项目框架代码

三、菜单与工具栏的实现

四、总结


一、QMainWindow基本构成

        QMainWindow 是一个为用户提供主窗口程序的类,包含一个菜单栏 (menu bar),多个工具栏(tool bars),多个锚接部件 (dock widgets), 一个状态栏 ( status bar ) 及一个中 心部件 ( central widget),是许多应用程序的基础,如文本编辑器、图片编辑器等。

1、菜单栏
        菜单是一系列命令的列表。为了实现菜单、工具栏按钮、键盘快捷方式等命令的一致性,Qt 使用动作(Action)来表示这些命令。Qt 的菜单就是由一系列的 QAction动作对象构成的列表,而菜单栏则是包容菜单的面板,它位于主窗口顶部、主窗口标题栏的下面。一个主窗口最多只有一个菜单栏。

2、状态栏
        状态栏通常显示 GUI 应用程序的一些状态信息,它位于主窗口的最底部。用户可以在状态栏上添加、使用 Qt 窗口部件。一个主窗口最多只有一个状态栏。

3、工具栏
        工具栏是由一系列的类似于按钮的动作排列而成的面板,它通常由一些经常使用的命令(动作)组成。工具栏的位于在菜单栏的下面、状态栏的上面,可以停靠在主窗口的上、下、左、右四个方向上。一个主窗口可以包含多个工具栏。

4、锚接部件
        锚接部件作为一个容器使用,以包容其他窗口部件来实现某些功能。例如,Qt设计器的属性编辑器、对象监视器等都是由锚接部件包容其他的 Qt 窗口部件来实现的。它位于工具栏区的内部,可以作为一个窗口自由地浮动在主窗口上面,也可以像工具栏一样停靠在主窗口的上、下、左、右四个方向上,一个主窗口可以包含多个锚接部件。

5、中心部件
        中心部件处在锚接部件区的内部、主窗口的中心,一个主窗口只有一个中心部件。

        为了控制主窗口工具栏和锚接部件的显隐,在默认情况下,QMainWindow 主窗口提供了一个上下文菜单(Context Menu)。通常,通过在工具栏或锚接部件上单击鼠标右键 就可以激活该上下文 菜单,也 可以通过函数 QMainWindow::createPopupMenu()激活该菜单。此外,还可以重写QMainWindow:createPopupMenu()函数,实现自定义的上下文菜单。

二、项目框架代码

        创建Qt项目时,项目名称为“ImageProcessor”,基类选择“QMainWindow”,类名为“ImgProcessor”,取消“创建界面”复选框的选中状态。工程的文件列表如下图:

 showwidget.h

#ifndef SHOWWIDGET_H
#define SHOWWIDGET_H#include <QWidget>
#include <QLabel>
#include <QTextEdit>
#include <QImage>class ShowWidget : public QWidget
{Q_OBJECT
public:explicit ShowWidget(QWidget *parent = 0);QImage img;                     //图片QLabel *imageLabel;             //放置图片的载体QTextEdit *text;                //文本编辑框
signals:public slots:};#endif // SHOWWIDGET_H

showwidget.cpp

#include "showwidget.h"
#include <QHBoxLayout>
ShowWidget::ShowWidget(QWidget *parent) :QWidget(parent)
{imageLabel =new QLabel;//用于控制图像是否根据控件大小自动缩放imageLabel->setScaledContents(true);// 设置边框样式imageLabel->setStyleSheet("border: 1px solid black;");text =new QTextEdit;//设置布局QHBoxLayout *mainLayout =new QHBoxLayout(this);mainLayout->addWidget(imageLabel,1);mainLayout->addWidget(text,3);
}

imgprocessor.h

#ifndef IMGPROCESSOR_H
#define IMGPROCESSOR_H#include <QMainWindow>
#include <QImage>
#include <QLabel>
#include <QMenu>
#include <QMenuBar>
#include <QAction>
#include <QComboBox>
#include <QSpinBox>
#include <QToolBar>
#include <QFontComboBox>
#include <QToolButton>
#include <QTextCharFormat>
#include "showwidget.h"class ImgProcessor : public QMainWindow
{Q_OBJECTpublic:ImgProcessor(QWidget *parent = 0);~ImgProcessor();void createActions();                        	//创建动作void createMenus();                           	//创建菜单void createToolBars();                      	//创建工具栏void loadFile(QString filename);                //加载文件void mergeFormat(QTextCharFormat);private:QMenu *fileMenu;                           		//各项菜单栏QMenu *zoomMenu;QMenu *rotateMenu;QMenu *mirrorMenu;QImage img;QString fileName;ShowWidget *showWidget;QAction *openFileAction;                     	//文件菜单项QAction *NewFileAction;QAction *PrintTextAction;QAction *PrintImageAction;QAction *exitAction;QAction *copyAction;                          	//编辑菜单项QAction *cutAction;QAction *pasteAction;QAction *aboutAction;QAction *zoomInAction;QAction *zoomOutAction;QAction *rotate90Action;                     	//旋转菜单项QAction *rotate180Action;QAction *rotate270Action;QAction *mirrorVerticalAction;              	//镜像菜单项QAction *mirrorHorizontalAction;QAction *undoAction;QAction *redoAction;QToolBar *fileTool;                          	//工具栏QToolBar *zoomTool;QToolBar *rotateTool;QToolBar *mirrorTool;QToolBar *doToolBar;
};

imgprocessor.cpp

#include "imgprocessor.h"
#include <QFileDialog>
#include <QFile>
#include <QTextStream>
#include <QPrintDialog>
#include <QPrinter>
#include <QPainter>
#include <QColorDialog>
#include <QColor>
#include <QTextList>ImgProcessor::ImgProcessor(QWidget *parent): QMainWindow(parent)
{//设置标题setWindowTitle(tr("Easy Word"));showWidget =new ShowWidget(this);setCentralWidget(showWidget);//创建菜单栏createActions();createMenus();//创建工具栏createToolBars();if(img.load("image.png")){showWidget->imageLabel->setPixmap(QPixmap::fromImage(img));}
}

三、菜单与工具栏的实现

        菜单与工具栏都与 QAction 类密切相关,工具栏上的功能按钮与菜单中的选项条目相对应,完成相同的功能,使用相同的快捷键与图标。QAction 类为用户提供了一个统一的命令接口,无论是从菜单触发还是从工具栏触发,或通过快捷键触发都调用同样的操作接口,以达到同样的目的。

1、动作(Action)的实现

void ImgProcessor::createActions()
{//"打开"动作openFileAction =new QAction(QIcon("open.png"),tr("打开"),this);//用于在组件上设置快捷键openFileAction->setShortcut(tr("Ctrl+O"));//用于设置一个状态提示openFileAction->setStatusTip(tr("open a file"));connect(openFileAction,SIGNAL(triggered()),this,SLOT(ShowOpenFile()));//"新建"动作NewFileAction =new QAction(QIcon("new.png"),tr("新建"),this);NewFileAction->setShortcut(tr("Ctrl+N"));NewFileAction->setStatusTip(tr("新建一个文件"));connect(NewFileAction,SIGNAL(triggered()),this,SLOT(ShowNewFile()));//"退出"动作exitAction =new QAction(tr("退出"),this);exitAction->setShortcut(tr("Ctrl+Q"));exitAction->setStatusTip(tr("退出程序"));connect(exitAction,SIGNAL(triggered()),this,SLOT(close()));//"复制"动作copyAction =new QAction(QIcon("copy.png"),tr("复制"),this);copyAction->setShortcut(tr("Ctrl+C"));copyAction->setStatusTip(tr("复制文件"));connect(copyAction,SIGNAL(triggered()),showWidget->text,SLOT(copy()));//"剪切"动作cutAction =new QAction(QIcon("cut.png"),tr("剪切"),this);cutAction->setShortcut(tr("Ctrl+X"));cutAction->setStatusTip(tr("剪切文件"));connect(cutAction,SIGNAL(triggered()),showWidget->text,SLOT(cut()));//"粘贴"动作pasteAction =new QAction(QIcon("paste.png"),tr("粘贴"),this);pasteAction->setShortcut(tr("Ctrl+V"));pasteAction->setStatusTip(tr("粘贴文件"));connect(pasteAction,SIGNAL(triggered()),showWidget->text,SLOT(paste()));//"关于"动作aboutAction =new QAction(tr("关于"),this);connect(aboutAction,SIGNAL(triggered()),this,SLOT(QApplication::aboutQt()));//"打印文本"动作PrintTextAction =new QAction(QIcon("printText.png"),tr("打印文本"), this);PrintTextAction->setStatusTip(tr("打印一个文本"));connect(PrintTextAction,SIGNAL(triggered()),this,SLOT(ShowPrintText()));//"打印图像"动作PrintImageAction =new QAction(QIcon("printImage.png"),tr("打印图像"), this);PrintImageAction->setStatusTip(tr("打印一幅图像"));connect(PrintImageAction,SIGNAL(triggered()),this,SLOT(ShowPrintImage()));//"放大"动作zoomInAction =new QAction(QIcon("zoomin.png"),tr("放大"),this);zoomInAction->setStatusTip(tr("放大一张图片"));connect(zoomInAction,SIGNAL(triggered()),this,SLOT(ShowZoomIn()));//"缩小"动作zoomOutAction =new QAction(QIcon("zoomout.png"),tr("缩小"),this);zoomOutAction->setStatusTip(tr("缩小一张图片"));connect(zoomOutAction,SIGNAL(triggered()),this,SLOT(ShowZoomOut()));//实现图像旋转的动作(Action)//旋转90°rotate90Action =new QAction(QIcon("rotate90.png"),tr("旋转90°"),this);rotate90Action->setStatusTip(tr("将一幅图旋转90°"));connect(rotate90Action,SIGNAL(triggered()),this,SLOT(ShowRotate90()));//旋转180°rotate180Action =new QAction(QIcon("rotate180.png"),tr("旋转180°"), this);rotate180Action->setStatusTip(tr("将一幅图旋转180°"));connect(rotate180Action,SIGNAL(triggered()),this,SLOT(ShowRotate180()));//旋转270°rotate270Action =new QAction(QIcon("rotate270.png"),tr("旋转270°"), this);rotate270Action->setStatusTip(tr("将一幅图旋转270°"));connect(rotate270Action,SIGNAL(triggered()),this,SLOT(ShowRotate270()));//实现图像镜像的动作(Action)//纵向镜像mirrorVerticalAction =new QAction(tr ("纵向镜像"),this);mirrorVerticalAction->setStatusTip(tr("对一张图作纵向镜像"));connect(mirrorVerticalAction,SIGNAL(triggered()),this,SLOT(ShowMirrorVertical()));//横向镜像mirrorHorizontalAction =new QAction(tr("横向镜像"),this);mirrorHorizontalAction->setStatusTip(tr("对一张图作横向镜像"));connect(mirrorHorizontalAction,SIGNAL(triggered()),this,SLOT(ShowMirrorHorizontal()));//排序:左对齐、右对齐、居中和两端对齐actGrp =new QActionGroup(this);leftAction =new QAction(QIcon("left.png"),"左对齐",actGrp);leftAction->setCheckable(true);rightAction =new QAction(QIcon("right.png"),"右对齐",actGrp);rightAction->setCheckable(true);centerAction =new QAction(QIcon("center.png"),"居中",actGrp);centerAction->setCheckable(true);justifyAction =new QAction(QIcon("justify.png"),"两端对齐",actGrp);justifyAction->setCheckable(true);connect(actGrp,SIGNAL(triggered(QAction*)),this,SLOT(ShowAlignment(QAction*)));//实现撤销和重做的动作(Action)//撤销和重做undoAction =new QAction(QIcon("undo.png"),"撤销",this);connect(undoAction,SIGNAL(triggered()),showWidget->text,SLOT(undo()));redoAction =new QAction(QIcon("redo.png"),"重做",this);connect(redoAction,SIGNAL(triggered()),showWidget->text,SLOT(redo()));
}

        openFileAction =new QAction(QIcon(nopen.pngn),tr(MOpenn),this):在创建“打开文件”动作的同时,指定了此动作使用的图标、名称及父窗口。
        openFileAction->setShortcut(tr(nCtrl+OM)):设置此动作的组合键为【Ctrl+O】。
        openFileAction->setStatusTip(tr(nopen a ImageM)):设定了状态条显示,当鼠标光标移至此动作对应的菜单条目或工具栏按钮上时,在状态条上显示 “打开一个文件” 的提示。如果此函数在调用后未实现效果,可以尝试调用this->statusBar()->show()函数使之显示。效果如下图所示:

2、菜单(Menus)的实现

        在实现了各个动作之后,需要将它们通过菜单、工具栏或快捷键的方式体现出来,以下是菜单的实现函数 createMenus。代码:

void ImgProcessor::createMenus()
{//文件菜单fileMenu =menuBar()->addMenu(tr("文件"));fileMenu->addAction(openFileAction);fileMenu->addAction(NewFileAction);fileMenu->addAction(PrintTextAction);fileMenu->addAction(PrintImageAction);fileMenu->addSeparator();                //添加分隔符fileMenu->addAction(exitAction);//缩放菜单zoomMenu =menuBar()->addMenu(tr("编辑"));zoomMenu->addAction(copyAction);zoomMenu->addAction(cutAction);zoomMenu->addAction(pasteAction);zoomMenu->addAction(aboutAction);zoomMenu->addSeparator();zoomMenu->addAction(zoomInAction);zoomMenu->addAction(zoomOutAction);//旋转菜单rotateMenu =menuBar()->addMenu(tr("旋转"));rotateMenu->addAction(rotate90Action);rotateMenu->addAction(rotate180Action);rotateMenu->addAction(rotate270Action);//镜像菜单mirrorMenu =menuBar()->addMenu(tr("镜像"));mirrorMenu->addAction(mirrorVerticalAction);mirrorMenu->addAction(mirrorHorizontalAction);
}

        fileMenu =menuBarO->addMenu(tr(M 文件")):直接调用 QMainWindow 的menuBar( )函数即可得到主窗口的菜单条指针,再调用菜单条 QMenuBar 的addMenu( )函数,即可完成在菜单条中插入一个新菜单 fileMenu,fileMenu 为一个QMenu 类对象。
        fileMenu->addAction(…):调用 QMenu 的 addAction()函数在菜单中加入菜单条目 “Open”、“New”、"PrintText” 和 “PrintIamge”。
        类似地,实现缩放菜单、旋转菜单和镜像菜单。

3、工具栏(ToolBars)的实现


void ImgProcessor::createToolBars()
{//文件工具条fileTool =addToolBar("File");fileTool->addAction(openFileAction);fileTool->addAction(NewFileAction);fileTool->addAction(PrintTextAction);fileTool->addAction(PrintImageAction);//编辑工具条zoomTool =addToolBar("Edit");zoomTool->addAction(copyAction);zoomTool->addAction(cutAction);zoomTool->addAction(pasteAction);zoomTool->addSeparator();                //添加分隔符zoomTool->addAction(zoomInAction);zoomTool->addAction(zoomOutAction);//旋转工具条rotateTool =addToolBar("rotate");rotateTool->addAction(rotate90Action);rotateTool->addAction(rotate180Action);rotateTool->addAction(rotate270Action);//撤销和重做工具条doToolBar =addToolBar("doEdit");doToolBar->addAction(undoAction);doToolBar->addAction(redoAction);//字体工具条fontToolBar =addToolBar("Font");fontToolBar->addWidget(fontLabel1);fontToolBar->addWidget(fontComboBox);fontToolBar->addWidget(fontLabel2);fontToolBar->addWidget(sizeComboBox);fontToolBar->addSeparator();fontToolBar->addWidget(boldBtn);fontToolBar->addWidget(italicBtn);fontToolBar->addWidget(underlineBtn);fontToolBar->addSeparator();fontToolBar->addWidget(colorBtn);//排序工具条listToolBar =addToolBar("list");listToolBar->addWidget(listLabel);listToolBar->addWidget(listComboBox);listToolBar->addSeparator();listToolBar->addActions(actGrp->actions());
}

        fileTool =addToolBar(nFilen):直接调用 QMainWindow 的 addToolBar()函数即可获得主窗口的工具条对象,每新增一个工具条调用一次 addToolBar()函数,赋予不同的名称,即可在主窗口中新增一个工具条。 
        fileTooI->addAction(…):调用 QToolBar 的 addAction()函数在工具条中插入属于本工具条的动作。类似地,实现“编辑工具条”、“旋转工具条”、“撤销和重做工具条”。 工具条的显示可以由用户进行选择,在工具栏上单击鼠标右键将弹出工具条显示的选择菜单,用户对需要显示的工具条进行选择即可。
        工具条是一个可移动的窗口,它可停靠的区域由 QToolBar 的 allowAreas 决定,包括Qt::LeftToolBarArea 、 Qt::RightToolBarArea 、 Qt::TopToolBarArea 、Qt::BottomToolBarArea 和 Qt::AlIToolBarAreas o 默认为 Qt::AllToolBarAreas, 启动后默认出现于主窗口的顶部。可通过调用setAllowAreas()函数来指定工具条可停靠
的区域,如:
        fileTool->setAllowedAreas(Qt::TopToolBarArea|Qt::LeftToolBarArea);
        此函数限定文件工具条只可出现在主窗口的顶部或左侧。工具条也可通过调用setMovableo函数设定可移动性,如:
        fileTool->setMovable(false);
        指定文件工具条不可移动,只出现于主窗口的顶部。

四、总结

        本文介绍了QMainWindow的基本构成并且梳理了文本编辑器的代码逻辑和框架,至于每一个详细的功能的实现会放在后续的章节进行详细的介绍。

        

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

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

相关文章

近源渗透简介

什么是近源渗透 通过乔装、社工等方式实地物理侵入企业办公区域&#xff0c;通过其内部各种潜在攻击面&#xff08;如Wi-Fi网络、RFID门禁、暴露的有线网口、USB接口等&#xff09;获得“战果”&#xff0c;最后以隐秘的方式将评估结果带出上报&#xff0c;由此证明企业安全防…

最新版康泰克完整版- Kontakt v7.10.5 for Win和Mac,支持m芯片和intel,有入库工具

一。世界最受欢迎的采样器的新篇章 Native Instruments Kontakt是采样器领域的标准&#xff0c;您将获得高质量的滤波器&#xff0c;在这里您将找到经典的模拟电路和最现代的滤波器。每一个都可以根据您的口味进行定制&#xff0c;并且由于它&#xff0c;您可以获得前所未有的声…

Ubuntu上卸载Nginx步骤操作

停止Nginx服务&#xff1a; sudo systemctl stop nginx删除Nginx软件包&#xff1a; sudo apt-get remove --purge nginx nginx-common这条命令会删除Nginx及其配置文件。 清理依赖项&#xff1a; sudo apt-get autoremove这会删除Nginx安装时可能安装的依赖项&#xff0c;…

debian12 允许远程ssh登录

1、查看ssh服务是否在运行 systemctl status ssh 如果没有安装ssh服务&#xff0c;可以通过以下命令安装&#xff1a; apt install openssh-server 如果服务没有运行&#xff0c;通过以下命令重启ssh服务&#xff1a; systemctl restart ssh 2、编辑配置文件 vim /etc/ss…

DROO论文笔记

推荐文章DROO源码及论文学习 读论文《Deep Reinforcement Learning for Online Computation Offloading in Wireless Powered Mobile-Edge Computing Networks》的笔记 论文地址&#xff1a;用于无线移动边缘计算网络在线计算卸载的深度强化学习 论文代码地址&#xff1a;DR…

数组去重(去重+单调栈 用boolen instack来去重

如果存到一个小的就把比它大的都pop出去&#xff0c;在后面还有的情况下&#xff0c;如果后面没有就不pop了 class Solution {public String removeDuplicateLetters(String s) {Stack<Character> stacknew Stack<>();int[] countnew int[256];boolean[] inStackn…

使用 Vue3、Node.js、MySQL、Electron 和 Express 实现用户登录、文章管理和截屏功能

在现代 Web 开发中&#xff0c;前后端分离的架构已经成为主流。本文将详细介绍如何使用 Vue3、Node.js、MySQL、Electron 和 Express 实现一个完整的用户登录、文章管理和截屏功能的应用。我们将从项目的初始化开始&#xff0c;逐步实现各个功能模块&#xff0c;并提供详细的代…

泰迪智能科技江西大数据实验室成功案例介绍说明

高校大数据实验室作为作为支撑高校人培方案实施的核心设施&#xff0c;实验室的建设一定要与学科建设、人才培养充分融合&#xff0c;是一个包含物理空间硬件资源软件资源课程内容的系统化工程。高校在实验室规划过程中&#xff0c;第一要务就是从学科定位出发、结合学校的特色…

14_Shell重定向输入输出

14_Shell重定向输入输出 输出重定向&#xff1a;一般情况&#xff0c;输出是在终端直接显示&#xff0c;改变输出位置&#xff0c;改变到文件中&#xff0c;这就是输出重定向 输入重定向&#xff1a;一般情况&#xff0c;输入是读取用户终端输入&#xff0c;改变输入位置&#…

图解PyTorch中的Transpose操作

在PyTorch中&#xff0c;我们时常会对张量进行转置操作。若张量是二维的&#xff0c;则非常容易理解。若张量维度更高&#xff0c;则会令人摸不到头脑。 高维张量究竟是怎么转置的&#xff1f;简单来说&#xff0c;就是将参与转置的维度抽出来&#xff0c;将内侧的子张量视为一…

js判断是否包含某些字符串中的一个

被判断的字符串是由逗号和中文拼接成的字符串&#xff0c; 编写一个js来校验一个字符串是否包含“纪委书记”&#xff0c;“纪检专岗”&#xff0c;“纪律检查室主任”&#xff0c;判断是否包含这三个字符串中的一个&#xff0c;包含其中一个就为true&#xff0c;多字少字都不算…

【C++PythonJava】字符处理详细解读_字符_ASCLL码_字母数字转换_算法竞赛_开发语言

文章目录 Beginning1&#xff09;ASCLL 码2&#xff09;大小比较2&#xff09;判断数字字符3&#xff09;字符、数字间的相互转换End Beginning 在 C 中&#xff0c;字符和整数有着密不可分的关系。原因就是在计算机中&#xff0c;字符是以一种较 ASCLL 码的整数存储的。自然&…

职业PDF标准 Python 下载器-CSDN

目的 下载技能人才评价网 - 职业技能标准查询系统 - PDF 打包下载 使用文件 a.json 代码解析 import base64 import requests import json import os import time# 读取JSON文件 with open(a.json, r, encodingutf-8) as f:data json.load(f) # 从名为 a.json 的文件中读…

【vue深入学习第1章】Vue.js 中的 Ajax 处理:vue-resource 库的深度解析

在现代前端开发中&#xff0c;Ajax 请求是与后端进行数据交互的关键技术。Vue.js 作为一个渐进式 JavaScript 框架&#xff0c;提供了多种方式来处理 Ajax 请求&#xff0c;其中 vue-resource 是一个较为常用的库。尽管 vue-resource 在 Vue 2.x 之后不再是官方推荐的 Ajax 处理…

四川蔚澜时代电子商务有限公司领航抖音电商新纪元

在数字化浪潮的推动下&#xff0c;电子商务已成为现代商业发展的重要引擎。四川蔚澜时代电子商务有限公司&#xff0c;凭借对市场的敏锐洞察力和对技术的执着追求&#xff0c;成功在抖音电商领域崭露头角&#xff0c;成为众多电商创业者值得信赖的合作伙伴。 抖音&#xff0c;…

qt 创建一个矩形,矩形的边线可以拖拽,拖拽时这个矩形随着这个边线缩放

在Qt中&#xff0c;要创建一个矩形&#xff0c;其边线可以拖拽以实现缩放功能&#xff0c;你需要重写QGraphicsRectItem类&#xff0c;并在其中处理鼠标事件来更新矩形的大小。以下是一个示例代码&#xff0c;展示了如何实现一个可拖拽边线以缩放的矩形&#xff1a; #include …

关系数据库:mysql

使用 mysqladmin 删除数据库 关系型数据库的术语&#xff1a; 数据库: 数据库是一些关联表的集合。数据表: 表是数据的矩阵。在一个数据库中的表看起来像一个简单的电子表格。列: 一列(数据元素) 包含了相同类型的数据, 例如邮政编码的数据。行&#xff1a;一行&#xff08;元组…

idea双击没有反应,打不开

问题描述 Error opening zip file or JAR manifest missing : /home/IntelliJ-IDEA/bin/jetbrains-agent.jar解决方案

前端路由手写Hash和History两种模式

文章目录 1. Hash模式&#xff1a;简洁而广泛适用2. History模式&#xff1a;更自然的用户体验3. 结论 在现代Web开发中&#xff0c;单页面应用&#xff08;Single Page Application&#xff0c;简称SPA&#xff09;因其流畅的用户体验和高效的页面交互能力而备受青睐。前端路由…

PyTorch人脸识别

新书速览|PyTorch深度学习与企业级项目实战-CSDN博客 一套基本的人脸识别系统主要包含三部分&#xff1a;检测器、识别器和分类器&#xff0c;流程架构如图11-3所示&#xff1a; 图11-5 检测器负责检测图片中的人脸&#xff0c;再将检测出来的人脸感兴趣区域&#xff08;Reg…