项目:微服务即时通讯系统客户端(基于C++QT)]四,中间界面搭建和逻辑准备

四,中间界面搭建

前言:当项目越来越复杂的时候,或许画草图是非常好的选择

一,初始化中间窗口initMidWindow

void mainWidget::initMidWindow()
{//使用网格布局进行管理QGridLayout* layout =new QGridLayout();//距离上方 20px 的距离,另外三个方向都不要边距layout->setContentsMargins(0,20,0,0);layout->setHorizontalSpacing(0);layout->setVerticalSpacing(10);windowMid->setLayout(layout);searchEdit =new QLineEdit();searchEdit->setFixedHeight(40);searchEdit->setPlaceholderText("这查找哦(●ˇ∀ˇ●)!");searchEdit->setStyleSheet("QLineEdit {""   border: 2px solid rgb(237,190,135);"  // 边框颜色"   border-radius: 10px;"        // 圆角"   padding: 5px;"                // 内边距"   background-color: #F0F0F0;A"  // 背景色"   color: #333333;"              // 字体颜色"   font-size: 14px;"             // 字体大小"   text-align: center;"       // 使用样式表来居中"}""QLineEdit:focus {""   border: 2px solid rgb(239,109,15);"  // 聚焦时边框颜色"   background-color: #FFFFFF;"   // 聚焦时背景色"}");addUserBtn =new QPushButton();addUserBtn->setFixedSize(40,40);addUserBtn->setIcon(QIcon(":/resource/image/cross.png"));addUserBtn->setStyleSheet("QPushButton {""   background-color: #F0F0F0;"  // 背景颜色"   color: white;"                // 字体颜色"   border: none;"                // 无边框"   border-radius: 20px;"          // 圆角"   padding: 8px 18px;"          // 内边距"   cursor: pointer;"              // 鼠标指针"}""QPushButton:hover {""   background-color: #FFFFFF;"  // 鼠标悬停时的背景颜色"}""QPushButton:pressed {""   background-color: #EDBA39;"   // 按下时的背景颜色"}");//为了更灵活的控制边界,只针对搜索按钮这行,所以我们可以创建空白的widget填充到我们的布局管理器中QWidget* space1 = new  QWidget();space1->setFixedWidth(8);QWidget* space2 = new  QWidget();space2->setFixedWidth(8);QWidget* space3 = new  QWidget();space3->setFixedWidth(8);//统一进行管理布局layout->addWidget(space1,0,0);layout->addWidget(searchEdit,0,1);layout->addWidget(space2,0,2);layout->addWidget(addUserBtn,0,3);layout->addWidget(space3,0,4);SessionFriendArea* sessionFriendArea=new SessionFriendArea();layout->addWidget(sessionFriendArea,1,0,1,5);//后面的为占据一行,横跨五列}
  1. 首先创造一个网格布局管理器的指针

  2. 设置布局管理器的各项属性

  3. 将windowMid的布局管理器设为layout

  4. 创建一个新的 QLineEdit 对象,作为搜索框架,并且初始化各项参数

然后关于QLineEdit,它是 Qt 中用于输入和编辑单行文本的类。

别忘了在mainWidget中加入成员属性。

image.png

5.创建添加用户的按钮,并初始化各项外观属性

6.为了保持设置的HorizontalSpacing为0,我们手动增加各种控件。

7.添加SessionFriendArea()并且包含头文件,现在我们的目标就转移到了SessionFriendArea

image.png

使用布局管理器统一进行管理,我们画图来显示这么一部分

a98959fa0f5b4670dcd8ebaa1116f7a.jpeg

二,来构建sessionFriendArea吧

1.先来头文件,我们的头文件要继承自QScrollArea

class SessionFriendArea : public QScrollArea
{//1.这是一个宏,允许该类使用Qt的信号和槽机制Q_OBJECT
public:explicit SessionFriendArea(QWidget *parent = nullptr);//3.清空该区域所有itemvoid clear();//4.添加一个item到该区域中(这个后面会再次改动)void addItem(const QIcon& user, const QString& name, const QString& text);
private://5.往container内部的layout后续添加元素,能够触发QScrollArea滚动元素QWidget* container;//高度会随着里面添加的元素动态增加的。//通常container会被设置一个布局,该布局会管理其中的子空间,//并且由于QWidget可以根据控件大小自动调整大小//并且这个类作为一个滚动区域,它会显示container的可视区域,如果内容超过,会自动增加滚动条
//6.定义信号(待添加,用于实现逻辑)
signals:
};

注释讲解的很清楚了,我们来补充一下Q_OBJECT

image.png

2.我们来写构造函数SessionFriendArea(QWidget *parent)

SessionFriendArea::SessionFriendArea(QWidget *parent): QScrollArea{parent}
{//1.设置滚动开启,并设置滚动条样式this->setWidgetResizable(true);//开启滚动效果this->verticalScrollBar()->setStyleSheet("QScrollBar:vertical {""   background: #F0F0F0;"              // 背景颜色"   width: 2px;"                      // 滚动条宽度"   border: none;"                     // 无边框"   border-radius: 1px;"               // 圆角"}""QScrollBar::handle:vertical {""   background: #FFABAB;"              // 滚动条颜色"   border-radius: 7px;"               // 圆角"   min-height: 7px;"                 // 滚动条最小高度"}""QScrollBar::handle:vertical:hover {""   background: #FF6F61;"              // 鼠标悬停时的颜色"}""QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical {""   background: none;"                 // 上下箭头的背景"   height: 0px;""}""QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical {""   background: none;"                 // 上下空白区域的背景"}");;//垂直方向的滚动条//设置不可见的水平滚动条this->horizontalScrollBar()->setStyleSheet("QScrollBar:horizontal {""   background: transparent;"  // 背景透明"   height: 2px;"              // 仍然保持高度为0,隐藏它"}");this->setStyleSheet("QWidget {border : none;}");//2.把widget创建出来container=new QWidget();container->setFixedWidth(230);this->setWidget(container);//告诉滚动区,和哪个QWidget配合,和这个宽度为230的区域//3.给这个container widget指定布局管理器,以便后续添加元素进去QVBoxLayout* layout=new QVBoxLayout();layout->setContentsMargins(0,0,0,0);layout->setSpacing(0);layout->setAlignment(Qt::AlignTop);container->setLayout(layout);//4.简单测试一下UI效果// for(int i=0;i<500;i++)// {//     QPushButton* btn =new QPushButton();//     btn->setText("测试");//     layout->addWidget(btn);// }
//4.测试工程展示ui效果
#if TEST_UI1QIcon icon(":/resource/image/defaultAvatar1.png");for(int i=0;i<50;i++){this->addItem(icon,"正切"+QString::number(i),"最后一条消息"+QString::number(i));}
#endif
}

3.写clear函数

void SessionFriendArea::clear()
{//1.取出布局管理器QLayout* layout = container->layout();//遍历布局管理器中的所有元素,并依次从布局管理器中删除掉// for(int i=0;i<layout->count();++i){// takeAt 就能移除对应下标的元素//     layout->takeAt(i);// }//上面的是有问题的//2.遍历布局管理器的所有元素for(int i=layout->count()-1;i>=0;i--){QLayoutItem* item=layout->takeAt(i);//从指定的布局(layout)中移除索引为 i 的布局项(QLayoutItem),并将其返回给itemif(item->widget()){delete item->widget();//移除的item是否有关联的widget,如果有删除widget,释放空间}}
}

知识一:QLayoutItem*这是一个指向 QLayoutItem 类型的指针,表示布局中的一个项目

知识二:takeAt(i) 是 QLayout 类的成员函数,它接受一个整数参数 i,表示要移除的项目的索引。这个函数会从布局中移除该索引位置的项,并返回指向该项的指针。

知识三:item->widget() 方法返回与当前布局项关联的 QWidget 指针,这个if是在检查item种是否有关联的部件

4.添加sessionFriendArea的项目的函数

//添加一个item到该区域中
void SessionFriendArea::addItem(const QIcon& user, const QString& name, const QString& text)
{SessionFriendItem* item = new SessionFriendItem(this, user, name, text);container->layout()->addWidget(item);
}
//包含用户头像,名字,最后一段文本

f32ce6dee7f71c17efa600ca3f1af93.jpeg

三,增加一项又一项的item

1.头文件

class SessionFriendItem : public QWidget{Q_OBJECT;//加上这个宏
public:SessionFriendItem(QWidget* owner,const QIcon& user,const QString& name,const QString& text);//为了让QSS正常使用void paintEvent(QPaintEvent* event)override;//重写鼠标按压函数void mousePressEvent(QMouseEvent* event)override;//重写鼠标触但没压的函数void enterEvent(QEnterEvent* event)override;//重写移开鼠标的函数void leaveEvent(QEvent* event)override;void select();private://owner指向了上述的SessionFriendAreaQWidget* owner;bool selected =false;//这个变量用来表示当前item是否是“选中”状态,实现后续选中效果};

解释一下这里的owner

45e0c7367187a84df185373ce4ca9a1.jpeg

2.构造函数

SessionFriendItem::SessionFriendItem(QWidget* owner,const QIcon& user,const QString& name,const QString& text):owner(owner)
{//1.设置样式this->setFixedHeight(70);//高度this->setStyleSheet("QWidget { background-color:rgb(70,70,70);}");//2.添加网格布局管理器QGridLayout* layout =new QGridLayout();layout->setContentsMargins(18,0,0,0);layout->setHorizontalSpacing(10);layout->setVerticalSpacing(0);this->setLayout(layout);//3.创建头像部件QPushButton* userbtn =new QPushButton();userbtn->setFixedSize(60,60);userbtn->setIconSize(QSize(60,60));userbtn->setIcon(user);userbtn->setStyleSheet("QPushButton {border:none;}");userbtn->setSizePolicy(QSizePolicy::Fixed,QSizePolicy::Fixed);//4.创建名字部件QLabel* nameLabel =new QLabel();nameLabel->setText(name);nameLabel->setStyleSheet("QLabel {font-size: 20px; color: white; font-weight: 400;}");nameLabel->setFixedHeight(35);nameLabel->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Fixed);\//水平方向拓展,竖直方向固定//5.创建消息预览的labelQLabel* messageLabel =new QLabel();messageLabel->setText(text);messageLabel->setStyleSheet("QLabel {font-size: 15px; color: white; font-weight: 400;}");messageLabel->setFixedHeight(35);messageLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);//6.进行布局管理,头像处于 0,0 位置,占据 2行,占据 2列layout->addWidget(userbtn,0,0,2,2);layout->addWidget(nameLabel,0,2,1,1);// 名字处于 0,2 位置,占据 1行,占据 1列layout->addWidget( messageLabel,1,2,1,1);// 消息预览处于 1,2 位置,占据 1 行,占据 1 列layout->addwidget(messageLabel,1,2,1,1);
};

c17c7277b8b513b3f105669cec115ad.jpeg

会发现这样不能设置stylesheet,现在我们来进行处理

原因:在Qt种,如果是给QWidget的子类,通过QSS设置背景色默认是不生效的,除非加上官方代码上的特殊代码

方法:

image.png

image.png

image.png

我们重写一下这个函数

void SessionFriendItem::paintEvent(QPaintEvent* event)
{(void)event;QStyleOption opt;opt.initFrom(this);QPainter p(this);style()->drawPrimitive(QStyle::PE_Widget,&opt,&p,this);}

3.设置各种效果

image.png

void SessionFriendItem::mousePressEvent(QMouseEvent* event)
{(void)event;select();
}
void SessionFriendItem::select()
{//鼠标点击时会触发这个函数//拿到所有的兄弟元素const QObjectList children =this->parentWidget()->children();for(QObject* child :children){if(!child->isWidgetType()){//判定是否是Widgetcontinue;}//是 widget,就把这里的child 强转成SessionFriendItemSessionFriendItem* item=dynamic_cast<SessionFriendItem*>(child);if(item->selected){item->selected =false;item->setStyleSheet("QWidget { background-color: rgb(100,100,100);}");//还原背景色}//点击时修改背景色this->selected =true;this->setStyleSheet("QWidget { background-color: rgb(200,200,200);}");}}
//浮动到上面的情况
void SessionFriendItem::enterEvent(QEnterEvent* event)
{(void)event;// 当前这个 item 是选中状态,则背景色不受到该逻辑影响if(this->selected){return;}//设置一个更深的颜色this->setStyleSheet("QWidget { background-color: rgb(150,150,150);}");
}
//重写移开鼠标的函数
void SessionFriendItem::leaveEvent(QEvent* event)
{(void)event;// 当前这个 item 是选中状态,则背景色不受到该逻辑影响if(this->selected){return;}// 还原背景色this->setStyleSheet("QWidget { background-color: rgb(70,70,70);}");
}

四,封装必要的逻辑

1.实现点击的逻辑

//click函数
void SessionFriendArea::clickItem(int index)
{if(index<0||index>=container->layout()->count()){LOG()<<"指定的元素超出坐标范围,index是"<<index;return;}QLayoutItem* layoutItem=container->layout()->itemAt(index);//itemAt(index): 这是 QLayout 类的成员函数,它接受一个整数参数 index,表示要获取的布局项的索引。该函数返回对应索引的 QLayoutItem 指针,如果索引超出范围,则返回 nullptr.if(layoutItem ==nullptr || layoutItem->widget()==nullptr){LOG()<<"指定的元素不存在,index="<<index;return;}//选中状态SessionFriendItem* item = dynamic_cast<SessionFriendItem*>(layoutItem->widget());item->select();
}

2.会话item的实现

class SessionItem : public SessionFriendItem
{Q_OBJECT;
public://owner,会话id,用户名字,用户头像,用户最后一条信息SessionItem(QWidget* owner, const QString& chatSessionId,const QIcon& user,const QString& name,const QString& lastMessage);
private://当前会话的idQString chatSessionId;
};
//继承自父类SessionFriendItem
SessionItem::SessionItem(QWidget* owner, const QString& chatSessionId,const QIcon& user,const QString& name,const QString& lastMessage)
{}

image.png

这个报错的含义是:

**SessionItem** 的构造函数需要显式地初始化基类 **SessionFriendItem**,因为它没有默认构造函数。你可以在 **SessionItem** 的构造函数初始化列表中调用 **SessionFriendItem** 的构造函数。

SessionItem::SessionItem(QWidget* owner, const QString& chatSessionId,const QIcon& user,const QString& name,const QString& lastMessage):SessionFriendItem{owner,user,name,lastMessage},chatSessionId{chatSessionId}
{}

3.好友item的实现

class FriendItem : public SessionFriendItem
{Q_OBJECT;
public://owner,会话id,用户名字,用户头像,用户最后一条信息FriendItem(QWidget* owner, const QString& userId,const QIcon& user,const QString& name,const QString& Description);
private://好友用户的idQString userId;
};
FriendItem::FriendItem(QWidget* owner, const QString& userId,const QIcon& user,const QString& name,const QString& Description):SessionFriendItem{owner,user,name,Description},userId{userId}
{}

4.好友申请item的实现

class ApplyItem : public SessionFriendItem
{Q_OBJECT;
public://owner,会话id,用户名字,用户头像,用户最后一条信息ApplyItem(QWidget* owner, const QString& userId,const QIcon& user,const QString& name);
private://申请用户的idQString userId;
};

因为这里不用text的构造所以我们对text直接传入空字符串

ApplyItem::ApplyItem(QWidget* owner, const QString& userId,const QIcon& user,const QString& name):SessionFriendItem{owner,user,name,""},userId{userId}
{}

5.基于此对additem进行改造

void SessionFriendArea::addItem(ItemType itemtype,const QString id,const QIcon& user, const QString& name, const QString& text)
{SessionFriendItem* item =nullptr;if(itemtype==SessionItemType){item=new SessionItem(this,id,user, name, text);}else if(itemtype==FriendItemType){item=new FriendItem(this,id,user, name, text);}else if(itemtype==ApplyItemType){item=new ApplyItem(this,id,user, name);}else{LOG()<<"错误的item"<<itemtype;return ;}container->layout()->addWidget(item);
}

6.对applyitem界面的调整

//abc代码
ApplyItem::ApplyItem(QWidget* owner, const QString& userId,const QIcon& user,const QString& name):SessionFriendItem{owner,user,name,""},userId{userId}
{//1.移除父类的messageLabel//将ApplyItem的布局管理器强转为QGridLayoutQGridLayout* layout =dynamic_cast<QGridLayout*>(this->layout());layout->removeWidget(messageLabel);//释放内存,否则会内存泄露delete messageLabel;//2.创建两个按钮出来并且美化字体QPushButton* accepBtn =new QPushButton();accepBtn->setText("同意");accepBtn->setStyleSheet("QPushButton {font-size: 15px; color: white; font-weight: 400; font-family: 'SimSun'; }");QPushButton* rejectBtn =new QPushButton();rejectBtn->setText("拒绝");rejectBtn->setStyleSheet("QPushButton {font-size: 15px; color: white; font-weight: 400; font-family: 'SimSun'; }");//3.添加到布局管理器中layout->addWidget(accepBtn,1,2,1,1);layout->addWidget(rejectBtn,1,3,1,1);
}
  1. 强转为网格布局

  2. 删除掉messageLabel,会发现父类里messageLabel是构造函数的局部变量。

image.png

我们改成protected让这个成员能够被子类访问,要记得释放内存,否则会内存泄漏

c.创建两个按钮出来7bddfa1878c7c4f7d52f06806dd0257.jpeg

这是产生的页面效果

image.png

d.很丑我们就调整名字、消息所占的列,并且美化字体

90e19493bdc3d1f008b8217609fe310.jpeg

产生的效果

image.png

image.png

7.点击逻辑的准备工作

Sessionltem :点击之后,应该要在主界面右侧消息展示区,加载出对应的消息列表.

Friendltem:点击之后,要切换到会话列表,并且选中对应的会话.

Applyltem:点击之后,无事发生.主要逻辑是靠"同意""拒绝"按钮触发的.

在父类上加虚函数active()

在子类上加重写的active()

image.png

image.png

并且对鼠标按压的触发做出逻辑实现

void SessionFriendItem::select()
{//鼠标点击时会触发这个函数//拿到所有的兄弟元素const QObjectList children =this->parentWidget()->children();for(QObject* child :children){if(!child->isWidgetType()){//判定是否是Widget//如果不是不用处理continue;}//是 widget,就把这里的child 强转成SessionFriendItemSessionFriendItem* item=dynamic_cast<SessionFriendItem*>(child);if(item->selected){item->selected =false;item->setStyleSheet("QWidget { background-color: rgb(70,70,70);}");//还原背景色}}//点击时修改背景色this->selected =true;this->setStyleSheet("QWidget { background-color: rgb(200,200,200);}");//提供逻辑this->active();
}

告一段落:

image.png

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

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

相关文章

高效录制,尽在掌握:四大录屏软件对比分析!

屏幕录制是一种重要的信息传递方式。今天&#xff0c;我们就来一起探索几款市场上备受好评的录屏工具——福昕录屏大师、转转大师录屏、爱拍录屏以及OCAM录屏&#xff0c;看看它们各自都有哪些独特之处。 福昕录屏工具 直达链接&#xff1a;www.foxitsoftware.cn/REC/ 作为一…

pyqt打包成exe相关流程

1、首先是安装pyinstaller, 在cmd中输入以下安装命令&#xff1a; pip3 install pyinstaller -i https://mirrors.tuna.tsinghua.edu.cn/pypi/web/simple/ 2、安装完毕之后&#xff0c;下一步就是找到你要打包的工程&#xff0c;打包的logo放置如下位置&#xff1a; 3、将log…

[C语言]--编译和链接

文章目录 目录 文章目录 前言 一、环境介绍 二、翻译环境 1.预处理&#xff08;预编译&#xff09; 2.编译 3.汇编 4.链接 三、运行环境 前言 对编译和链接 进行简单的介绍 一、环境介绍 在ANSIC的任何⼀种实现中&#xff0c;存在两个不同的环境。 翻译环境&#xff0c;在这…

flutter_鸿蒙next(win)环境搭建

第一步 拉取鸿蒙版本flutterSDK仓库 仓库地址&#xff1a;OpenHarmony-SIG/flutter_flutter 第二步 找到拉取的仓库中的README.md 并根据说明配置环境 第三步 配置好环境变量之后 用管理员开启cmd 输入&#xff1a;flutter dcotor 并查看此时flutter所支持的系统 包括&…

《深度学习》OpenCV 图像拼接 原理、参数解析、案例实现

目录 一、图像拼接 1、直接看案例 图1与图2展示&#xff1a; 合并完结果&#xff1a; 2、什么是图像拼接 3、图像拼接步骤 1&#xff09;加载图像 2&#xff09;特征点检测与描述 3&#xff09;特征点匹配 4&#xff09;图像配准 5&#xff09;图像变换和拼接 6&am…

【若依】postman调试出现认证失败,无法访问系统资源

如果前后端都已经连接通了&#xff0c;但是调试出现错误代码&#xff0c;可能是因为没有授权的问题&#xff0c;需要获得授权。 授权内容在cookie中 把cookie中的token内容粘贴到postman里面 这个时候再在postman里测试接口&#xff0c;发现可以拿到数据了

pytorch之梯度累加

1.什么是梯度&#xff1f; 梯度可以理解为一个多变量函数的变化率&#xff0c;它告诉我们在某一点上&#xff0c;函数的输出如何随输入的变化而变化。更直观地说&#xff0c;梯度指示了最优化方向。 在机器学习中的作用&#xff1a;在训练模型时&#xff0c;我们的目标是最小…

TransFormer 视频笔记

TransFormer BasicsAttention单头注意力 single head attentionQ&#xff1a; query 查寻矩阵 128*12288K key matrix 128*12288SoftMax 归一 ![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/19e3cf1ea28442eca60d5fc1303921f4.png)Value matrix 12288*12288 MLP Bas…

【Linux】进程地址空间、环境变量:从理论到实践(三)

&#x1f308; 个人主页&#xff1a;Zfox_ &#x1f525; 系列专栏&#xff1a;Linux 目录 &#x1f680; 前言一&#xff1a;&#x1f525; 环境变量 &#x1f95d; 基本概念&#x1f95d; 常见环境变量&#x1f95d; 查看环境变量方法 二&#xff1a;&#x1f525; 测试 &…

前端算法合集-1(含面试题)

(这是我面试一家中厂公司的二面算法题) 数组去重并按出现次数排序 题目描述: 给定一个包含重复元素的数组&#xff0c;请你编写一个函数对数组进行去重&#xff0c;并按元素出现的次数从高到低排序。如果次数相同&#xff0c;则按元素值从小到大排序。 let arr [2, 11,10, 1…

GPTQ vs AWQ vs GGUF(GGML) 速览和 GGUF 文件命名规范

简单介绍一下四者的区别。 参考链接&#xff1a;GPTQ - 2210.17323 | AWQ - 2306.00978 | GGML | GGUF - docs | What is GGUF and GGML? 文章目录 GPTQ vs AWQ vs GGUF&#xff08;GGML&#xff09; 速览GGUF 文件命名GGUF 文件结构文件名解析答案 附录GGUF 文件命名GGUF 文件…

15分钟学 Python 第35天 :Python 爬虫入门(一)

Day 35 : Python 爬虫简介 1.1 什么是爬虫&#xff1f; 网页爬虫&#xff08;Web Crawler&#xff09;是自动访问互联网并提取所需信息的程序。爬虫的主要功能是模拟用户通过浏览器访问网页的操作&#xff0c;从而实现对网页内容的批量访问与信息提取。它们广泛应用于数据收集…

JAVA并发编程系列(13)Future、FutureTask异步小王子

美团本地生活面试&#xff1a;模拟外卖订单处理&#xff0c;客户支付提交订单后&#xff0c;查询订单详情&#xff0c;后台需要查询店铺备餐进度、以及外卖员目前位置信息后再返回。 时间好快&#xff0c;一转眼不到一个月时间&#xff0c;已经完成分享synchronized、volatile、…

【VUE】案例:商场会员管理系统

编写vuedfr实现对会员进行基本增删改查 1. drf项目初始化 请求&#xff1a; POST http://127/0.0.0.1:8000/api/auth/ {"username":"cqn", "password":"123"}返回&#xff1a; {"username":"cqn", "token&q…

读论文、学习时 零碎知识点记录01

1.入侵检测技术 2.深度学习、机器学习相关的概念 ❶注意力机制 ❷池化 ❸全连接层 ❹Dropout层 ❺全局平均池化 3.神经网络中常见的层

.NET Core 集成 MiniProfiler性能分析工具

前言&#xff1a; 在日常开发中&#xff0c;应用程序的性能是我们需要关注的一个重点问题。当然我们有很多工具来分析程序性能&#xff1a;如&#xff1a;Zipkin等&#xff1b;但这些过于复杂&#xff0c;需要单独搭建。 MiniProfiler就是一款简单&#xff0c;但功能强大的应用…

Unraid的cache使用btrfs或zfs?

Unraid的cache使用btrfs或zfs&#xff1f; 背景&#xff1a;由于在unraid中添加了多个docker和虚拟机&#xff0c;因此会一直访问硬盘。然而&#xff0c;单个硬盘实在难以让人放心。在阵列盘中&#xff0c;可以通过添加校验盘进行数据保护&#xff0c;在cache中无法使用xfs格式…

深入挖掘C++中的特性之一 — 继承

目录 1.继承的概念 2.举个继承的例子 3.继承基类成员访问方式的变化 1.父类成员的访问限定符对在子类中访问父类成员的影响 2.父类成员的访问限定符子类的继承方式对在两个类外访问子类中父类成员的影响 4.继承类模版&#xff08;注意事项&#xff09; 5.父类与子类间的转…

数据结构——计数、桶、基数排序

目录 引言 计数排序 1.算法思想 2.算法步骤 3.代码实现 4.复杂度分析 桶排序 1.算法思想 2.算法步骤 3.代码实现 4.复杂度分析 基数排序 1.算法思想 2.算法步骤 3.代码实现 4.复杂度分析 排序算法的稳定性 1.稳定性的概念 2.各个排序算法的稳定性 结束语 引…

C++(string类的实现)

1. 迭代器、返回capacity、返回size、判空、c_str、重载[]和clear的实现 string类的迭代器的功能就类似于一个指针&#xff0c;所以我们可以直接使用一个指针来实现迭代器&#xff0c;但如下图可见迭代器有两个&#xff0c;一个是指向的内容可以被修改&#xff0c;另一个则是指…