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

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

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

相关文章

木各力“GERRI”被“GREE”格力无效宣告成功

近日“GERRI”被“GREE”格力无效宣告成功&#xff0c;“GERRI”和“GREE”近似不&#xff0c;如果很近似当初就不会通过初审和下商标注册证&#xff0c;但是如果涉及知名商标和驰名商标&#xff0c;人家就可以异议和无效。 “GERRI”在被无效宣告时&#xff0c;引用了6个相关的…

【python刷题】【深基5.例5】旗鼓相当的对手

题目描述 算法思路 用二维数组data存放成绩数据。双重循环遍历所有的组合&#xff0c;因为自己不能和自己比&#xff0c;所以要注意内层遍历的起始位置。新建一个数组用来得出各个科目的分差&#xff0c;便于代码的书写。由于分差计算出来会出现负数&#xff0c;所以比较的时候…

探索MySQL核心技术:理解索引和主键的关系

在数据密集型应用中&#xff0c;数据库的性能往往是决定一个应用成败的重要因素之一。其中&#xff0c;MySQL作为一种开源关系型数据库管理系统&#xff0c;以其卓越的性能和丰富的功能被广泛应用。而在MySQL数据库优化的众多技巧中&#xff0c;索引和主键扮演着极其重要的角色…

Windows怎么实现虚拟IP

在做高可用架构时&#xff0c;往往需要用到虚拟IP&#xff0c;在linux上面有keepalived来实现虚拟ip的设置。在windows上面该怎么弄&#xff0c;keepalived好像也没有windows版本&#xff0c;我推荐一款浮动IP软件PanguVip&#xff0c;它可以实现windows上面虚拟ip的漂移。设置…

WordPress中文网址导航栏主题风格模版HaoWa

模板介绍 WordPress响应式网站中文网址导航栏主题风格模版HaoWa1.3.1源码 HaoWA主题风格除行为主体导航栏目录外&#xff0c;对主题风格需要的小控制模块都开展了敞开式的HTML在线编辑器方式的作用配备&#xff0c;另外预埋出默认设置的编码构造&#xff0c;便捷大伙儿在目前…

常用字符串方法<python>

导言 在python中内置了许多的字符串方法&#xff0c;使用字符串方法可以方便快捷解决很多问题&#xff0c;所以本文将要介绍一些常用的字符串方法。 目录 导言 string.center(width[,fillchar]) string.capitalize() string.count(sub[,start[,end]]) string.join(iterabl…

Qt学习之ui创建串口助手

一、串口简介 二、Qt编写串口助手 1、创建Qt工程 选择MinGW 64-bit 点击下一步完成&#xff0c;工程创建完成。 使用串口模块&#xff0c;需要在工程文件.pro中添加以下代码&#xff0c;不添加的话&#xff0c;会报错。 或者在core gui 后输入 serialport 也可以 2、配置UI…

【Unity】RPG2D龙城纷争(六)关卡编辑器之角色编辑

更新日期&#xff1a;2024年6月26日。 项目源码&#xff1a;第五章发布&#xff08;正式开始游戏逻辑的章节&#xff09; 索引 简介一、角色编辑模式1.将字段限制为只读2.创建角色&#xff08;刷角色&#xff09;3.预览所有角色4.编辑选中角色属性5.移动角色位置6.移除角色 简介…

vue中【事件修饰符号】详解

在Vue中&#xff0c;事件修饰符是一种特殊的后缀&#xff0c;用于修改事件触发时的默认行为。以下是Vue中常见的事件修饰符的详细解释&#xff1a; .stop 调用event.stopPropagation()&#xff0c;阻止事件冒泡。当你在嵌套元素中都有相同的事件监听器&#xff08;如click事件…

【Linux系统】进程替换 自主实现shell(简易版)

1.先看代码 && 现象 我们用exec*函数执行新的程序&#xff0c; exec*系列的函数&#xff0c;执行完毕后&#xff0c;后续的代码不见了&#xff0c;因为被替换了。 execl的返回值可以不关心了&#xff0c;只要替换成功&#xff0c;就不会向后继续运行&#xff0c;只要…

