Qt入门小项目 | WPS tab页面(无边框窗口综合应用)

news2024/11/18 23:41:34

文章目录

  • 一、手写代码实现WPS tab页面

一、手写代码实现WPS tab页面

  实现类似WPS tab效果,具体包含:

  • 自定义标题栏:最大、最小、关闭
  • 在QTabWidget的tab上增加控件
  • 在QTabWidget的tab上右键菜单
  • 可拖拽移动
  • 可拉伸窗口
  • 双击标题栏在最大与正常间切换

补充:如何给QTabWidget的左右tab栏增加控件

void QTabWidget::setCornerWidget(QWidget *widget, Qt::Corner corner = Qt::TopRightCorner)

setCornerWidget 函数用于在标签控件(QTabWidget)的指定角落显示给定的控件(widget)。

参数:

  • QWidget *widget:指向要在角落显示的控件的指针。

  • Qt::Corner corner:一个可选参数,指定控件要显示在标签控件的哪个角落。默认值是 Qt::TopRightCorner,即右上角。

    enum Corner {
        TopLeftCorner = 0x00000,
        TopRightCorner = 0x00001,
        BottomLeftCorner = 0x00002,
        BottomRightCorner = 0x00003
    };
    

代码示例:
CTabTitleWidget.h

/*
tabWidget右侧的widget控件
*/

#pragma once

#include <QWidget>
#include <QPushButton>

class CTabTitleWidget : public QWidget
{
	Q_OBJECT

public:
	CTabTitleWidget(QWidget* parent = nullptr);
	~CTabTitleWidget();

	void setEmptyWidgetWidth(int w);

protected:
	void paintEvent(QPaintEvent* event) override;
	void mousePressEvent(QMouseEvent* event) override;
	void mouseDoubleClickEvent(QMouseEvent* event);

signals:
	void sig_close();
	void sig_addtab();

private slots:
	void on_Clicked();

private:
	QPushButton* m_pAddBtn = nullptr;
	QWidget*     m_pEmptyWidget = nullptr;
	QPushButton* m_pUserBtn = nullptr;
	QPushButton* m_pMinBtn = nullptr;
	QPushButton* m_pMaxBtn = nullptr;
	QPushButton* m_pCloseBtn = nullptr;
};

CTabTitleWidget.cpp

#include "CTabTitleWidget.h"
#include <QHBoxLayout>
#include <QMouseEvent>
#include <QStyleOption>
#include <QPainter>

#ifdef Q_OS_WIN
#include <qt_windows.h>
#pragma comment(lib, "user32.lib")
#endif

CTabTitleWidget::CTabTitleWidget(QWidget* parent)
{
    setStyleSheet("background-color:#E3E4E7");
	m_pAddBtn = new QPushButton(this);
    m_pAddBtn->setFlat(true);
    m_pAddBtn->setFixedSize(32, 32);
    m_pAddBtn->setStyleSheet("background-image:url(:/WPSDemo/resources/add.svg)");

    m_pEmptyWidget = new QWidget(this);

    m_pUserBtn = new QPushButton(this);
    m_pUserBtn->setFlat(true);
    m_pUserBtn->setFixedSize(32, 32);
    m_pUserBtn->setStyleSheet("background-image:url(:/WPSDemo/resources/user)");

	m_pMinBtn = new QPushButton(this);
    m_pMinBtn->setFlat(true);
    m_pMinBtn->setFixedSize(32, 32);
    m_pMinBtn->setStyleSheet("background-image:url(:/WPSDemo/resources/min.svg)");

	m_pMaxBtn = new QPushButton(this);
    m_pMaxBtn->setFlat(true);
    m_pMaxBtn->setFixedSize(32, 32);
    m_pMaxBtn->setStyleSheet("background-image:url(:/WPSDemo/resources/max.svg)");

	m_pCloseBtn = new QPushButton(this);
    m_pCloseBtn->setFlat(true);
    m_pCloseBtn->setFixedSize(32, 32);
    m_pCloseBtn->setStyleSheet("background-image:url(:/WPSDemo/resources/close.svg)");

	QHBoxLayout* pHLay = new QHBoxLayout(this);
    pHLay->addWidget(m_pAddBtn);
    pHLay->addWidget(m_pEmptyWidget);
    this->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Expanding);  //水平策略为最大值
    pHLay->addWidget(m_pUserBtn);
    pHLay->addSpacing(8);
    pHLay->addWidget(m_pMinBtn);
    pHLay->addWidget(m_pMaxBtn);
    pHLay->addWidget(m_pCloseBtn);
    pHLay->setContentsMargins(1, 0, 1, 3);
    setLayout(pHLay);

    connect(m_pAddBtn, &QPushButton::clicked, this, &CTabTitleWidget::on_Clicked);
    connect(m_pMinBtn, &QPushButton::clicked, this, &CTabTitleWidget::on_Clicked);
    connect(m_pMaxBtn, &QPushButton::clicked, this, &CTabTitleWidget::on_Clicked);
    connect(m_pCloseBtn, &QPushButton::clicked, this, &CTabTitleWidget::on_Clicked);
}

