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

Qt开发 | Qt界面布局 | 水平布局 | 竖直布局 | 栅格布局 | 分裂器布局 | setLayout使用 | 添加右键菜单 | 布局切换与布局删除重构

文章目录

  • 一、Qt界面布局
  • 二、Qt水平布局--QHBoxLayout
  • 三、Qt竖直布局
  • 四、Qt栅格布局
  • 五、分裂器布局代码实现
  • 六、setLayout使用说明
  • 七、布局切换与布局删除重构
    • 1.如何添加右键菜单
    • 2.布局切换与布局删除重构

一、Qt界面布局

  Qt的界面布局类型可分为如下几种

  • 水平布局(Horizontal Layout)

    水平布局将控件水平排列。控件按照从左到右的顺序排列,可以设置控件之间的间距。

  • 竖直布局(Vertical Layout)

    竖直布局将控件垂直排列。控件按照从上到下的顺序排列,也可以设置控件之间的间距。

  • 栅格布局(Grid Layout)

    栅格布局将控件排列在网格中。你可以指定控件的行和列,以及行和列的间距。栅格布局非常适合需要将控件整齐排列在表格中的场景。

  • 分裂器布局(Splitter Layout)

    分裂器布局允许用户通过拖动分隔条来调整相邻控件的大小。这种布局通常用于需要动态调整空间分配的界面,例如在文本编辑器中调整工具栏和文本区域的大小。

除了这些基本布局,Qt 还提供了其他一些布局管理器,例如:

  • 表单布局(Form Layout):用于创建表单界面,控件和标签按照两列排列。
  • 堆栈布局(Stack Layout):允许在同一个空间内堆叠多个控件,并且一次只能显示一个。
  • 工具箱布局(Tool Box Layout):类似于网页上的选项卡,允许用户在多个页面之间切换。

ui设计器设计界面很方便,为什么还要手写代码

  • 更好的控制布局
  • 更好的设置qss
  • 代码复用

二、Qt水平布局–QHBoxLayout

介绍手写水平布局,不使用ui设计器来设置布局,因此,可将ui文件等删掉

  • 创建水平布局

    #include <QHBoxLayout>
    QHBoxLayout *pHLay = new QHBoxLayout(父窗口指针); //一般填this
    
  • 相关方法

    • addWidget:在布局中添加一个控件
    • addLayout:在布局里添加布局
    • setMargin:设置水平布局最外边界与相邻空间左上右下的间隙,这时左上右下的间隙相同;如果想设置成不同,可以使用setContentMargins方法
    • setSpacing:设置相邻控件之间的间隙,默认值大概是7
    • addSpacing:在setSpacing的基础上进行相加,例如:addSpacing(-7),相当于两个控件之间没有距离;addSpacing(13)相当于setSpacing(20);
    • addStretch:在水平布局时添加一个水平的伸缩空间(QSpacerItem),在竖直布局时,添加一个竖直的伸缩空间

示例:

xx.h

#pragma once#include <QtWidgets/QWidget>class ch2_3_hLayout : public QWidget
{Q_OBJECTpublic:ch2_3_hLayout(QWidget *parent = Q_NULLPTR);};

xx.cpp

#include "ch2_3_hLayout.h"
#include <QHBoxLayout>
#include <QLabel>
#include <QLineEdit>
#include <QPushButton>
#include <QDebug>ch2_3_hLayout::ch2_3_hLayout(QWidget *parent): QWidget(parent)
{this->resize(400, 80);//新建三个控件QLabel* pPath = new QLabel(this);pPath->setObjectName("pPath");//pPath->setFixedSize(40, 32);pPath->setText(u8"路径");QLineEdit* pEdit = new QLineEdit(this);pEdit->setObjectName("pEdit");//pEdit->setFixedSize(100, 32);pEdit->setMinimumWidth(50);QPushButton* pBtn = new QPushButton(this);pBtn->setObjectName("pBtn");//pBtn->setFixedSize(50, 32);pBtn->setText(u8"打开");//创建水平布局QHBoxLayout* pHLay = new QHBoxLayout(this);//pHLay->setMargin(0);  //设置水平布局最外边界与相邻空间左上右下的间隙//pHLay->setContentsMargins(0, 100, 10, 0); //设置左上右下的间隙//将三个控件添加到水平布局中pHLay->addStretch();    //添加水平弹簧pHLay->addWidget(pPath);pHLay->addSpacing(10);  //添加相邻两个控件间的间隙pHLay->addWidget(pEdit);pHLay->addWidget(pBtn);pHLay->addStretch();
}