单片机是否有损坏,怎沫判断

目录 1、操作步骤&#xff1a; 2、单片机损坏常见原因&#xff1a; 3、 单片机不工作的原因&#xff1a; 参考&#xff1a;细讲寄存器读写与Bit位操作原理--单片机C语言编程Bit位的与或非屏蔽运算--洋桃电子大百科P019_哔哩哔哩_bilibili 1、操作步骤&#xff1a; 首先需要…

前置章节-熟悉Python、Numpy、SciPy和matplotlib

目录 一、编程环境-使用jupyter notebook 1.下载homebrew包管理工具 2.安装Python环境 3.安装jupyter 4.下载Anaconda使用conda 5.使用conda设置虚拟环境 二、学习Python基础 1.快排的Python实现 (1)列表推导-一种创建列表的简洁方式 (2)列表相加 2.基本数据类型及运…

Navicat上新啦

前言 Navicat&#xff0c;在数据库界&#xff0c;几乎是一个神奇的存在&#xff0c;似乎统治了数据库开发工具的“一片天”。且看下图&#xff1a; 红的蓝的绿的橙的…&#xff0c;可以说&#xff0c;留给它的color不多了。 那么商业BI到服务监控、从云托管到云协作&#xff…

最强文生图模型Stable Diffusion 3 Medium 正式开源

Stability AI 宣布 Stable Diffusion 3 Medium 现已开源&#xff0c;是 Stable Diffusion 3 系列中最新、最先进的文本生成图像 AI 模型 —— 官方声称是 “迄今为止最先进的开源模型”&#xff0c;其性能甚至超过了 Midjourney 6。 Stable Diffusion 3 Medium 模型规格参数达到…

【鸿蒙学习笔记】位置设置

官方文档&#xff1a;位置设置 目录标题 align&#xff1a;子元素的对齐方式direction&#xff1a;官方文档没懂&#xff0c;看图理解吧 align&#xff1a;子元素的对齐方式 Stack() {Text(TopStart)}.width(90%).height(50).backgroundColor(0xFFE4C4).align(Alignment.TopS…

Spring+Vue集成AOP系统日志

新建logs表 添加aop依赖 <!-- aop依赖--> <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId> </dependency> 新建获取ip地址工具类 import javax.servlet.http.H…

昇思25天学习打卡营第12天|ShuffleNet图像分类

1. 学习内容复盘 ShuffleNet网络介绍 ShuffleNetV1是旷视科技提出的一种计算高效的CNN模型&#xff0c;和MobileNet, SqueezeNet等一样主要应用在移动端&#xff0c;所以模型的设计目标就是利用有限的计算资源来达到最好的模型精度。ShuffleNetV1的设计核心是引入了两种操作&a…

自然语言处理:第三十八章: 开箱即用的SOTA时间序列大模型 -Timsfm

自然语言处理:第三十八章: 开箱即用的SOTA时间序列大模型 -Timsfm 文章链接:[2310.10688] A decoder-only foundation model for time-series forecasting (arxiv.org) 项目链接: google-research/timesfm: TimesFM (Time Series Foundation Model) is a pretrained time-ser…

【FFmpeg】avformat_alloc_output_context2函数

【FFmpeg】avformat_alloc_output_context2函数 1.avformat_alloc_output_context21.1 初始化AVFormatContext&#xff08;avformat_alloc_context&#xff09;1.2 格式猜测&#xff08;av_guess_format&#xff09;1.2.1 遍历可用的fmt&#xff08;av_muxer_iterate&#xff0…

C : 线性规划例题求解

Submit Page TestData Time Limit: 1 Sec Memory Limit: 128 Mb Submitted: 93 Solved: 49 Description 求解下述线性规划模型的最优值min &#xfffd;1&#xfffd;1&#xfffd;2&#xfffd;2&#xfffd;3&#xfffd;3&#xfffd;.&#xfffd;. &…