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

news2024/12/23 13:46:55

文章目录

  • 一、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_OBJECT

public:
    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_OBJECT

public:
    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_OBJECT

public:
    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_OBJECT

public:
    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);
    //左侧widget
    QWidget* pLeftWidget = new QWidget(this);
    pLeftWidget->setStyleSheet("background-color:rgb(54, 54, 54)");
    pLeftWidget->setMinimumWidth(200);

    //分裂器添加widget
    pHSplitter->addWidget(pLeftWidget);

    //右侧的竖直分裂器
    QSplitter* pVSplitter = new QSplitter(Qt::Vertical, pHSplitter);

    //在拖动到位并弹起鼠标后再显式分隔条
    pVSplitter->setOpaqueResize(false);

    //右侧顶部widget
    QWidget* 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_OBJECT

public:
    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_OBJECT

public:
    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.coloradmin.cn/o/1860546.html

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

相关文章

【ai】tx2 nx :安装torch、torchvision for yolov5

torchvision 是自己本地构建的验证torchvision nvidia@tx2-nx:~/twork/03_yolov5/torchvision$ nvidia@tx2-nx:~/twork/03_yolov5/torchvision$ python3 Python 3.6.9 (default, Mar 10 2023, 16:46:00) [GCC 8.4.0] on linux Type "help", "copyright",…

乐鑫ESP32-WROOM-32E模组设备低功耗控制方案,启明云端乐鑫代理商

在数字化浪潮的推动下&#xff0c;物联网&#xff08;IoT&#xff09;正迅速成为我们日常生活的一部分。而在这个领域中&#xff0c;ESP32-WROOM-32E模组以其卓越的性能和多功能性&#xff0c;成为了开发者和制造商的选择。 ESP32-WROOM-32E模组集成了ESP32-D0WD-V3芯片&#…

迁移学习——CycleGAN——循环一致性对抗网络

CycleGAN 1.导入需要的包2.数据加载&#xff08;1&#xff09;to_img 函数&#xff08;2&#xff09;数据加载&#xff08;3&#xff09;图像转换 3.随机读取图像进行预处理&#xff08;1&#xff09;函数参数&#xff08;2&#xff09;数据路径&#xff08;3&#xff09;读取文…

NAS安全存储怎样实现更精细的数据权限管控?

NAS存储&#xff0c;即网络附属存储&#xff08;Network Attached Storage&#xff09;&#xff0c;是一种专用数据存储服务器&#xff0c;其核心特点在于将数据存储设备与网络相连&#xff0c;实现集中管理数据的功能。 NAS存储具有以下明显优势&#xff0c;而被全球范围内的企…

vncsever ,window 远程ubuntu远程界面安装方式,VNC Viewer安装教程+ linux配置server 操作

linux 端安装 # 安装VNC 服务器软件 sudo apt install autocutsel # 剪切黏贴操作支持的包 sudo apt-get install tightvncserver # 安装的是 VNC 服务器软件,用于远程桌面访问 # 安装Xfce桌面环境 sudo apt-get install xfce4 xfce4-goodies #安装的是 XFCE 桌面环境和其…

EXCEL表格怎么批量删除日期后的时间?

竞价师最近有点忙了&#xff0c;因为百度新出来一个“线索有效性诊断”功能 一、下载电话、表单、咨询表格 二、选中整列 三、选中ctrlf 进行替换&#xff0c;日期输入空格&#xff0c;时间输入*&#xff0c;替换为空即可&#xff01; 四、整列单元格格式“日期”拉倒底部&…

正则表达式以及文本三剑客grep、sed、awk

正则表达式匹配的是文本内容&#xff0c;文本三剑客都是针对文本内容。 grep&#xff1a;过滤文本内容 sed&#xff1a;针对文本内容进行增删改查 awk&#xff1a;按行取列 一、grep grep的作用使用正则表达式来匹配文本内容 1、grep选项 -m&#xff1a;匹配几次之后停止…

知识付费小程序源码系统 构建知识交易新平台 带完整的安装代码包+搭建部署教程

系统概述 随着互联网技术的不断发展&#xff0c;人们获取信息的方式发生了巨大改变。传统的知识传播方式已经无法满足人们日益多样化的需求&#xff0c;知识付费逐渐成为一种趋势。同时&#xff0c;移动互联网的普及使得小程序成为人们生活中不可或缺的一部分&#xff0c;利用…

拓扑排序-体育课测验(二)

目录 一、问题描述 二、解答思路 三、代码实现 四、刷题链接 一、问题描述 二、解答思路 拓扑排序&#xff1a; 1.设置一个入度数组&#xff0c;构建图的邻接矩阵的同时对入度数组进行初始化 2.执行结点个数次的循环&#xff0c;每次循环都统计入度数组中的入度为0的结点P&…