main.cpp

#include "ch2_3_hLayout.h"
#include <QtWidgets/QApplication>int main(int argc, char *argv[])
{QApplication a(argc, argv);ch2_3_hLayout w;w.show();return a.exec();
}

运行结果

image-20240624170042686

三、Qt竖直布局

  • 创建水平布局

    #include <QVBoxLayout>
    QVBoxLayout *pMainVLay = new QVBoxLayout(父窗口指针); //一般填this
    
  • 相关方法:与水平布局类似

    • addWidget:在布局中添加一个控件
    • addLayout:在布局里添加布局
    • setMargin:设置水平布局最外边界与相邻空间左上右下的间隙,这时左上右下的间隙相同;如果想设置成不同,可以使用setContentMargins方法
    • setSpacing:设置相邻控件之间的间隙,默认值大概是7
    • addSpacing:在setSpacing的基础上进行相加,例如:addSpacing(-7),相当于两个控件之间没有距离;addSpacing(13)相当于setSpacing(20);
    • addStretch:在水平布局时添加一个水平的伸缩空间(QSpacerItem),在竖直布局时,添加一个竖直的伸缩空间

示例:

xx.h

#ifndef WIDGET_H
#define WIDGET_H#include <QWidget>class Widget : public QWidget
{Q_OBJECTpublic:Widget(QWidget *parent = nullptr);~Widget();
};
#endif // WIDGET_H

xx.cpp

#include "widget.h"
#include <QPushButton>
#include <QVBoxLayout>Widget::Widget(QWidget *parent): QWidget(parent)
{//新建三个按钮QPushButton *pBtn1 = new QPushButton(this);pBtn1->setObjectName("pBtn1");pBtn1->setText("pBtn1");// pBtn1->setFixedSize(40, 32);QPushButton *pBtn2 = new QPushButton(this);pBtn2->setObjectName("pBtn2");pBtn2->setText("pBtn2");// pBtn1->setFixedSize(40, 32);QPushButton *pBtn3 = new QPushButton(this);pBtn3->setObjectName("pBtn3");pBtn3->setText("pBtn3");// pBtn1->setFixedSize(40, 32);//新建竖直布局QVBoxLayout *pVLay = new QVBoxLayout(this);// pVLay->setMargin(100);// pVLay->setContentsMargins(80, 70, 60, 50);pVLay->addWidget(pBtn1);pVLay->addSpacing(10);pVLay->addWidget(pBtn2);pVLay->addSpacing(50);pVLay->addWidget(pBtn3);
}Widget::~Widget()
{}

main.cpp

#include "widget.h"#include <QApplication>int main(int argc, char *argv[])
{QApplication a(argc, argv);Widget w;w.show();return a.exec();
}

运行结果

image-20240624171928197

四、Qt栅格布局

  • 创建栅格布局

    #include <QGridLayout>
    QGridLayout *pGridLayout = new QGridLayout(this);
    
  • 相关方法:与水平布局类似

    • 栅格布局添加控件

      class Q_WIDGETS_EXPORT QGridLayout : public QLayout
      {//...inline void addWidget(QWidget *w) { QLayout::addWidget(w); }//基于行、列、对齐方式来添加控件void addWidget(QWidget *, int row, int column, Qt::Alignment = Qt::Alignment());//基于行、列、跨多少行、跨多少列、对齐方式来添加控件void addWidget(QWidget *, int row, int column, int rowSpan, int columnSpan, Qt::Alignment = Qt::Alignment());//基于行、列、对齐方式来添加子布局void addLayout(QLayout *, int row, int column, Qt::Alignment = Qt::Alignment());void addLayout(QLayout *, int row, int column, int rowSpan, int columnSpan, Qt::Alignment = Qt::Alignment());//...
      }
      
    • 栅格布局设置间隙

      • 设置水平间距

        pGridLayout->setHorizontalSpacing(10);
        
      • 设置垂直间距

        pGridLayout->setVerticalSpacing(10);
        

示例:

xx.h

#ifndef WIDGET_H
#define WIDGET_H#include <QWidget>class Widget : public QWidget
{Q_OBJECTpublic:Widget(QWidget *parent = nullptr);~Widget();
};
#endif // WIDGET_H

xx.cpp

