【Qt常用控件】—— 布局管理器

目录

前言 

(一)垂直布局 

(二)水平布局

(三)网格布局

(四)表单布局

(五)分组布局

(六)Spacer

总结


前言 

之前使⽤Qt在界⾯上创建的控件,都是通过"绝对定位"的⽅式来设定的.

  • 也就是每个控件所在的位置,都需要计算坐标,最终通过 setGeometry 或者 move ⽅式摆放过去.这种设定⽅式其实并不方便.尤其是界⾯如果内容⽐较多,不好计算.而且⼀个窗口大小往往是可以调整的,按照绝对定位的⽅式,也⽆法⾃适应窗口⼤⼩.

因此Qt引⼊"布局管理器"(Layout)机制,来解决上述问题.

Qt的布局管理器(Layout Manager)是一种用于自动排列和调整窗口或容器中的控件的工具。它们可以完成以下两件事:

  1. 自动调整控件的位置,包括控件之间的间距、对齐等。
  2. 当用户调整窗口大小时,位于布局管理器内的控件也会随之调整大小,从而保持整个界面的美观。

Qt共提供了5种布局管理器,每种布局管理器对应一个类,分别是:

  1. QVBoxLayout(垂直布局):将所有控件从上到下(或者从下到上)依次摆放。
  2. QHBoxLayout(水平布局):包含的对象都横向排列开。
  3. QGridLayout(网格布局):将控件放置到网格中布局,它本身会从父窗口或父布局中占据尽可能多的界面空间,然后把自己的空间划分为行和列,再把每个控件塞到设置好的一个或多个单元格中。
  4. QFormLayout(表单布局):通常用于创建表单界面,其中控件成对出现,例如标签和输入框。
  5. QStackedLayout(分组布局):可以将多个控件堆叠在一起,但一次只能显示一个控件。这通常用于实现多页面的用户界面。

这些布局管理器都继承自QLayout类,这是Qt布局管理器的抽象基类。通过继承QLayout,Qt实现了功能各异且互补的布局管理器。

与绝对位置定位相比,布局管理器具有更高的灵活性和适应性。它们可以根据窗口的大小自动调整控件的大小和位置,而无需手动调整每个控件的位置和大小。这使得在开发用户界面时更加高效和方便。

🔥 当然,布局管理器并⾮Qt独有.其他的GUI开发框架,像Android,前端等也有类似的机制.


(一)垂直布局

使用 VBoxLayout 表示垂直的布局管理器.V是 vertical 的缩写.

在Qt中,垂直布局(QVBoxLayout)是一种常用的布局管理器,它可以将控件按照垂直方向进行排列。这种布局方式非常适用于需要从上到下依次排列控件的界面设计。

核心属性:

属性说明
layoutLeftMargin左侧边距
layoutRightMargin右侧边距
layoutTopMargin上方边距
layoutBottomMargin下方边距
layoutSpacing相邻元素之间的间距

🔥 注意Layout只是⽤于界⾯布局,并没有提供信号.

QVBoxLayout是一种布局管理器,具有以下特点:

  1. 垂直排列:控件会按照从上到下的顺序进行排列。

  2. 自动调整:当父窗口或容器的大小发生变化时,QVBoxLayout会自动调整其内部控件的大小和位置,以保持布局的整齐和美观。

  3. 可嵌套:QVBoxLayout可以嵌套在其他布局管理器中,如QHBoxLayout或QGridLayout,以实现更复杂的界面布局。

使用方法如下:

  1. 创建QVBoxLayout对象:首先,需要创建一个QVBoxLayout对象。这可以通过在代码中直接创建或使用Qt Designer进行设计后生成。

  2. 添加控件:然后,将需要排列的控件添加到QVBoxLayout中。这可以通过调用QVBoxLayout的addWidget()方法来实现。

  3. 设置布局:最后,将QVBoxLayout设置为某个窗口或容器的布局。这可以通过调用窗口或容器的setLayout()方法来实现。

代码示例:使用 QVBoxLayout 管理多个控件.