CTabTitleWidget::~CTabTitleWidget()
{
}

void CTabTitleWidget::setEmptyWidgetWidth(int w)
{
    m_pEmptyWidget->setMinimumWidth(w);
}

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

//处理鼠标按下事件--无边框窗口拖拽移动的解决办法
void CTabTitleWidget::mousePressEvent(QMouseEvent* event)
{
    if (ReleaseCapture())
    {
        QWidget* pWindow = this->window();
        if (pWindow->isTopLevel())
        {
            SendMessage(HWND(pWindow->winId()), WM_SYSCOMMAND, SC_MOVE + HTCAPTION, 0);
        }
    }

    event->ignore();
}

//双击放大与恢复正常模式
void CTabTitleWidget::mouseDoubleClickEvent(QMouseEvent* event)
{
    emit m_pMaxBtn->clicked();
}

//四个按钮链接到一个槽函数
void CTabTitleWidget::on_Clicked()
{
    QPushButton* pButton = qobject_cast<QPushButton*>(sender());

    QWidget* pWindow = this->window();

    if (pWindow->isTopLevel())
    {
        if (pButton == m_pAddBtn)
        {
            emit sig_addtab();
        }
        else if (pButton == m_pMinBtn)
        {
            pWindow->showMinimized();
        }
        else if (pButton == m_pMaxBtn)
        {
            pWindow->isMaximized() ? pWindow->showNormal() : pWindow->showMaximized();
        }
        else if (pButton == m_pCloseBtn)
        {
            emit sig_close();
        }
    }
}

CTabBrowser.h

/*

  自定义QTabWidget实现浏览器tab样式

*/

#pragma once
  
#include <QTabWidget>   
#include <QMenu> 
#include "CTabTitleWidget.h"
  

class CTabBrowser : public QTabWidget  
{  
    Q_OBJECT  

public:  
    explicit CTabBrowser(QWidget *parent = 0);  

    //tab操作标志
    enum TAB_FLAG
    {
        NEW,
        CLOSE,
        NORMAL,
        SPECIAL
    };
        
protected:  
    void resizeEvent(QResizeEvent *e) override;

private:
    void initTabWidget();   //初始化Tab
    void setTabBarFlag(TAB_FLAG flag);  //基于Tab操作设置样式
    void createTabMenu();  //创建菜单
  
private slots:  
    void on_newTab();   //新建tab
    void on_closeTab(int index);    //关闭Tab
    void onMenuShow(const QPoint& pos); //显示菜单
    void on_closeAllTab();  //关闭所有Tab

signals:
    void sig_close();

private:
    CTabTitleWidget* m_pRightWidget = nullptr;
    QMenu* m_pTabMenu = nullptr;
};  