#include "widget.h"
#include <QGridLayout>
#include <QPushButton>
#include <QLabel>
#include <QLineEdit>
#include <QCheckBox>
#include <QDebug>Widget::Widget(QWidget *parent): QWidget(parent)
{//无边框窗口且可以最大化与最小化this->setWindowFlags(Qt::FramelessWindowHint | Qt::WindowMinMaxButtonsHint);/**新建控件**///头像QLabel* pImageLabel = new QLabel(this);QPixmap pixMap(":/resources/user_image.png");pImageLabel->setFixedSize(150, 150);pixMap.scaled(pImageLabel->size(), Qt::KeepAspectRatio);pImageLabel->setPixmap(pixMap);pImageLabel->setScaledContents(true);//用户名QLineEdit* pUserNameLineEdit = new QLineEdit(this);pUserNameLineEdit->setFixedSize(300, 50);pUserNameLineEdit->setPlaceholderText("QQ号码/手机/邮箱"); //设置提示信息//密码QLineEdit* pPwdLineEdit = new QLineEdit(this);pPwdLineEdit->setFixedSize(300, 50);pPwdLineEdit->setPlaceholderText("密码");pPwdLineEdit->setEchoMode(QLineEdit::Password); //密码模式//找回密码QPushButton* pForgetButton = new QPushButton(this);pForgetButton->setText("找回密码");pForgetButton->setFixedWidth(80);//记住密码QCheckBox* pRemCheckBox = new QCheckBox(this);pRemCheckBox->setText("记住密码");//自动登陆QCheckBox* pAutoLoginCheckBox = new QCheckBox(this);pAutoLoginCheckBox->setText("自动登陆");//登陆QPushButton* pLoginBtn = new QPushButton(this);pLoginBtn->setFixedHeight(48);pLoginBtn->setText("登陆");//注册账号QPushButton* pRegisterBtn = new QPushButton(this);pRegisterBtn->setFixedHeight(48);pRegisterBtn->setText("注册账号");//新建栅格布局QGridLayout* pGridLayout = new QGridLayout(this);pGridLayout->addWidget(pImageLabel, 0, 0, 3, 1);pGridLayout->addWidget(pUserNameLineEdit, 0, 1, 1, 2);pGridLayout->addWidget(pPwdLineEdit, 1, 1, 1, 2);pGridLayout->addWidget(pForgetButton, 2, 1, 1, 1);pGridLayout->addWidget(pRemCheckBox, 2, 2, 1, 1, Qt::AlignLeft | Qt::AlignVCenter);pGridLayout->addWidget(pAutoLoginCheckBox, 2, 2, 1, 1, Qt::AlignRight | Qt::AlignVCenter);pGridLayout->addWidget(pLoginBtn, 3, 1, 1, 2);pGridLayout->addWidget(pRegisterBtn, 4, 1, 1, 2);//设置水平布局与垂直布局pGridLayout->setHorizontalSpacing(20);//pGridLayout->setVerticalSpacing(20);pGridLayout->setContentsMargins(30, 30, 30, 30);
}Widget::~Widget() {}

main.cpp

#include "widget.h"#include <QApplication>int main(int argc, char *argv[])
{QApplication a(argc, argv);Widget w;w.show();return a.exec();
}

运行结果

image-20240624190548535

五、分裂器布局代码实现

在Qt设计器中使用两个按钮实现分裂器

image-20240624205827817

  • 水平分裂器

    QSplitter* pHSplitter = new QSplitter(Qt::Horizontal, this);
    
  • 竖直分裂器

    QSplitter* pVSplitter = new QSplitter(Qt::Vertical, pHSplitter);
    
  • 分裂器也是QWidget的子类,因此,分裂器也有addWidget方法,而布局也可以使用addWidget往布局里添加分裂器。

示例:

xx.h

#ifndef WIDGET_H
#define WIDGET_H#include <QWidget>class Widget : public QWidget
{Q_OBJECTpublic:Widget(QWidget *parent = nullptr);~Widget();
};
#endif // WIDGET_H

xx.cpp:

#include "widget.h"
#include <QHBoxLayout>
#include <QSplitter>
#include <QTextBrowser>Widget::Widget(QWidget *parent): QWidget(parent)
{this->setWindowTitle("Qt分裂器布局_c++代码");QHBoxLayout* pHboxLayout = new QHBoxLayout(this);//整体的水平分裂器QSplitter* pHSplitter = new QSplitter(Qt::Horizontal, this);//左侧widgetQWidget* pLeftWidget = new QWidget(this);pLeftWidget->setStyleSheet("background-color:rgb(54, 54, 54)");pLeftWidget->setMinimumWidth(200);//分裂器添加widgetpHSplitter->addWidget(pLeftWidget);//右侧的竖直分裂器QSplitter* pVSplitter = new QSplitter(Qt::Vertical, pHSplitter);//在拖动到位并弹起鼠标后再显式分隔条pVSplitter->setOpaqueResize(false);//右侧顶部widgetQWidget* pRightTopWidget = new QWidget(this);pRightTopWidget->setStyleSheet("background-color:rgb(154, 154, 154)");//右侧底部窗体QTextBrowser* pRightBottom = new QTextBrowser(this);pVSplitter->addWidget(pRightTopWidget);pVSplitter->addWidget(pRightBottom);pHSplitter->addWidget(pVSplitter);//布局添加分裂器pHboxLayout->addWidget(pHSplitter);//设置整体布局//this->setLayout(pHboxLayout);
}Widget::~Widget() {}

main.cpp

#include "widget.h"#include <QApplication>int main(int argc, char *argv[])
{QApplication a(argc, argv);Widget w;w.show();return a.exec();
}

运行结果

image-20240624212248737

六、setLayout使用说明

  QWidget::setLayout(QLayout *layout) 是 Qt 框架中的一个成员函数,用于为窗口小部件(widget)设置布局管理器(layout manager)。

  • 设置此窗口小部件的布局管理器为 layout
  • 如果此窗口小部件上已经安装了布局管理器,QWidget 不会允许你安装另一个。你必须首先删除现有的布局管理器(由 layout() 返回),然后才能使用新的布局调用 setLayout()
  • 如果 layout 是另一个窗口小部件上的布局管理器,setLayout() 将重新为其设置父级,并使其成为此窗口小部件的布局管理器。

示例:

QVBoxLayout *layout = new QVBoxLayout;
layout->addWidget(formWidget);
setLayout(layout);

还可以通过将窗口小部件作为参数传递给布局的构造函数来设置布局,这样窗口小部件就会自动接管布局的所有权。

七、布局切换与布局删除重构

1.如何添加右键菜单

  • 菜单事件

    void contextMenuEvent(QContextMenuEvent* event) override;
    
  • 设置菜单策略

    this->setContextMenuPolicy(Qt::DefaultContextMenu);
    
  • 创建菜单

    void Widget::initMenu()
    {m_pMenu = new QMenu(this);QAction *pAction1 = new QAction("查看");QAction *pAction2 = new QAction("排序方式");QAction *pAction3 = new QAction("刷新");m_pMenu->addAction(pAction1);m_pMenu->addAction(pAction2);m_pMenu->addAction(pAction3);
    }
    
  • 弹出菜单

    void Widget::contextMenuEvent(QContextMenuEvent* event)
    {m_pMenu->exec(QCursor::pos());
    }
    

示例:

xx.h

#ifndef WIDGET_H
#define WIDGET_H#include <QWidget>
#include <QMenu>class Widget : public QWidget
{Q_OBJECTpublic:Widget(QWidget *parent = nullptr);~Widget();//菜单事件void contextMenuEvent(QContextMenuEvent* event) override;void initMenu();    //创建菜单private:QMenu* m_pMenu = nullptr;
};
#endif // WIDGET_H

xx.cpp

#include "widget.h"
#include <QAction>
#include <QMessageBox>Widget::Widget(QWidget *parent): QWidget(parent)
{this->setWindowFlags(Qt::FramelessWindowHint | Qt::WindowMinMaxButtonsHint);//设置菜单策略this->setContextMenuPolicy(Qt::DefaultContextMenu);initMenu(); //初始化菜单
}Widget::~Widget() {}void Widget::contextMenuEvent(QContextMenuEvent* event)
{m_pMenu->exec(QCursor::pos());
}void Widget::initMenu()
{m_pMenu = new QMenu(this);QAction *pAction1 = new QAction("查看");QAction *pAction2 = new QAction("排序方式");QAction *pAction3 = new QAction("刷新");m_pMenu->addAction(pAction1);m_pMenu->addAction(pAction2);m_pMenu->addAction(pAction3);connect(pAction1, &QAction::triggered, [=]{QMessageBox::information(this, "title", "查看");});
}

main.cpp

#include "widget.h"#include <QApplication>int main(int argc, char *argv[])
{QApplication a(argc, argv);Widget w;w.show();return a.exec();
}

运行结果

image-20240624215757223

2.布局切换与布局删除重构

  通过右键菜单项,实现布局的切换与布局删除重构。

示例:

SwitchWidget.h