1)编写代码,创建布局管理器和三个按钮.并且把按钮添加到布局管理器中.

  • 使⽤ addWidget 把控件添加到布局管理器中.
  • 使⽤ setLayout 设置该布局管理器到widget中.
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    // 创建三个按钮
    QPushButton* btn1 = new QPushButton("按钮1");
    QPushButton* btn2 = new QPushButton("按钮2");
    QPushButton* btn3 = new QPushButton("按钮3");

    // 创建布局管理器, 并且把按钮添加进去
    // 如果创建的时候指定⽗元素为 this, 则后⾯不需要 setLayout ⽅法了.
    QVBoxLayout* layout = new QVBoxLayout();
    layout->addWidget(btn1);
    layout->addWidget(btn2);
    layout->addWidget(btn3);

    // 把布局管理器设置到 widget 中
    this->setLayout(layout);
}

2)运⾏程序,可以看到此时界⾯上的按钮就存在于布局管理器中.随着窗口尺寸变化而发⽣改变.

  •  此时三个按钮的尺⼨和位置,都是⾃动计算出来的.

  • 通过上述代码的方式,只能给这个widget设定⼀个布局管理器.实际上也可以过Qt Design在⼀个窗⼝中创建多个布局管理器.

代码示例:创建两个 QVBoxLayout

1)在界⾯上创建两个 QVBoxLayout ,每个 QVBoxLayout 各放三个按钮.

2)运行程序,可以看到这些按钮已经⾃动排列好.只不过当前这些按钮的位置不能随着窗⼝⼤⼩⾃动变化.


(二)水平布局

使⽤ QHBoxLayout 表⽰垂直的布局管理器.H是 horizontal 的缩写.

在Qt中,水平布局(Horizontal Layout)是一种常用的布局管理方式,它允许你将多个控件(如按钮、文本框等)水平地排列在一起。

核心属性(和QVBoxLayout 属性是⼀致的)

属性说明
layoutLeftMargin左侧边距
layoutRightMargin右侧边距
layoutTopMargin上方边距
layoutBottomMargin下方边距
layoutSpacing相邻元素之间的间距

代码示例:使用 QHBoxLayout 管理控件

1)编写代码,创建布局管理器和三个按钮.并且把按钮添加到布局管理器中.

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    // 创建三个按钮
    QPushButton* btn1 = new QPushButton("按钮1");
    QPushButton* btn2 = new QPushButton("按钮2");
    QPushButton* btn3 = new QPushButton("按钮3");

    // 创建布局管理器
    QHBoxLayout* layout = new QHBoxLayout();
    layout->addWidget(btn1);
    layout->addWidget(btn2);
    layout->addWidget(btn3);

    // 设置 layout 到 widget 上
    this->setLayout(layout);
}

2)运⾏程序,可以看到此时界⾯上的按钮就存在于布局管理器中.随着窗⼝尺⼨变化⽽发⽣改变.

  • 此时三个按钮的尺⼨和位置,都是⾃动计算出来的.

  • 注意:Layout⾥⾯可以再嵌套上其他的layout,从而达到更复杂的布局效果.

代码示例: 嵌套的layout

1)在代码中创建以下内容

  • 使⽤addLayout 给layout中添加⼦layout.
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    // 创建顶层 layout
    QVBoxLayout* layoutParent = new QVBoxLayout();
    this->setLayout(layoutParent);

    // 添加两个按钮进去
    QPushButton* btn1 = new QPushButton("按钮1");
    QPushButton* btn2 = new QPushButton("按钮2");
    layoutParent->addWidget(btn1);
    layoutParent->addWidget(btn2);

    // 创建⼦ layout
    QHBoxLayout* layoutChild = new QHBoxLayout();

    // 添加两个按钮进去
    QPushButton* btn3 = new QPushButton("按钮3");
    QPushButton* btn4 = new QPushButton("按钮4");
    layoutChild->addWidget(btn3);
    layoutChild->addWidget(btn4);

    // 把这个⼦ layout 添加到 ⽗ layout 中
    layoutParent->addLayout(layoutChild);
}

2)执行程序,观察结果

  • 结合 QHBoxLayout 和 QVBoxLayout ,就可以做出各种复杂的界⾯了。

(三)网格布局

Qt中还提供了QGridLayout ⽤来实现⽹格布局的效果.可以达到M*N的这种⽹格的效果

核心属性

  • 整体和 QVBoxLayout 以及 QHBoxLayout 相似.但是设置spacing的时候是按照垂直⽔平两个⽅向来设置的