CTabBrowser.cpp

#include "tabbrowser.h"  
#include <QDebug>  
#include <QPushButton>
#include <QHBoxLayout>
#include <QMessageBox>
#include <QTabBar>

QString qss0 = "QTabBar::tab{ \
            font: 75 12pt Arial; \
            text-align:left; \
            width:184px; \
            height:32; \
            background:#FFFFFF; \
            border:2px solid #FFFFFF; \
            border-bottom-color:#FFFFFF; \
            border-top-left-radius:4px; \
            border-top-right-radius:4px; \
            padding:2px; \
            margin-top:0px; \
            margin-right:1px; \
            margin-left:1px;  \
            margin-bottom:0px;} \
        QTabBar::tab:selected{  \
            color:#333333; /*文字颜色*/  \
            background-color:#FFFFFF;} \
        QTabBar::tab:!selected{ \
            color:#B2B2B2; \
            border-color:#FFFFFF;} \
        QTabBar::scroller{width: 0px;}";

QString qss1 = "QTabBar::tab{ \
            font: 75 12pt Arial; \
            text-align:left; \
            width:184px; \
            height:32; \
            background:#FFFFFF; \
            border:2px solid #FFFFFF; \
            border-bottom-color:#FFFFFF; \
            border-top-left-radius:4px; \
            border-top-right-radius:4px; \
            padding:2px; \
            margin-top:0px; \
            margin-right:1px; \
            margin-left:1px;  \
            margin-bottom:0px;} \
        QTabBar::tab:selected{  \
            color:#333333; /*文字颜色*/  \
            background-color:#FFFFFF;} \
        QTabBar::tab:!selected{ \
            color:#B2B2B2; \
            border-color:#FFFFFF;} \
        QTabBar::scroller{width: 36px;}";
  
CTabBrowser::CTabBrowser(QWidget *parent) :  
    QTabWidget(parent)  
{  
    this->addTab(new QWidget,u8"稻壳");  

    this->setUsesScrollButtons(true);  //滚动鼠标可切换tab
    this->setTabsClosable(true);       //显示tab右侧的关闭按钮
    this->setMovable(true);            //tab可移动位置

    initTabWidget();
    setTabBarFlag(NORMAL);

    this->setStyleSheet(qss0);

    connect(this, &QTabWidget::tabCloseRequested,this, &CTabBrowser::on_closeTab);
}  
  
void CTabBrowser::resizeEvent(QResizeEvent *e)  
{  
    setTabBarFlag(NORMAL);
    QTabWidget::resizeEvent(e);  
}

void CTabBrowser::createTabMenu()   //创建菜单
{
    m_pTabMenu = new QMenu(this);

    QAction* pAcSave = new QAction(QIcon(":/WPSDemo/resources/save.png"), u8"保存", m_pTabMenu);
    m_pTabMenu->addAction(pAcSave);

    connect(pAcSave, &QAction::triggered, [=] {
        QMessageBox::information(this, u8"提示", u8"你点击了 保存");
        });

    QAction* pAcSaveAs = new QAction(QString(u8"另存为"), m_pTabMenu);
    m_pTabMenu->addAction(pAcSaveAs);

    m_pTabMenu->addSeparator();

    QAction* pAcShareDoc = new QAction(QIcon(":/WPSDemo/resources/share.png"), QString(u8"分享文档"), m_pTabMenu);
    m_pTabMenu->addAction(pAcShareDoc);

    QAction* pAcSendToDevice = new QAction(QString(u8"发送到设备"), m_pTabMenu);
    m_pTabMenu->addAction(pAcSendToDevice);

    m_pTabMenu->addSeparator();

    QAction* pAcNewName = new QAction(QString(u8"重命名"), m_pTabMenu);
    m_pTabMenu->addAction(pAcNewName);

    QAction* pAcSaveToWPSCloud = new QAction(QString(u8"保存到WPS云文档"), m_pTabMenu);
    m_pTabMenu->addAction(pAcSaveToWPSCloud);

    QAction* pAcCloseAll = new QAction(QString(u8"关闭所有文件"), m_pTabMenu);
    m_pTabMenu->addAction(pAcCloseAll);
    connect(pAcCloseAll, &QAction::triggered, this, &CTabBrowser::on_closeAllTab);
}