如何以管理员身份运行CMD?

好久没更新博客了&#xff0c;今天在日常使用中遇到了一个问题&#xff0c;顺便记录下来。 据说国内的谷歌浏览器 Chrome 可以自动升级了&#xff0c;终于不用每次都自己跑去官网下载最新版本&#xff0c;然后安装迁移&#xff0c;重复劳动。下一篇讲如何讲迁移 Chrome&#x…

面试-java并发与多线程的部分函数

1.sleep和wait的区别 基本的差别&#xff1a; Sleep是Thread的方法。Wait是object方法。Wait不传参&#xff0c;最终也是调用wait(native)的传参方法。 Sleep方法可以在任何地方使用。 Wait方法只能在synchronized方法或synchronized方法块中使用。 最主要的本质区别&#xf…

pdf压缩,pdf压缩在线,pdf文件太大怎么变小

在数字化时代&#xff0c;PDF文档因其跨平台、保持原样、易于阅读和打印等特点&#xff0c;成为了我们日常工作和生活中不可或缺的一部分。然而&#xff0c;随着PDF文件的不断累积&#xff0c;存储空间逐渐变得紧张&#xff0c;特别是在处理大量大型PDF文件时&#xff0c;如何有…

qlv格式转换成mp4格式,qlv转换成mp4格式软件工具转换器

在当今的互联网时代&#xff0c;视频格式转换已成为我们日常生活中的一项常见任务。其中&#xff0c;qlv转MP4的需求尤为突出&#xff0c;本文将详细介绍qlv转MP4的几种方法&#xff0c;帮助大家转换视频格式&#xff0c;我们一起来看下。 方法一&#xff1a; 1、使用 "小…

突发!OpenAI停止不支持国家API,7月9日开始执行

6月25日凌晨&#xff0c;有部分开发者收到了OpenAI的信&#xff0c;“根据数据显示&#xff0c;你的组织有来自OpenAl目前不支持的地区的API流量。从7月9日起&#xff0c;将采取额外措施&#xff0c;停止来自不在OpenAI支持的国家、地区名单上的API使用。” 但这位网友表示&am…

如何申请免费SSL证书以消除访问网站显示连接不安全提醒

在当今互联网时代&#xff0c;网络安全已成为一个不可忽视的问题。当用户浏览一些网站时&#xff0c;有时会看到浏览器地址栏出现“不安全”的提示&#xff0c;这意味着该网站没有安装SSL证书&#xff0c;数据传输可能存在风险。那么&#xff0c;如何消除这种不安全提醒&#x…

ONLYOFFICE 桌面编辑器 8.1全新发布,更强大的编辑工具

ONLYOFFICE 8.1 一、什么是ONLYOFFICE&#xff1f;二、怎么安装 ONLYOFFICE 8.1三、主要功能介绍四、总结 一、什么是ONLYOFFICE&#xff1f; ONLYOFFICE 是一款功能强大的办公套件&#xff0c;旨在提供全面的文档、表格和演示文稿编辑解决方案。它集成了文字处理、电子表格和演…

webstorm无法识别@路径的问题,左键无法跳转

在项目根目录下创建 webstorm.config.js use strict; const webpackConfig require(vue/cli-service/webpack.config.js); module.exports webpackConfig;webstorm设置里找到以下位置&#xff0c;引入新建的 webstorm.config.js即可&#xff0c;不生效把webstorm重启一下

LED显示屏的点间距越小越好吗

引言 在LED显示屏市场日趋成熟的同时&#xff0c;小间距显示屏成为了许多用户的首选。然而&#xff0c;点间距真的是越小越好吗&#xff1f;本文将探讨这一问题&#xff0c;并提供全面的选购指南。 点间距&#xff1a;并非越小越好 小间距显示屏因其精细的显示效果而备受青睐。…

推荐一款好用的编辑工具——onlyoffice桌面编辑器8.1

读者大大们好呀&#xff01;&#xff01;!☀️☀️☀️ &#x1f525; 欢迎来到我的博客 &#x1f440;期待大大的关注哦❗️❗️❗️ &#x1f680;欢迎收看我的主页文章➡️寻至善的主页 文章目录 &#x1f525;前言&#x1f680;版本更新概览&#x1f697;文档编辑PDF编辑器…

Vue - HTML基础学习

一、元素及属性 1.元素 <p>我是一级标题</p>2.嵌套元素 把元素放到其他元素之中——这被称作嵌套。 <p>我是<strong>一级</strong>标题</p>3.块级元素 块级元素在页面中以块的形式展现&#xff0c;会换行&#xff0c;可嵌套内联元素。 …