属性说明
layoutLeftMargin左侧边距
layoutRightMargin右侧边距
layoutTopMargin上⽅边距
layoutBottomMargin下⽅边距
layoutHorizontalSpacing相邻元素之间⽔平⽅向的间距
layoutVerticalSpacing相邻元素之间垂直⽅向的间距
layoutRowStretch⾏⽅向的拉伸系数
layoutColumnStretch列⽅向的拉伸系数

代码示例:使用 QGridLayout 管理元素

1)代码中创建 QGridLayout 和4个按钮.

  • 使⽤ addWidget 添加控件到布局管理器中.但是添加的同时会指定两个坐标.表⽰放在第⼏⾏,第⼏列.
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    // 创建 4 个按钮
    QPushButton* btn1 = new QPushButton("按钮1");
    QPushButton* btn2 = new QPushButton("按钮2");
    QPushButton* btn3 = new QPushButton("按钮3");
    QPushButton* btn4 = new QPushButton("按钮4");

    // 创建⽹格布局管理器, 并且添加元素
    QGridLayout* layout = new QGridLayout();
    layout->addWidget(btn1, 0, 0);
    layout->addWidget(btn2, 0, 1);
    layout->addWidget(btn3, 1, 0);
    layout->addWidget(btn4, 1, 1);

    // 设置 layout 到窗⼝中.
    this->setLayout(layout);
}

2)执⾏代码,观察效果.可以看到当前的这⼏个按钮是按照2⾏2列的⽅式排列的.
 

3)如果调整⾏列坐标为下列代码

// 创建⽹格布局管理器, 并且添加元素
QGridLayout* layout = new QGridLayout();
layout->addWidget(btn1, 0, 0);
layout->addWidget(btn2, 0, 1);
layout->addWidget(btn3, 0, 2);
layout->addWidget(btn4, 0, 3);

执行代码,可以看到这⼏个按钮都在同⼀⾏了.相当于 QHBoxLayout

4)如果调整⾏列坐标为下列代码

QGridLayout* layout = new QGridLayout();
layout->addWidget(btn1, 1, 0);
layout->addWidget(btn2, 2, 0);
layout->addWidget(btn3, 3, 0);
layout->addWidget(btn4, 4, 0);

执行代码,可以看到这⼏个按钮都在同⼀列了.相当于 QVBoxLayout

5)任意调整⾏列,即可看到不同的效果.

// 创建⽹格布局管理器, 并且添加元素
QGridLayout* layout = new QGridLayout();
layout->addWidget(btn1, 0, 0);
layout->addWidget(btn2, 1, 1);
layout->addWidget(btn3, 2, 2);
layout->addWidget(btn4, 3, 3);

 代码示例:设置 QGridLayout 中元素的大小⽐例

1)创建6个按钮,按照2⾏3列的⽅式排列

  • 使用 setColumnStretch 设置每⼀列的拉伸系数.
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    // 创建 6 个按钮
    QPushButton* btn1 = new QPushButton("按钮1");
    QPushButton* btn2 = new QPushButton("按钮2");
    QPushButton* btn3 = new QPushButton("按钮3");
    QPushButton* btn4 = new QPushButton("按钮4");
    QPushButton* btn5 = new QPushButton("按钮5");
    QPushButton* btn6 = new QPushButton("按钮6");

    // 创建⽹格布局管理器, 并且添加元素
    QGridLayout* layout = new QGridLayout();
    layout->addWidget(btn1, 0, 0);
    layout->addWidget(btn2, 0, 1);
    layout->addWidget(btn3, 0, 2);
    layout->addWidget(btn4, 1, 0);
    layout->addWidget(btn5, 1, 1);
    layout->addWidget(btn6, 1, 2);

    // 设置拉伸⽐例
    // 第 0 列拉伸⽐例设为 1;
    layout->setColumnStretch(0, 1);
    // 第 1 列拉伸⽐例设为 0, 即为固定⼤⼩, 不参与拉伸
    layout->setColumnStretch(1, 0);
    // 第 2 列拉伸⽐例设为 3, 即为第 2 列的宽度是第 0 列的 3 倍
    layout->setColumnStretch(2, 3);

    // 设置 layout 到窗⼝中.
    this->setLayout(layout);
}