//基于Tab操作设置样式
void CTabBrowser::setTabBarFlag(TAB_FLAG flag)
{  
    int w = this->width();

    int tabsWidth = 0;  //所有tab的总宽度
    int tabsHeight = tabBar()->height();  
    int tabs = this->count();  

    if (flag == NEW || flag == NORMAL)
    {
        for (int i = 0; i < tabs; ++i)
        {
            tabsWidth += tabBar()->tabRect(i).width();  //用于获取 QTabWidget 中索引为 i 的标签页的宽度
        }  
    }
    else
    {
        for (int i = 0;i < tabs - 1;++i)
        {
            tabsWidth += tabBar()->tabRect(i).width();   //用于获取 QTabWidget 中索引为 i 的标签页的宽度
        }  
    }  
  
    if (w > tabsWidth)
    {
        m_pRightWidget->setEmptyWidgetWidth(w - tabsWidth - 32 * 5 - 15);
        this->setStyleSheet(qss0);
    }
    else
    {
        //当所有tab的宽度大于整个tabWidget的宽时
        m_pRightWidget->setEmptyWidgetWidth(150);
        this->setStyleSheet(qss1);
    }  
}  

//初始化Tab
void CTabBrowser::initTabWidget()
{  
    //修改菜单策略
    this->setContextMenuPolicy(Qt::CustomContextMenu);  //自定义上下文菜单策略
    connect(this, &QTabWidget::customContextMenuRequested, this, &CTabBrowser::onMenuShow);
    createTabMenu();    //创建菜单

    m_pRightWidget = new CTabTitleWidget(this);

    this->setCornerWidget(m_pRightWidget, Qt::TopRightCorner);  //标题栏放到Tab右侧
    connect(m_pRightWidget, &CTabTitleWidget::sig_addtab, this, &CTabBrowser::on_newTab);
    connect(m_pRightWidget, &CTabTitleWidget::sig_close, this, &CTabBrowser::sig_close);
}  
 
//新建tab
void CTabBrowser::on_newTab()
{  
	int nCount = count();
	QString  title = QString::number(nCount);
    title = "Page" + title;

    // 这里写的有问题,应该是 insertTab
    this->addTab(new QWidget, title);

    if (!tabsClosable())
    {
        setTabsClosable(true);  
    }  

    setTabBarFlag(NEW);
}  

void CTabBrowser::on_closeTab(int index)
{  
    widget(index)->deleteLater();  
    setTabBarFlag(CLOSE);

    //当只剩下1个tab时
    if (count() == 1)
    {
        setTabsClosable(false);  
        setTabBarFlag(SPECIAL);
    }  
}  
 
void CTabBrowser::onMenuShow(const QPoint& pos)
{
    int index = this->tabBar()->tabAt(pos);

#ifdef _DEBUG
    qDebug() << u8"当前tab为:" << QString::number(index);
    this->setCurrentIndex(index);
#endif

    if (index != -1)
    {
        m_pTabMenu->exec(QCursor::pos());
    }
}

void CTabBrowser::on_closeAllTab()
{
}

WPSDemo.h

#pragma once

#include <QtWidgets/QWidget>

class WPSDemo : public QWidget
{
    Q_OBJECT

public:
    WPSDemo(QWidget *parent = Q_NULLPTR);

protected:
    bool nativeEvent(const QByteArray& eventType, void* message, long* result) override;

private slots:
    void on_close();

private:
    int     m_BorderWidth = 5; //表示鼠标位于边框缩放范围的宽度
};