#pragma once#include <QtWidgets/QWidget>
#include <QLabel>
#include <QList>
#include <QMenu>// 视频分屏类型
enum VideoLayoutType
{OneVideo = 0,TwoVideo,ThreeVideo,FourVideo,FiveVideo,SixVideo,SeventVideo,EightVideo,NineVideo,
};class SwitchWidget : public QWidget
{Q_OBJECTpublic:SwitchWidget(QWidget* parent = nullptr);~SwitchWidget();private:void initWidget();void initMenu();void contextMenuEvent(QContextMenuEvent* event) override;  //菜单事件void switchLayout(VideoLayoutType type);    //切换不同布局private:QList<QLabel*> m_videoLabelList;    //用于保存视频区域QMenu* m_switchMenu;
};

SwitchWidget.cpp

#pragma execution_character_set("utf-8")
#include "SwitchWidget.h"
#include <QGridLayout>
#include <QContextMenuEvent>
#include <QDebug>SwitchWidget::SwitchWidget(QWidget* parent): QWidget(parent)
{this->setWindowTitle(u8"Qt布局切换与布局删除重构");initWidget();this->resize(QSize(800, 500));this->setContextMenuPolicy(Qt::DefaultContextMenu); //设置菜单策略
}SwitchWidget::~SwitchWidget() {}void SwitchWidget::initWidget() //初始化界面
{initMenu(); //初始化菜单for (int i = 0; i < 9; i++){QLabel* label = new QLabel();label->setStyleSheet(QString("QLabel{background-image:url(:/SwitchWidget/resources/%1.png); \border:1px solid gray; \background-position:center; \background-repeat:no-repeat; \}").arg(QString::number(i + 1)));m_videoLabelList.append(label);}switchLayout(VideoLayoutType::OneVideo);
}void SwitchWidget::initMenu() //初始化菜单
{m_switchMenu = new QMenu(this);m_switchMenu->addAction(u8"一分屏");m_switchMenu->addAction(u8"四分屏");m_switchMenu->addAction(u8"五分屏");m_switchMenu->addAction(u8"六分屏");m_switchMenu->addAction(u8"九分屏");QMap<QString, int> strTypeMap;strTypeMap["一分屏"] = VideoLayoutType::OneVideo;strTypeMap["四分屏"] = VideoLayoutType::FourVideo;strTypeMap["五分屏"] = VideoLayoutType::FiveVideo;strTypeMap["六分屏"] = VideoLayoutType::SixVideo;strTypeMap["九分屏"] = VideoLayoutType::NineVideo;//信号槽connect(m_switchMenu, &QMenu::triggered, this, [=](QAction* action) {QString strText = action->text();qDebug() << "strText = " << strText;qDebug() << strTypeMap[strText];VideoLayoutType type = static_cast<VideoLayoutType>(strTypeMap[strText]);qDebug() << "type = " << type;switchLayout(type);});
}void SwitchWidget::contextMenuEvent(QContextMenuEvent* event) //菜单事件
{m_switchMenu->exec(QCursor::pos()); //弹出菜单--使用当前鼠标位置来执行菜单
}void SwitchWidget::switchLayout(VideoLayoutType type) //切换不同布局
{QLayout* layout = this->layout();   //获取当前窗口的布局//当切换布局时,若布局不为空,则清空布局内的所有元素if (layout){QLayoutItem* child; //布局中的子项//删除布局中的所有子项while ((child = layout->takeAt(0)) != 0){//调用 setParent(NULL) 方法将控件的父对象设置为 NULL。这样做可以防止控件在从布局中删除后界面上仍然显示。if (child->widget()){child->widget()->setParent(NULL);}delete child;}delete layout;}//设置新的布局switch (type){case OneVideo:{qDebug() << "OneVideo\n";QGridLayout* gLayout = new QGridLayout(this);gLayout->addWidget(m_videoLabelList[0]);gLayout->setMargin(0);}break;case FourVideo:{qDebug() << "FourVideo\n";QGridLayout* gLayout = new QGridLayout(this);gLayout->setSpacing(0);gLayout->setMargin(0);for (int i = 0; i < 4; i++){gLayout->addWidget(m_videoLabelList[i], i / 2, i % 2);}}break;case FiveVideo:{qDebug() << "FiveVideo\n";QVBoxLayout* pVLay = new QVBoxLayout(this);pVLay->setSpacing(0);QHBoxLayout* pHTopLay = new QHBoxLayout(this);pHTopLay->setSpacing(0);for (int i = 0; i < 3; i++){pHTopLay->addWidget(m_videoLabelList[i]);}QHBoxLayout* pHBottomLay = new QHBoxLayout(this);pHBottomLay->setSpacing(0);for (int i = 3; i < 5; i++){pHBottomLay->addWidget(m_videoLabelList[i]);}pVLay->addLayout(pHTopLay);pVLay->addLayout(pHBottomLay);}break;case SixVideo:{QGridLayout* gLayout = new QGridLayout(this);gLayout->addWidget(m_videoLabelList[0], 0, 0, 2, 2);gLayout->addWidget(m_videoLabelList[1], 0, 2);gLayout->addWidget(m_videoLabelList[2], 1, 2);gLayout->addWidget(m_videoLabelList[3], 2, 0);gLayout->addWidget(m_videoLabelList[4], 2, 1);gLayout->addWidget(m_videoLabelList[5], 2, 2);gLayout->setSpacing(0);gLayout->setMargin(0);}break;case NineVideo:{QGridLayout* gLayout = new QGridLayout(this);gLayout->setSpacing(0);gLayout->setMargin(0);for (int i = 0; i < 9; i++){gLayout->addWidget(m_videoLabelList[i], i / 3, i % 3);}}break;default:break;}}

main.cpp

#include "SwitchWidget.h"
#include <QtWidgets/QApplication>int main(int argc, char *argv[])
{QApplication a(argc, argv);SwitchWidget w;w.show();return a.exec();
}

运行结果

image-20240625125930032

image-20240625125956501

image-20240625130018525

image-20240625130033826

相关文章:

Qt开发 | Qt界面布局 | 水平布局 | 竖直布局 | 栅格布局 | 分裂器布局 | setLayout使用 | 添加右键菜单 | 布局切换与布局删除重构

文章目录 一、Qt界面布局二、Qt水平布局--QHBoxLayout三、Qt竖直布局四、Qt栅格布局五、分裂器布局代码实现六、setLayout使用说明七、布局切换与布局删除重构1.如何添加右键菜单2.布局切换与布局删除重构 一、Qt界面布局 Qt的界面布局类型可分为如下几种 水平布局&#xff08;…...

LW-DETR: A Transformer Replacement to YOLO for Real-Time Detection

LW-DETR: A Transformer Replacement to YOLO for Real-Time Detection 论文链接&#xff1a;http://arxiv.org/abs/2406.03459 代码链接&#xff1a;https://github.com/Atten4Vis/LW-DETR 一、摘要 介绍了一种轻量级检测变换器LWDETR&#xff0c;它在实时物体检测方面超越…...

前端技术(二)——javasctipt 介绍

一、javascript基础 1. javascript简介 ⑴ javascript的起源 ⑵ javascript 简史 ⑶ javascript发展的时间线 ⑷ javascript的实现 ⑸ js第一个代码 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>…...

FireFox 编译指南2024 Windows10篇-环境准备(一)

1. 引言 在开源浏览器项目中&#xff0c;Firefox因其高性能和灵活性而备受开发者青睐。为了在本地环境中编译和定制Firefox&#xff0c;开发者需要做好充分的环境准备工作。这不仅是编译成功的基础&#xff0c;也是后续调试、优化和二次开发的关键步骤。 编译Firefox是一个复…...

Spring Boot中的热部署配置

Spring Boot中的热部署配置 大家好&#xff0c;我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编&#xff0c;也是冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01;今天我们将探讨如何在Spring Boot项目中实现热部署配置&#xff0c;提升开发效率和项…...

用ChatGPT快速打造一个专业WordPress网站

作为一个使用HostEase多年的老用户&#xff0c;我想和大家分享一下如何利用HostEase和ChatGPT快速构建一个WordPress网站的经验。这不仅仅是一个简单的操作步骤&#xff0c;更是一次从零到有的实战经历。希望我的分享能给你们带来一些实用的帮助。 获取主机服务和域名 首先&a…...

dsp入门

安装环境 安装 ccs5.5安装 BIOS-MCSDK 多核软件开发包安装 仿真器驱动 工程创建与导入工程 创建工程 创建工程填信息添加.cmd文件&#xff0c;配置内存编译 导入工程 导入 配置工程 选择properties 环境变量 头文件 库文件 仿真器 添加仿真器 先调出仿真器界面创建仿…...

Java并发编程-Atomiclnteger、LongAdder等原子类的使用及案例实战

文章目录 i++和Atomiclnteger之间的差别分析以及使用介绍i++AtomicInteger使用介绍i++ 示例AtomicInteger 示例总结Atomiclnteger中的CAS无锁化原理和思路介绍CAS 原理AtomicInteger 的 CAS 应用无锁化思路Atomiclnteger源码剖析:仅限JDK内部使用的Unsafe类`Unsafe` 类的关键作…...

九浅一深Jemalloc5.3.0 -- ②浅*size class

目前市面上有不少分析Jemalloc老版本的博文&#xff0c;但5.3.0却少之又少。而且5.3.0的架构与之前的版本也有较大不同&#xff0c;本着“与时俱进”、“由浅入深”的宗旨&#xff0c;我将逐步分析Jemalloc5.3.0的实现。 另外&#xff0c;单讲实现代码是极其枯燥的&#xff0c;…...

JavaScript——属性的增删改查

目录 任务描述 相关知识 属性的获取 方式一 方式二 属性的修改与新增 删除属性 编程要求 任务描述 Luma Restaurant 以前的财务人员在统计销售额的时候不小心把数据弄错了&#xff0c;现在的财务人员想通过一个 JavaScript 函数方便的修改数据&#xff0c;并署上自己的…...

51单片机第15步_串口多机通讯使用CRC8校验

本章重点介绍串口多机通讯使用CRC8校验。 数据格式:"$123xxxx*crc8\r\n"; 如:"$1234567890ABCDEF*06\r\n" 如:"$1231234567890*31\r\n" crc8是CRC校验值,为十六进制的ASCII码,不包含$和校验值前面的那个* #include <REG51.h> //包含…...

WPF----进度条ProgressBar(渐变色)

ProgressBar 是一种用于指示进程或任务的进度的控件&#xff0c;通常在图形用户界面&#xff08;GUI&#xff09;中使用。它提供了一种视觉反馈&#xff0c;显示任务的完成程度&#xff0c;帮助用户了解任务的进展情况。 基本特性 Minimum 和 Maximum 属性&#xff1a; 这些属…...

Apipost接口测试工具的原理及应用详解(四)

本系列文章简介&#xff1a; 随着软件行业的快速发展&#xff0c;API&#xff08;应用程序编程接口&#xff09;作为不同软件组件之间通信的桥梁&#xff0c;其重要性日益凸显。API的质量直接关系到软件系统的稳定性、性能和用户体验。因此&#xff0c;对API进行严格的测试成为…...

【图论】200. 岛屿问题

200. 岛屿问题 难度&#xff1a;中等 力扣地址&#xff1a;https://leetcode.cn/studyplan/top-100-liked/ 问题描述 给你一个由 1&#xff08;陆地&#xff09;和 0&#xff08;水&#xff09;组成的的二维网格&#xff0c;请你计算网格中岛屿的数量。 岛屿总是被水包围&…...

AI学习指南机器学习篇-随机森林的优缺点

AI学习指南机器学习篇-随机森林的优缺点 引言 机器学习是人工智能领域的重要分支&#xff0c;其中随机森林(Random Forest)算法以其高性能和广泛应用而备受瞩目。然而&#xff0c;就像任何其他算法一样&#xff0c;随机森林也有其优缺点。本文将深入探讨随机森林算法的优势和…...

基于boost::beast的http服务器(上)

文章目录 1.beast网落库介绍2.相关类及api3.异步读写的处理3.1异步写案例3.2异步读案例 1.beast网落库介绍 Beast网络库是一个基于Boost库的C网络库&#xff0c;特别用于开发高性能的网络应用程序。它提供了一组易于使用的API&#xff0c;主要用于处理HTTP和WebSocket协议&…...

深度学习之近端策略优化(Proximal Policy Optimization,PPO)

PPO(Proximal Policy Optimization,近端策略优化)是深度强化学习中的一种算法,属于策略梯度方法中的一种。PPO通过优化策略来最大化累积奖励,具有稳定性好、易于调参等优点,是目前广泛应用的一种深度强化学习算法。下面介绍PPO的基本原理和流程。 PPO基本原理 PPO算法的…...

用pycharm进行python爬虫的步骤

使用 pycharm 进行 python 爬虫的步骤&#xff1a;下载并安装 pycharm。创建一个新项目。安装 requests 和 beautifulsoup 库。编写爬虫脚本&#xff0c;包括获取页面内容、解析 html 和提取数据的代码。运行爬虫脚本。保存和处理提取到的数据。 用 PyCharm 进行 Python 爬虫的…...

重写功能 rewrite

Nginx服务器利用 ngx_http_rewrite_module 模块解析和处理rewrite请求&#xff0c;此功能依靠 PCRE(perl compatible regular expression)&#xff0c;因此编译之前要安装PCRE库&#xff0c;rewrite是nginx服务器的重要功能之 一&#xff0c;用于实现URL的重写&#xff0c;URL的…...

ISO19110操作要求类中/req/operation/operation-attributes的详细解释

/req/operation/operation-attributes 要求: 只有要素属性&#xff08;feature attributes&#xff09;可以通过‘observesValueOf’、‘triggeredByValuesOf’或‘affectsValuesOf’关联角色与要素操作&#xff08;feature operations&#xff09;关联。 具体解释 定义 要…...

龙虎榜——20250610

上证指数放量收阴线&#xff0c;个股多数下跌&#xff0c;盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型&#xff0c;指数短线有调整的需求&#xff0c;大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的&#xff1a;御银股份、雄帝科技 驱动…...

未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?

编辑&#xff1a;陈萍萍的公主一点人工一点智能 未来机器人的大脑&#xff1a;如何用神经网络模拟器实现更智能的决策&#xff1f;RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战&#xff0c;在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…...

Docker 离线安装指南

参考文章 1、确认操作系统类型及内核版本 Docker依赖于Linux内核的一些特性&#xff0c;不同版本的Docker对内核版本有不同要求。例如&#xff0c;Docker 17.06及之后的版本通常需要Linux内核3.10及以上版本&#xff0c;Docker17.09及更高版本对应Linux内核4.9.x及更高版本。…...

使用VSCode开发Django指南

使用VSCode开发Django指南 一、概述 Django 是一个高级 Python 框架&#xff0c;专为快速、安全和可扩展的 Web 开发而设计。Django 包含对 URL 路由、页面模板和数据处理的丰富支持。 本文将创建一个简单的 Django 应用&#xff0c;其中包含三个使用通用基本模板的页面。在此…...

Redis相关知识总结(缓存雪崩,缓存穿透,缓存击穿,Redis实现分布式锁,如何保持数据库和缓存一致)

文章目录 1.什么是Redis&#xff1f;2.为什么要使用redis作为mysql的缓存&#xff1f;3.什么是缓存雪崩、缓存穿透、缓存击穿&#xff1f;3.1缓存雪崩3.1.1 大量缓存同时过期3.1.2 Redis宕机 3.2 缓存击穿3.3 缓存穿透3.4 总结 4. 数据库和缓存如何保持一致性5. Redis实现分布式…...

STM32+rt-thread判断是否联网

一、根据NETDEV_FLAG_INTERNET_UP位判断 static bool is_conncected(void) {struct netdev *dev RT_NULL;dev netdev_get_first_by_flags(NETDEV_FLAG_INTERNET_UP);if (dev RT_NULL){printf("wait netdev internet up...");return false;}else{printf("loc…...

使用分级同态加密防御梯度泄漏

抽象 联邦学习 &#xff08;FL&#xff09; 支持跨分布式客户端进行协作模型训练&#xff0c;而无需共享原始数据&#xff0c;这使其成为在互联和自动驾驶汽车 &#xff08;CAV&#xff09; 等领域保护隐私的机器学习的一种很有前途的方法。然而&#xff0c;最近的研究表明&…...

Linux云原生安全:零信任架构与机密计算

Linux云原生安全&#xff1a;零信任架构与机密计算 构建坚不可摧的云原生防御体系 引言&#xff1a;云原生安全的范式革命 随着云原生技术的普及&#xff0c;安全边界正在从传统的网络边界向工作负载内部转移。Gartner预测&#xff0c;到2025年&#xff0c;零信任架构将成为超…...

Device Mapper 机制

Device Mapper 机制详解 Device Mapper&#xff08;简称 DM&#xff09;是 Linux 内核中的一套通用块设备映射框架&#xff0c;为 LVM、加密磁盘、RAID 等提供底层支持。本文将详细介绍 Device Mapper 的原理、实现、内核配置、常用工具、操作测试流程&#xff0c;并配以详细的…...

C#中的CLR属性、依赖属性与附加属性

CLR属性的主要特征 封装性&#xff1a; 隐藏字段的实现细节 提供对字段的受控访问 访问控制&#xff1a; 可单独设置get/set访问器的可见性 可创建只读或只写属性 计算属性&#xff1a; 可以在getter中执行计算逻辑 不需要直接对应一个字段 验证逻辑&#xff1a; 可以…...