2)执行程序,可以看到每⼀列的宽度是不同的.并且随着窗⼝调整动态变化

  • 另外, QGridLayout 也提供了 setRowStretch 设置⾏之间的拉伸系数.
  • 上述案例中,直接设置 setRowStretch 效果不明显,因为每个按钮的⾼度是固定的.需要把按钮的垂直⽅向的 sizePolicy 属性设置为 QSizePolicy::Expanding 尽可能填充满布局管理器,才能看到效果.

 使⽤ setSizePolicy 设置按钮的尺⼨策略.可选的值如下:

  • QSizePolicy::Ignored :忽略控件的尺⼨,不对布局产⽣影响。
  • QSizePolicy::Minimum :控件的最⼩尺⼨为固定值,布局时不会超过该值。
  • QSizePolicy::Maximum :控件的最⼤尺⼨为固定值,布局时不会⼩于该值。
  • QSizePolicy::Preferred :控件的理想尺⼨为固定值,布局时会尽量接近该值。
  • QSizePolicy::Expanding :控件的尺⼨可以根据空间调整,尽可能占据更多空间。
  • QSizePolicy::Shrinking :控件的尺⼨可以根据空间调整,尽可能缩⼩以适应空间。
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    // 创建 6 个按钮

    QPushButton* btn1 = new QPushButton("按钮1");
    QPushButton* btn2 = new QPushButton("按钮2");
    QPushButton* btn3 = new QPushButton("按钮3");
    QPushButton* btn4 = new QPushButton("按钮4");
    QPushButton* btn5 = new QPushButton("按钮5");
    QPushButton* btn6 = new QPushButton("按钮6");

    // 设置按钮的 sizePolicy, 此时按钮的⽔平⽅向和垂直⽅向都会尽量舒展开
    btn1->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
    btn2->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
    btn3->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
    btn4->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
    btn5->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
    btn6->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);

    // 创建⽹格布局管理器, 并且添加元素
    QGridLayout* layout = new QGridLayout();
    layout->addWidget(btn1, 0, 0);
    layout->addWidget(btn2, 0, 1);
    layout->addWidget(btn3, 1, 0);
    layout->addWidget(btn4, 1, 1);
    layout->addWidget(btn5, 2, 0);
    layout->addWidget(btn6, 2, 1);

    // 设置拉伸⽐例
    // 第 0 ⾏拉伸⽐例设为 1;
    layout->setRowStretch(0, 1);
    // 第 1 ⾏拉伸⽐例设为 0, 即为固定⼤⼩, 不参与拉伸
    layout->setRowStretch(1, 0);
    // 第 2 ⾏拉伸⽐例设为 3, 即为第 2 ⾏的宽度是第 0 ⾏的 3 倍
    layout->setRowStretch(2, 3);

    // 设置 layout 到窗⼝中.
    this->setLayout(layout);
}

 此时的按钮垂直⽅向都舒展开了.并且调整窗⼝尺⼨,也会按照设定的⽐例同步变化

  • 总的来说,使⽤ QGridLayout 能够代替很多 QHBoxLayout 和 QVBoxLayout 嵌套的场景.毕竟嵌套的代码写起来是⽐较⿇烦的.
  • 另外不要忘了, QGridLayout ⾥⾯也能嵌套 QHBoxLayout 和 QVBoxLayout ,QHBoxLayout和QVBoxLayout ⾥⾯也能嵌套 QGridLayout

(四)表单布局

除了上述的布局管理器之外,Qt还提供了 QFormLayout ,属于是 QGridLayout 的特殊情况,专门用于实现两列表单的布局.

  • 这种表单布局多⽤于让⽤⼾填写信息的场景.左侧列为提⽰,右侧列为输⼊框.

代码示例:使⽤ QFormLayout 创建表单.

1)编写代码,创建 QFormLayout ,以及三个label和三个lineEdit

  • 使⽤ addRow ⽅法来添加⼀⾏.每⾏包含两个控件.第⼀个控件固定是QLabel/⽂本,第⼆个控件则可以是任意控件.
  • 如果把第⼀个参数填写为NULL,则什么都不显示.
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    // 创建 layout
    QFormLayout* layout = new QFormLayout();
    this->setLayout(layout);

    // 创建三个 label
    QLabel* label1 = new QLabel("姓名");
    QLabel* label2 = new QLabel("年龄");
    QLabel* label3 = new QLabel("电话");

    // 创建三个 lineEdit
    QLineEdit* lineEdit1 = new QLineEdit();
    QLineEdit* lineEdit2 = new QLineEdit();
    QLineEdit* lineEdit3 = new QLineEdit();

    // 创建⼀个提交按钮
    QPushButton* btn = new QPushButton("提交");

    // 把上述元素添加到 layout 中
    layout->addRow(label1, lineEdit1);
    layout->addRow(label2, lineEdit2);
    layout->addRow(label3, lineEdit3);

    layout->addRow(NULL, btn);
}