WPSDemo.cpp

#include "WPSDemo.h"
#include "tabbrowser.h"
#include <QHBoxLayout>

#ifdef Q_OS_WIN
#include <qt_windows.h>
#include <Windows.h>
#include <windowsx.h>
#endif

#pragma comment(lib, "user32.lib")
#pragma comment(lib,"dwmapi.lib")

WPSDemo::WPSDemo(QWidget *parent)
    : QWidget(parent)
{
	this->resize(600, 400);
    setWindowFlags(Qt::FramelessWindowHint | Qt::WindowMinMaxButtonsHint);	//无边框窗口
	setStyleSheet("background-color:#E3E4E7");

    CTabBrowser* pTab = new CTabBrowser(this);

    QHBoxLayout* pHLay = new QHBoxLayout(this);
    pHLay->addWidget(pTab);
	pHLay->setContentsMargins(6, 6, 6, 6);
    setLayout(pHLay);

	connect(pTab, &CTabBrowser::sig_close, this, &WPSDemo::on_close);
}

void WPSDemo::on_close()
{
	/*
	其它业务逻辑
	*/

	close();
}

bool WPSDemo::nativeEvent(const QByteArray& eventType, void* message, long* result)
{
	Q_UNUSED(eventType)

		MSG* param = static_cast<MSG*>(message);

	switch (param->message)
	{
	case WM_NCHITTEST:
	{
		int nX = GET_X_LPARAM(param->lParam) - this->geometry().x();
		int nY = GET_Y_LPARAM(param->lParam) - this->geometry().y();

		// 如果鼠标位于子控件上,则不进行处理
		if (childAt(nX, nY) != nullptr)
			return QWidget::nativeEvent(eventType, message, result);

		// 鼠标区域位于窗体边框,进行缩放
		if ((nX > 0) && (nX < m_BorderWidth))
			*result = HTLEFT;

		if ((nX > this->width() - m_BorderWidth) && (nX < this->width()))
			*result = HTRIGHT;

		if ((nY > 0) && (nY < m_BorderWidth))
			*result = HTTOP;

		if ((nY > this->height() - m_BorderWidth) && (nY < this->height()))
			*result = HTBOTTOM;

		if ((nX > 0) && (nX < m_BorderWidth) && (nY > 0)
			&& (nY < m_BorderWidth))
			*result = HTTOPLEFT;

		if ((nX > this->width() - m_BorderWidth) && (nX < this->width())
			&& (nY > 0) && (nY < m_BorderWidth))
			*result = HTTOPRIGHT;

		if ((nX > 0) && (nX < m_BorderWidth)
			&& (nY > this->height() - m_BorderWidth) && (nY < this->height()))
			*result = HTBOTTOMLEFT;

		if ((nX > this->width() - m_BorderWidth) && (nX < this->width())
			&& (nY > this->height() - m_BorderWidth) && (nY < this->height()))
			*result = HTBOTTOMRIGHT;

		return true;
	}
	}

	return QWidget::nativeEvent(eventType, message, result);
}

main.cpp

#include "WPSDemo.h"
#include <QtWidgets/QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    WPSDemo w;
    w.show();
    return a.exec();
}

运行结果
image-20240630180959376

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

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

相关文章

14-10 AIGC 项目生命周期——第一阶段

生成式 AI 项目生命周期的整个过程类似于从范围、选择、调整和对齐/协调模型以及应用程序集成开始的顺序依赖过程。流程表明每个步骤都建立在前一步的基础上。有必要了解每个阶段对于项目的成功都至关重要。 下面的流程图重点介绍了生成式 AI 项目生命周期的第一阶段 1 — “范…

vue项目创建+eslint+Prettier+git提交规范(commitizen+hooks+husk)