2)执行程序,可以看到以下结果.


(五)分组布局

在Qt中,分组布局(Stacked Layout)通常通过QStackedLayoutQStackedWidget来实现。这种布局方式允许你将多个控件或窗口部件堆叠在一起,但每次只显示其中一个。这对于需要动态切换界面的应用程序特别有用。

举个简单的例子,下图中的界面就使用了 QStackedLayout 布局管理器:

【解释说明】 

  • 整个窗口被一分为二,左侧是 QListWidget 列表控件,右侧是 QStackedLayout 布局管理器。QStackedLayout 中包含 QPushButonn、QLabel 和 QLineEdit 这 3 个控件,但每次只能 3 个控件中的一个。 

常用方法

成员方法功 能
int QStackedLayout::addWidget(QWidget *widget)将 widget 控件添加到 QStackedLayout 控件中。
int QStackedLayout::insertWidget(int index, QWidget *widget)将 widget 控件插入到 QStackedLayout 控件指定的位置处。
信号函数功 能
void QStackedLayout::currentChanged(int index)切换当前显示的控件时,会触发此信号,index 为显示的新控件的索引。
void QStackedLayout::widgetRemoved(int index)移除某个控件时,会触发此信号,index 为被移除控件的索引。
槽函数功 能
void setCurrentIndex(int index)将第 index 个控件作为要显示的控件。
void QStackedLayout::setCurrentWidget(QWidget *widget)设置 widget 作为当前要实现的控件。注意,必须保证 widget 存储在 QStackedLayout 控件中。

(六)Spacer

使⽤布局管理器的时候,可能需要在控件之间,添加⼀段空⽩.就可以使⽤ QSpacerItem 来表示.

核心属性

属性说明
width宽度
height⾼度
hData⽔平⽅向的sizePolicy
• QSizePolicy::Ignored :忽略控件的尺⼨,不对布局产⽣影响。
• QSizePolicy::Minimum :控件的最⼩尺⼨为固定值,布局时不会超过该值。
• QSizePolicy::Maximum :控件的最⼤尺⼨为固定值,布局时不会⼩于该值。
• QSizePolicy::Preferred :控件的理想尺⼨为固定值,布局时会尽量接近。
值。
• QSizePolicy::Expanding :控件的尺⼨可以根据空间调整,尽可能占据更多空
间。
• QSizePolicy::Shrinking :控件的尺⼨可以根据空间调整,尽可能缩⼩以适应
空间。
vData垂直⽅向的sizePolicy
选项同上.

代码示例:创建⼀组左右排列的按钮.

1)在界⾯上创建⼀个 QVBoxLayout ,并添加两个按钮.

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    QHBoxLayout* layout = new QHBoxLayout();
    this->setLayout(layout);

    QPushButton* btn1 = new QPushButton("按钮1");
    QPushButton* btn2 = new QPushButton("按钮2");

    layout->addWidget(btn1);
    layout->addWidget(btn2);
}

2)直接运行程序,可以看到两个按钮是紧挨着的.

3)在两个按钮中间添加⼀个spacer

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    QHBoxLayout* layout = new QHBoxLayout();
    this->setLayout(layout);

    QPushButton* btn1 = new QPushButton("按钮1");
    QPushButton* btn2 = new QPushButton("按钮2");

    // 创建 Spacer
    QSpacerItem* spacer = new QSpacerItem(200, 20);
    layout->addWidget(btn1);

    // 在两个 widget 中间添加空⽩
    layout->addSpacerItem(spacer);
    layout->addWidget(btn2);
}

4)运行程序,观察代码效果.可以看到两个按钮之间已经存在了间隔了.

  • 调整QSpacerItem不同的尺⼨,即可看到不同的间距.

其次在Qt Designer中,也可以直接给界⾯上添加spacer.


总结

Qt布局管理器是Qt框架中用于自动调整和管理界面组件位置和大小的重要工具。以下是关于Qt布局管理器的小结:

  1. 作用与功能
    • 解决组件位置和大小无法自适应父窗口变化的问题。
    • 自动调整控件的位置,包括控件之间的间距、对齐等。
    • 当用户调整窗口大小时,位于布局管理器内的控件也会随之调整大小,保持界面的美观。
    • 无需手动调整每个控件的位置和大小,简化界面设计流程。
  2. 核心类与继承
    • QLayout是Qt布局管理器的抽象基类。
    • Qt提供了多种继承自QLayout的布局管理器类,如水平布局(QHBoxLayout)、垂直布局(QVBoxLayout)、网格布局(QGridLayout)和表单布局(QFormLayout)等。
  3. 优势
    • 自适应窗口大小和屏幕分辨率:Qt布局管理器能够自动调整控件的位置和大小,以适应不同的窗口大小和屏幕分辨率,确保应用程序在不同设备上都能良好显示。
    • 简化界面设计:布局管理器使得控件的排列和布局变得更加简单和直观,开发者可以更快地完成用户界面的设计。
    • 管理控件之间的关系:布局管理器可以管理控件之间的关系,如控件的对齐方式、间距等,使界面的设计更加协调和美观。
  4. 使用方法
    • 在Qt Designer中,可以通过拖拽布局管理器到界面中,然后向其中添加控件来创建布局。
    • 在代码中,可以使用布局管理器的构造函数和成员函数来创建和管理布局。例如,可以使用addWidget()函数向布局中添加控件,使用setSpacing()函数设置控件之间的间距等。

总之,Qt布局管理器是Qt框架中用于创建和维护良好用户界面的重要工具。通过合理使用布局管理器,可以大大提高应用程序的用户体验。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

听说部门来了个00后测试开发,一顿操作给我整麻了

公司新来了个同事,听说大学是学的广告专业,因为喜欢IT行业就找了个培训班,后来在一家小公司实习半年,现在跳槽来我们公司。来了之后把现有项目的性能优化了一遍,服务器缩减一半,性能反而提升4倍&#xff01…

HTML静态网页成品作业(HTML+CSS)——动漫熊出没介绍网页(3个页面)

🎉不定期分享源码,关注不丢失哦 文章目录 一、作品介绍二、作品演示三、代码目录四、网站代码HTML部分代码 五、源码获取 一、作品介绍 🏷️本套采用HTMLCSS,未使用Javacsript代码,共有3个页面。 二、作品演示 三、代…

使用`War`包部署`Jenkins`(超级详细)

使用War包部署Jenkins(超级详细) 别着急,你看这年复一年,春光不必趁早,冬霜不会迟到。过去的都会过去,该来的都在路上,一切都是刚刚好。 网站说明 https://get.jenkins.io/war-stable/ war包下载地址 https://www.jenk…

AIGC笔记--基于PEFT库使用LoRA

1--相关讲解 LORA: LOW-RANK ADAPTATION OF LARGE LANGUAGE MODELS LoRA 在 Stable Diffusion 中的三种应用:原理讲解与代码示例 PEFT-LoRA 2--基本原理 固定原始层,通过添加和训练两个低秩矩阵,达到微调模型的效果; 3--简单代…

boost asio异步服务器(2)实现伪闭包延长连接生命周期

闭包 在函数内部实现一个子函数,子函数的作用域内能访问外部函数的局部变量。闭包就是能够读取其他函数内部变量。但是由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成程的性能问题&#x…

没开玩笑!高速信号不能参考电源网络这条规则,其实很难做到

高速先生成员--黄刚 看到这篇文章的题目,我相信大家心里都呈现出了这么一个场景:高速信号线在L20层,我只要把L19和L21层都铺上完整的地平面,这不就满足了高速信号线不能参考电源平面这条规则了吗?这难道很难做到吗&…

51驱动DY-SV20F语音播放模块

51驱动DY-SV20F语音播放模块 简介模块特征电气参数工作模式配置原理图代码结果图 简介 DY-SV20F 是一款一对一分段触发控制播放器,支持 MP3,WAV 解码格式; 可分段触发 9 首曲目;低电平触发;3.7-5VDC 宽电压供电,直驱 …

expect自动交互

在执行命令或脚本的时候,当控制台提示我们需要输入账号密码、参数等信息的时候,expect可以将预设的参数值自动输入到控制台,实现了自动交互。 1. 安装expect yum install expect 2. 案例: 创建 demo.exp 文件,并添…