# 步骤 1、使用 vue-cli 创建项目 这一小节我们需要创建一个 vue3 的项目&#xff0c;而创建项目的方式依然是通过 vue-cli 进行创建。 不过这里有一点大家需要注意&#xff0c;因为我们需要使用最新的模板&#xff0c;所以请保证你的 vue-cli 的版本在 4.5.13 以上&#xff…

Android 添加LBS辅助定位

1.软件需求&#xff1a; 某Android设备没有sim卡但其支持定位&#xff0c;客户需求为在已有的Android中添加LBS网络定位&#xff0c;用以辅助gps定位。 2.思路分析 首先看到这个需求笔者是比较懵逼的&#xff0c;秉持着客户是上帝的原则&#xff0c;笔者首先先了解了一下什么…

双向广搜——AcWing 190. 字串变换

双向广搜 定义 双向广搜是图搜索算法的一种变体&#xff0c;与传统的单向广搜不同&#xff0c;它同时从起点和终点&#xff08;或目标状态&#xff09;开始进行搜索&#xff0c;直到两个搜索的前沿相遇为止。这种方法可以在某些情况下显著减少搜索空间&#xff0c;尤其是在寻…

安装PyTorch详细过程(个人过程仅供参考)

1.安装anaconda 2.创建一个虚拟环境 以上步骤默认已经完毕&#xff0c;毕竟只是记录pytorch的安装过程 3.查看个人电脑CUDA版本 winr 输入cmd 回车 输入指令 nvidia-smi 右上角为该电脑所支持的最高CUDA版本 输入命令 nvcc -V 图中即为该电脑所安装的CUDA版本 记住该版…

为什么安装了SSL证书还是不能HTTPS访问?

即便是正确安装了SSL证书&#xff0c;有时网站仍然无法通过HTTPS正常访问&#xff0c;这背后可能隐藏着多种原因。以下是一些常见的问题及解决方案&#xff0c;帮助您排查并解决这一困扰。 PC点此申请&#xff1a;SSL证书申请_https证书下载-极速签发 注册填写注册码230918&a…

文献解读-长读长测序-第十三期|《PrecisionFDA真相挑战第二版:利用短读长和长读长在难比对区域进行变异检测》

关键词&#xff1a;基因组&#xff1b;长读长测序&#xff1b;基准测试&#xff1b; 文献简介 标题&#xff08;英文&#xff09;&#xff1a;PrecisionFDA Truth Challenge V2: Calling variants from short and long reads in difficult-to-map regions标题&#xff08;中文…

零基础光速入门AI绘画,SD保姆攻略

前言 大家好&#xff0c;我是AI绘画咪酱。一名AIGC狂热爱好者&#xff0c;目前正在AI绘画领域进行深入的探索。 我花了一个月时间把SD研究了一遍&#xff0c;秉持着用有趣、易懂的文字让小白也可以零基础光速使用SD&#xff08;stable diffusion&#xff09;入门AI绘画&#…

家政小程序的开发,带动市场快速发展,提高家政服务质量

当下生活水平逐渐提高&#xff0c;也增加了年轻人的工作压力&#xff0c;同时老龄化也在日益增加&#xff0c;使得大众对家政的需求日益提高&#xff0c;能力、服务质量高的家政人员能够有效提高大众的生活幸福指数。 但是&#xff0c;传统的家政服务模式存在着效率低、用户与…

Java语法系列 小白入门参考资料 逻辑控制

顺序结构 顾名思义&#xff0c;就是按着从上到下的顺序执行代码 public class Demo {public static void main(String[] args) {System.out.println("aaa");System.out.println("bbb");System.out.println("ccc");} }如果调整代码的书写顺序, …

手撕Transformer!!从每一模块原理讲解到代码实现【超详细!】

文章目录 一、位置编码位置编码的原理代码解释 二、多头注意力三、前馈神经网络&#xff08;FeedForward&#xff09;和层归一化&#xff08;NormLayer&#xff09;FeedForward 模块代码解析 NormLayer 模块代码解析 四、EncoderEncoder 类EncoderLayer 类前向传播过程 五、Dec…

喜提一等奖!白鲸开源在“创业北京”创业创新大赛海淀区选拔赛决赛表现亮眼

6月25日&#xff0c;第七届“创业北京”创业创新大赛海淀区选拔赛决赛在中关村东升国际科学园成功举办。本次活动由海淀区人力资源和社会保障局、中关村科学城管委会主办&#xff0c;以“创响新时代 共圆中国梦”为主题&#xff0c;活动现场主体赛先进制造赛道和主体赛现代服务…

网络安全在2024好入行吗?

前言 024年的今天&#xff0c;慎重进入网安行业吧&#xff0c;目前来说信息安全方向的就业对于学历的容忍度比软件开发要大得多&#xff0c;还有很多高中被挖过来的大佬。 理由很简单&#xff0c;目前来说&#xff0c;信息安全的圈子人少&#xff0c;985、211院校很多都才建立…

网站提示不安全怎么办

当您访问一个网站时&#xff0c;如果浏览器提示该网站不安全&#xff0c;这通常意味着以下几个问题之一&#xff0c;以及相应的解决办法&#xff1a; 一、未启用HTTPS协议&#xff1a; 解决方法&#xff1a;确保网站启用了HTTPS协议。这意味着您需要为您的网站部署一个有效的…

2024年最适合Python小白的零基础入门教程!

伴随着云计算、大数据、AI等技术的迅速崛起&#xff0c;市场对Python人才的需求和市场人才的匮乏&#xff0c;让长期沉默的Python语言一下子备受众人的关注&#xff0c;再加上简单易学&#xff0c;使得Python一跃成为TIOBE排行榜的第一。 准备学Python或者想学Python的小伙伴们…

1.linux操作系统CPU负载

目录 概述CPU平均负载查看平均负载结束 概述 CPU 使用率 和CPU 平均使用率。 CPU平均负载 单位时间内系统处于 [可运行状态] 和 [不可中断状态] 的平均进程数&#xff0c;就是平均活跃进程数&#xff0c;和CPU使用率并没有直接关系 可运行状态 正在使用CPU或者正等待CPU的进…

ITK-读取/写入图像

作者&#xff1a;翟天保Steven 版权声明&#xff1a;著作权归作者所有&#xff0c;商业转载请联系作者获得授权&#xff0c;非商业转载请注明出处 绪论 在本文中&#xff0c;将介绍如何使用ITK&#xff08;Insight Segmentation and Registration Toolkit&#xff09;库来读取…

【毕业一年,聊聊什么】

毕业一年&#xff0c;聊聊什么 一&#xff0c;引子 武汉&#xff0c;大雨连连&#xff0c;大雨如柱&#xff0c;大雨倾盆&#xff0c;任性的&#xff0c;傲娇的&#xff0c;一点没有想停的样子。 下雨天&#xff0c;好适合Emo啊&#xff0c;该我了&#xff0c;请允许。 二&…

Meilisearch 安装和使用教程

如今搜索功能已成为几乎所有应用不可或缺的一部分。无论是电商平台、内容管理系统&#xff0c;还是企业内部知识库&#xff0c;用户都期待能够快速、准确地找到他们需要的信息。然而&#xff0c;传统的搜索解决方案往往面临着诸多挑战&#xff1a;响应速度慢、相关性差、难以适…

分享值得推荐的6大磁力搜索器平台,亲测有效!

昨天晚上&#xff0c;隔壁出租屋的小美私信阿星&#xff0c;问哪里能下载到有趣的资源&#xff0c;比如漫画、影音、学习资料等等。 这直接问到了阿星的强项了&#xff01;其实网络上&#xff0c;高手和小白之间&#xff0c;只差一个搜索引擎。 今天阿星想和大家分享几款好用…