英语四级翻译练习笔记③——大学英语四级考试2023年12月真题(第三套)

目录 引言(必看) 四级翻译评分标准分析及真题解析 四级翻译评分标准 四级翻译真题 学生作答 1. 评分 2. 修正翻译中的错误 错误标记: 3. 改正句子 4. 标出错误单词 5. 标准答案 6. 常考万能句子 7.重点单词的中文意思 引言&…

移动应用程序设计详解:基本概念和原理

移动应用程序设计是什么? 一般来说,应用程序设计师的核心职责是让用户有体验应用的欲望,而开发者负责让它正常工作。移动应用程序设计包括用户界面 (UI) 和用户体验 (UX)。设计者负责应用程序的整体风格,包括配色方案、字体选择、…

关于如何通过APlayer+MetingJS为自己的wordpress博客网页添加网易音乐播放器(无需插件)

本文转自博主的个人博客:https://blog.zhumengmeng.work,欢迎大家前往查看。 原文链接:点我访问 序言:最近在网上冲浪,发现大家的博客大部分都有一个音乐播放器能够播放音乐,随机我也开始寻找解决方法。可是找来找去我…

达梦数据库查看字符集、页大小

1.查看字符集select UNICODE (); 0 表示 GB18030,1 表示 UTF-8,2 表示 EUC-KR 2.查看页大小select SF_GET_PAGE_SIZE(); 也可以通过管理工具去查看

【组合数学 放球问题 虚拟点 小于等于转小于】1621. 大小为 K 的不重叠线段的数目

本文涉及知识点 放球问题 组合数学汇总 本题难道分:2198 LeetCode1621. 大小为 K 的不重叠线段的数目 给你一维空间的 n 个点,其中第 i 个点(编号从 0 到 n-1)位于 x i 处,请你找到 恰好 k 个不重叠 线段且每个线段…

菊花链通信技术整理

目录 一、菊花链简介 二、菊花链与CAN通信的区别 三、常见的菊花链AFE芯片 四、菊花链数据结构 五、菊花链方案介绍 一、菊花链简介 首先简单的说一下菊花链以及菊花链的应用,在目前国内的BMS开发中,我们应用最广泛的目前还还是分布式,…

代码随想录算法训练营第七天| 454.四数相加II 、383. 赎金信、 15. 三数之和、18. 四数之和

454.四数相加II 题目链接: 454.四数相加II 文档讲解:代码随想录 状态:没做出来,没想到考虑重复的情况! 题解: public int fourSumCount(int[] nums1, int[] nums2, int[] nums3, int[] nums4) {// 结果计数…

java的变量关系~使用和扩展

一、变量的概述 1、什么是变量 白话:变量就是一个装东西的盒子。 通俗:变量是用于存放数据的容器。我们通过变量名 获取数据,甚至数据可以修改。 2、变量在内存中的存储 本质:变量是程序在内存中申请的一块用来存放数据的空间,类似我们酒店的房间&a…

基于多源数据的微服务系统失败测试用例诊断

简介 本文介绍由南开大学、华为云及清华大学共同合作的论文:基于多源数据的微服务系统失败测试用例诊断。该论文已被FSE 2024(The ACM International Conference on the Foundations of Software Engineering) 会议录用,论文标题为: Fault D…

JS中的数组很重要,怎样定义(声明)

为什么呢?在java中有集合,数组的作用就弱了,其高光时刻基本都被集合代替了。在JS中没有集合,数组就有点忙不过来了。你说它重要不重要?! 在JS中,怎样定义一个数组呢? 数组的声明方…

动手学操作系统(二、编写MBR主引导记录)

动手学操作系统(二、编写MBR主引导记录) 文章目录 动手学操作系统(二、编写MBR主引导记录)1. 实模式和保护模式2. BIOS与MBR3. MBR程序Reference 在之前的学习内容中,我们已经实现了基本的仿真环境bochs的搭建&#xf…

【Linux】数据链路层协议+ICMP协议+NAT技术

欢迎来到Cefler的博客😁 🕌博客主页:折纸花满衣 🏠个人专栏:Linux 目录 👉🏻数据链路层👉🏻以太网以太网帧格式网卡Mac地址对比ip地址 👉🏻MTUMTU…