Qt之修改窗口标题、图标以及自定义标题栏(九)

Qt开发 系列文章 - titles-icons-titlebars(九)


目录

前言

一、修改标题

二、添加图标

三、更换标题栏

1.效果演示

2.创建标题栏类

3.定义相关函数

4.使用标题栏类

总结


前言

在我们利用Qt设计软件时,经常需要修改窗口标题、更改软件图标等之类的操作,更有甚者需要更换标题栏(因为Qt自带的窗口标题栏无法自定义)。这时需要用到QIcon类、QPixmap类等等相关基础功能的操作,以下是关于如何在不同场景中添加图标、修改标题、更换标题栏(自定义标题栏)的简单例子。


一、修改标题

本文提供修改软件窗口标题的方式有两种。

  • 第一种直接在软件初始化函数(即构造函数)添加如下代码。
MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);this->setWindowTitle("我的窗口");
}
  • 第二种,打开项目可视化UI设计界面,在上面进行修改,如下图所示。

以上两种方法修改完后,编译运行,会看到显示如下。

二、添加图标

添加图标的方式有多种,本文提供如下几种供参考。不管有几种实现方式,首先第一步是先把有图标的文件添加本项目路劲下面。

  • 第一种方式,打开项目pro文件,添加如下代码。
win32:RC_ICONS +=  $$PWD/ico/A_tubiao.ico
  • 第二种方式,在软件初始化函数(即构造函数)添加如下代码。
MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);this->setWindowTitle("我的窗口");this->setWindowIcon(QIcon(QDir::currentPath() + "/ico/A_tubiao.ico"));
}
  • 第三种方式,打开项目可视化UI设计界面,在上面进行修改,如下图所示。

上面添加完后,会有如下显示,说明添加成功。

以上几种方法修改完后,编译运行,会看到显示如下。

三、更换标题栏

Qt是一个跨平台的框架,它旨在提供在不同操作系统上都能保持一致的用户界面体验。Qt自带的窗口标题栏通常遵循操作系统的默认样式和布局,以确保在不同平台上都能提供一致且符合用户期望的用户体验,因此Qt自带的窗口标题栏无法自定义。

尽管Qt自带的窗口标题栏无法自定义,但可以通过一些方法来实现自定义标题栏的效果。例如,可以隐藏系统自带的标题栏(通过设置窗口标志Qt::FramelessWindowHint),然后自行设计一个包含所需功能(如最小化、最大化、关闭按钮等)的自定义标题栏。下面本文将提供一种自定义标题栏。

1.效果演示

2.创建标题栏类

在我们原有的项目上,添加新的类文件,选择C++设计类的模版,选择如下。

然后,定义类的名称为MyTitleBar,代码如下(示例):

#ifndef MYTITLEBAR_H
#define MYTITLEBAR_H#include <QWidget>enum ButtonType
{MIN_BUTTON = 0,         // 最小化和关闭按钮;MIN_MAX_BUTTON ,        // 最小化、最大化和关闭按钮;ONLY_CLOSE_BUTTON       // 只有关闭按钮;
};
class MyTitleBar : public QWidget
{Q_OBJECT
public:MyTitleBar(QWidget *parent);~MyTitleBar();void setBackgroundColor(int r, int g, int b , bool isTransparent = false);void setTitleIcon(QString filePath , QSize IconSize = QSize(25 , 25));void setTitleContent(QString titleContent , int titleFontSize = 9);void setTitleWidth(int width);void setButtonType(ButtonType buttonType);void setTitleRoll();void setWindowBorderWidth(int borderWidth);void saveRestoreInfo(const QPoint point, const QSize size);void getRestoreInfo(QPoint& point, QSize& size);
private:void paintEvent(QPaintEvent *event);void mouseDoubleClickEvent(QMouseEvent *event);void mousePressEvent(QMouseEvent *event);void mouseMoveEvent(QMouseEvent *event);void mouseReleaseEvent(QMouseEvent *event);void initControl();void initConnections();void loadStyleSheet(const QString &qssFile);
signals:void signalchangeStyle(const QString &qssFile);void signalButtonMinClicked();void signalButtonRestoreClicked();void signalButtonMaxClicked();void signalButtonCloseClicked();
private slots:void onButtonchangeStyle();void onButtonMinClicked();void onButtonRestoreClicked();void onButtonMaxClicked();void onButtonCloseClicked();void onRollTitle();
private:QLabel* m_pIcon;                    // 标题栏图标;QLabel* m_pTitleContent;            // 标题栏内容;QToolButton *m_pButtonMenu;         // 色彩菜单QPushButton* m_pButtonMin;          // 最小化按钮;QPushButton* m_pButtonRestore;      // 最大化还原按钮;QPushButton* m_pButtonMax;          // 最大化按钮;QPushButton* m_pButtonClose;        // 关闭按钮;int m_colorR;int m_colorG;int m_colorB;QPoint m_restorePos;QSize m_restoreSize;bool m_isPressed;QPoint m_startMovePos;QTimer m_titleRollTimer;QString m_titleContent;ButtonType m_buttonType;int m_windowBorderWidth;bool m_isTransparent;
};
#endif // MYTITLEBAR_H

3.定义相关函数

上面我们定义标题栏类的头文件,下面来说明相关功能函数。

#include "mytitlebar.h"
#include <QHBoxLayout>
#include <QPainter>
#include <QFile>
#include <QMouseEvent>
#include <QAction>
MyTitleBar::MyTitleBar(QWidget *parent): QWidget(parent), m_colorR(0), m_colorG(153), m_colorB(153), m_isPressed(false), m_buttonType(MIN_MAX_BUTTON), m_windowBorderWidth(0), m_isTransparent(false)
{// 初始化;initControl();// 信号槽的绑定;initConnections();// 加载本地样式 MyTitle.css文件;//loadStyleSheet("MyTitle");
}
// 初始化控件;
void MyTitleBar::initControl()
{// 定义按键变量m_pIcon = new QLabel;m_pTitleContent = new QLabel;m_pButtonMenu = new QToolButton;m_pButtonMin = new QPushButton;m_pButtonRestore = new QPushButton;m_pButtonMax = new QPushButton;m_pButtonClose = new QPushButton;QSizePolicy sizePolicy3(QSizePolicy::Fixed, QSizePolicy::Expanding);sizePolicy3.setHorizontalStretch(0);sizePolicy3.setVerticalStretch(0);sizePolicy3.setHeightForWidth(m_pButtonMenu->sizePolicy().hasHeightForWidth());m_pButtonMenu->setSizePolicy(sizePolicy3);m_pButtonMenu->setMinimumSize(QSize(30, 0));m_pButtonMenu->setMaximumSize(QSize(30, 16777215));m_pButtonMenu->setFocusPolicy(Qt::NoFocus);m_pButtonMenu->setPopupMode(QToolButton::InstantPopup);// 设置按键大小m_pButtonMin->setFixedSize(QSize(30, 30));m_pButtonRestore->setFixedSize(QSize(30, 30));m_pButtonMax->setFixedSize(QSize(30, 30));m_pButtonClose->setFixedSize(QSize(30, 30));// 设置名称m_pTitleContent->setObjectName("TitleContent");m_pButtonMenu->setObjectName("btnMenu");m_pButtonMin->setObjectName("ButtonMin");m_pButtonRestore->setObjectName("ButtonRestore");m_pButtonMax->setObjectName("ButtonMax");m_pButtonClose->setObjectName("ButtonClose");// 设置名称m_pButtonMenu->setToolTip(QStringLiteral("菜单"));m_pButtonMin->setToolTip(QStringLiteral("最小化"));m_pButtonRestore->setToolTip(QStringLiteral("还原"));m_pButtonMax->setToolTip(QStringLiteral("最大化"));m_pButtonClose->setToolTip(QStringLiteral("关闭"));// 定义图标QIcon icon,icon1;// 设置菜单图标icon.addFile(QString("ico/branch_menu.png"), QSize(), QIcon::Normal, QIcon::Off);m_pButtonMenu->setIcon(icon);// 设置关闭图标icon1.addFile(QString("ico/branch_close.png"), QSize(), QIcon::Normal, QIcon::Off);m_pButtonClose->setIcon(icon1);// 设置最小化图标icon.addFile(QString("ico/branch_min.png"), QSize(), QIcon::Normal, QIcon::Off);m_pButtonMin->setIcon(icon);// 设置最大化图标icon.addFile(QString("ico/branch_max.png"), QSize(), QIcon::Normal, QIcon::Off);m_pButtonMax->setIcon(icon);// 设置还原图标icon.addFile(QString("ico/branch_res.png"), QSize(), QIcon::Normal, QIcon::Off);m_pButtonRestore->setIcon(icon);// 创建Layout框QHBoxLayout* mylayout = new QHBoxLayout(this);mylayout->addWidget(m_pIcon);mylayout->addWidget(m_pTitleContent);mylayout->addWidget(m_pButtonMenu);mylayout->addWidget(m_pButtonMin);mylayout->addWidget(m_pButtonRestore);mylayout->addWidget(m_pButtonMax);mylayout->addWidget(m_pButtonClose);// 设置Layout框格式mylayout->setContentsMargins(5, 0, 0, 0);mylayout->setSpacing(0);// 设置标题栏内容大小m_pTitleContent->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);this->setFixedHeight(TITLE_HEIGHT);this->setWindowFlags(Qt::FramelessWindowHint);// 添加换肤菜单QStringList name;name << "蓝色" << "浅蓝色" << "灰色" << "浅灰色" << "浅黑色" << "浅紫色" << "橙色";foreach (QString str, name) {QAction *action = new QAction(str, this);this->m_pButtonMenu->addAction(action);connect(action, SIGNAL(triggered(bool)), this, SLOT(onButtonchangeStyle()));}
}
// 信号槽的绑定;
void MyTitleBar::initConnections()
{connect(m_pButtonMin, SIGNAL(clicked()), this, SLOT(onButtonMinClicked()));connect(m_pButtonRestore, SIGNAL(clicked()), this, SLOT(onButtonRestoreClicked()));connect(m_pButtonMax, SIGNAL(clicked()), this, SLOT(onButtonMaxClicked()));connect(m_pButtonClose, SIGNAL(clicked()), this, SLOT(onButtonCloseClicked()));
}
// 以下为按钮操作响应的槽
void MyTitleBar::onButtonchangeStyle()
{QAction *act = (QAction *)sender();QString name = act->text();QString qssFile = "qss/blue.css";if (name == "蓝色")qssFile = "qss/blue.css";else if (name == "浅蓝色")qssFile = "qss/lightblue.css";else if (name == "灰色")qssFile = "qss/flatgray.css";else if (name == "浅灰色")qssFile = "qss/lightgray.css";else if (name == "浅黑色")qssFile = "qss/blacksoft.css";else if (name == "浅紫色")qssFile = "qss/purple.css";else if (name == "橙色")qssFile = "qss/orange.css";loadStyleSheet(qssFile);emit signalchangeStyle(qssFile);
}
void MyTitleBar::onButtonMinClicked()
{emit signalButtonMinClicked();
}
void MyTitleBar::onButtonRestoreClicked()
{m_pButtonRestore->setVisible(false);m_pButtonMax->setVisible(true);emit signalButtonRestoreClicked();
}
void MyTitleBar::onButtonMaxClicked()
{m_pButtonMax->setVisible(false);m_pButtonRestore->setVisible(true);emit signalButtonMaxClicked();
}
void MyTitleBar::onButtonCloseClicked()
{emit signalButtonCloseClicked();
}// 加载本地样式文件;
// 可以将样式直接写在文件中,程序运行时直接加载进来;
void MyTitleBar::loadStyleSheet(const QString &qssFile)
{QFile file(qssFile);if (file.open(QFile::ReadOnly)) {QString qss = this->styleSheet();qss += QLatin1String(file.readAll());this->setStyleSheet(qss);file.close();}
}
// 设置标题栏背景色,在paintEvent事件中进行绘制标题栏背景色;
// 在构造函数中给了默认值,可以外部设置颜色值改变标题栏背景色;
void MyTitleBar::setBackgroundColor(int r, int g, int b, bool isTransparent)
{m_colorR = r;m_colorG = g;m_colorB = b;m_isTransparent = isTransparent;// 重新绘制(调用paintEvent事件);update();
}
// 设置标题栏图标;
void MyTitleBar::setTitleIcon(QString filePath, QSize IconSize)
{QPixmap titleIcon(filePath);m_pIcon->setPixmap(titleIcon.scaled(IconSize));
}
void MyTitleBar::setTitleContent(QString titleContent, int titleFontSize)
{// 设置标题字体大小;QFont font = m_pTitleContent->font();font.setPointSize(titleFontSize);m_pTitleContent->setFont(font);// 设置标题内容;m_pTitleContent->setText(titleContent);m_titleContent = titleContent;
}// 设置标题栏长度;
void MyTitleBar::setTitleWidth(int width)
{this->setFixedWidth(width);
}// 设置标题栏上按钮类型;
// 由于不同窗口标题栏上的按钮都不一样,所以可以自定义标题栏中的按钮;
// 这里提供了四个按钮,分别为最小化、还原、最大化、关闭按钮,如果需要其他按钮可自行添加设置;
void MyTitleBar::setButtonType(ButtonType buttonType)
{m_buttonType = buttonType;switch (buttonType){case MIN_BUTTON:{m_pButtonRestore->setVisible(false);m_pButtonMax->setVisible(false);}break;case MIN_MAX_BUTTON:{m_pButtonRestore->setVisible(false);}break;case ONLY_CLOSE_BUTTON:{m_pButtonMin->setVisible(false);m_pButtonRestore->setVisible(false);m_pButtonMax->setVisible(false);}break;default:break;}
}// 设置标题栏中的标题是否会自动滚动;
// 一般情况下标题栏中的标题内容是不滚动的,但是既然自定义就看自己需要嘛,想怎么设计就怎么搞O(∩_∩)O!
void MyTitleBar::setTitleRoll()
{connect(&m_titleRollTimer, SIGNAL(timeout()), this, SLOT(onRollTitle()));m_titleRollTimer.start(200);
}// 设置窗口边框宽度;
void MyTitleBar::setWindowBorderWidth(int borderWidth)
{m_windowBorderWidth = borderWidth;
}
// 保存窗口最大化前窗口的位置以及大小;
void MyTitleBar::saveRestoreInfo(const QPoint point, const QSize size)
{m_restorePos = point;m_restoreSize = size;
}// 获取窗口最大化前窗口的位置以及大小;
void MyTitleBar::getRestoreInfo(QPoint& point, QSize& size)
{point = m_restorePos;size = m_restoreSize;
}
// 绘制标题栏背景色;
void MyTitleBar::paintEvent(QPaintEvent *event)
{// 是否设置标题透明;if (!m_isTransparent){//设置背景色;QPainter painter(this);QPainterPath pathBack;pathBack.setFillRule(Qt::WindingFill);pathBack.addRoundedRect(QRect(0, 0, this->width(), this->height()), 3, 3);painter.setRenderHint(QPainter::Antialiasing, true);painter.fillPath(pathBack, QBrush(QColor(m_colorR, m_colorG, m_colorB)));}// 当窗口最大化或者还原后,窗口长度变了,标题栏的长度应当一起改变;// 这里减去m_windowBorderWidth ,是因为窗口可能设置了不同宽度的边框;// 如果窗口有边框则需要设置m_windowBorderWidth的值,否则m_windowBorderWidth默认为0;if (this->width() != (this->parentWidget()->width() - m_windowBorderWidth)){this->setFixedWidth(this->parentWidget()->width() - m_windowBorderWidth);}QWidget::paintEvent(event);
}// 双击响应事件,主要是实现双击标题栏进行最大化和最小化操作;
void MyTitleBar::mouseDoubleClickEvent(QMouseEvent *event)
{// 只有存在最大化、还原按钮时双击才有效;if (m_buttonType == MIN_MAX_BUTTON){// 通过最大化按钮的状态判断当前窗口是处于最大化还是原始大小状态;// 或者通过单独设置变量来表示当前窗口状态;if (m_pButtonMax->isVisible()){onButtonMaxClicked();}else{onButtonRestoreClicked();}}return QWidget::mouseDoubleClickEvent(event);
}// 以下通过mousePressEvent、mouseMoveEvent、mouseReleaseEvent三个事件实现了鼠标拖动标题栏移动窗口的效果;
void MyTitleBar::mousePressEvent(QMouseEvent *event)
{if (m_buttonType == MIN_MAX_BUTTON){// 在窗口最大化时禁止拖动窗口;if (m_pButtonMax->isVisible()){m_isPressed = true;m_startMovePos = event->globalPos();}}else{m_isPressed = true;m_startMovePos = event->globalPos();}return QWidget::mousePressEvent(event);
}void MyTitleBar::mouseMoveEvent(QMouseEvent *event)
{if (m_isPressed){QPoint movePoint = event->globalPos() - m_startMovePos;QPoint widgetPos = this->parentWidget()->pos();m_startMovePos = event->globalPos();this->parentWidget()->move(widgetPos.x() + movePoint.x(), widgetPos.y() + movePoint.y());}return QWidget::mouseMoveEvent(event);
}
void MyTitleBar::mouseReleaseEvent(QMouseEvent *event)
{m_isPressed = false;return QWidget::mouseReleaseEvent(event);
}
// 该方法主要是让标题栏中的标题显示为滚动的效果;
void MyTitleBar::onRollTitle()
{static int nPos = 0;QString titleContent = m_titleContent;// 当截取的位置比字符串长时,从头开始;if (nPos > titleContent.length())nPos = 0;m_pTitleContent->setText(titleContent.mid(nPos));nPos++;
}

4.使用标题栏类

在用户的构造函数上面添加对标题栏类的使用,主要是设置主窗口MainWindow的去除边框功能(通过设置窗口标志Qt::FramelessWindowHint)、设置窗口最小化时点击任务栏窗口可以显示出原窗口(通过设置窗口标志Qt::WindowMinimizeButtonHint)、设置窗口背景透明(通过设置窗口标志Qt::WA_TranslucentBackground),然后在初始化标题栏类,关联标题栏类和主窗口类的相关信号和槽函数,实现所需最小化、最大化、关闭按钮等功能,并包括对标题栏类图标、标题、大小尺寸等效果设置,具体代码如下。

class MainWindow : public QMainWindow
{Q_OBJECT
public:MainWindow(QWidget *parent = nullptr);~MainWindow();
private slots:void onButtonchangeStyle(const QString &qssFile);void onButtonMinClicked();void onButtonRestoreClicked();void onButtonMaxClicked();void onButtonCloseClicked();
protected:bool eventFilter(QObject *obj, QEvent *event) override;void initTitleBar();void paintEvent(QPaintEvent *event) override;
private:Ui::MainWindow *ui;MyTitleBar* m_titleBar;
};MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);// 设置窗口去除边框 窗口最小化时点击任务栏窗口可以显示出原窗口;this->setWindowFlags(Qt::FramelessWindowHint | Qt::WindowMinimizeButtonHint);// 设置窗口背景透明;setAttribute(Qt::WA_TranslucentBackground);// 关闭窗口时释放资源(注意!!!如果是主窗口不要设置WA_DeleteOnClose属性)//setAttribute(Qt::WA_DeleteOnClose);/*** 初始化标题栏 ***/initTitleBar();/*** 画图界面初始化 ***/InitChart();/*** 注册事件过滤器 ***/ui->widget->installEventFilter(this);ui->tab->installEventFilter(this);ui->tab_2->installEventFilter(this);/*** 创建右键菜单 ***/CreateMenu(ui->widget);CreateMenu(ui->tab);CreateMenu(ui->tab_2);/*** 工具栏影藏 ***/ui->toolBar->hide();
}
MainWindow::~MainWindow()
{delete ui;
}
void MainWindow::initTitleBar()
{m_titleBar = new MyTitleBar(this);m_titleBar->move(0, 0);connect(m_titleBar, SIGNAL(signalchangeStyle(QString)), this, SLOT(onButtonchangeStyle(QString)));connect(m_titleBar, SIGNAL(signalButtonMinClicked()), this, SLOT(onButtonMinClicked()));connect(m_titleBar, SIGNAL(signalButtonRestoreClicked()), this, SLOT(onButtonRestoreClicked()));connect(m_titleBar, SIGNAL(signalButtonMaxClicked()), this, SLOT(onButtonMaxClicked()));connect(m_titleBar, SIGNAL(signalButtonCloseClicked()), this, SLOT(onButtonCloseClicked()));// 设置标题栏效果,可以不设置;m_titleBar->setTitleRoll();// 设置标题栏图标;m_titleBar->setTitleIcon(QDir::currentPath() + "/ico/butterfly.ico");m_titleBar->setTitleContent(QStringLiteral("***Qt更改标题栏动态效果测试***"));m_titleBar->setButtonType(MIN_MAX_BUTTON);m_titleBar->setTitleWidth(this->width());
}
void MainWindow::onButtonchangeStyle(const QString &qssFile)
{QFile file(qssFile);if (file.open(QFile::ReadOnly)) {QString qss = this->styleSheet();qss += QLatin1String(file.readAll());qApp->setStyleSheet(qss);file.close();}
}
void MainWindow::onButtonMinClicked()
{showMinimized();
}
void MainWindow::onButtonRestoreClicked()
{QPoint windowPos;QSize windowSize;m_titleBar->getRestoreInfo(windowPos, windowSize);this->setGeometry(QRect(windowPos, windowSize));
}
void MainWindow::onButtonMaxClicked()
{m_titleBar->saveRestoreInfo(this->pos(), QSize(this->width(), this->height()));QRect desktopRect = QApplication::desktop()->availableGeometry();QRect FactRect = QRect(desktopRect.x() - 3, desktopRect.y() - 3, desktopRect.width() + 6, desktopRect.height() + 6);setGeometry(FactRect);
}
void MainWindow::onButtonCloseClicked()
{close();
}
void MainWindow::paintEvent(QPaintEvent* event)
{//设置背景色;QPainter painter(this);QPainterPath pathBack;pathBack.setFillRule(Qt::WindingFill);pathBack.addRoundedRect(QRect(0, 0, this->width(), this->height()), 3, 3);painter.setRenderHint(QPainter::SmoothPixmapTransform, true);painter.fillPath(pathBack, QBrush(QColor(238, 223, 204)));return QWidget::paintEvent(event);
}

以上是对自定义标题栏的实现一种,相关例程附文末,当然还有其他实现方式,例如,更快捷的是,通过可视化界面UI来设计标题栏,然后绑定/链接到主窗口界面上,具体例程可见文末链接处。


总结

博文中相应的工程代码Qt-Case.zip 利用Qt开发软件进行编的例程,为博文提供案例-CSDN文库。

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

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

相关文章

睡岗和玩手机数据集,4653张原始图,支持YOLO,VOC XML,COCO JSON格式的标注

睡岗和玩手机数据集&#xff0c;4653张原始图&#xff0c;支持YOLO&#xff0c;VOC XML&#xff0c;COCO JSON格式的标注 数据集分割 训练组70&#xff05; 3257图片 有效集20&#xff05; 931图片 测试集10&#xff05; 465图片 预处理 没有采用任何预处…

GIN

gin是什么 Gin 是一个用 Go (Golang) 编写的 HTTP Web 框架。 它具有类似 Martini 的 API&#xff0c;但性能比 Martini 快 40 倍。如果你需要极好的性能&#xff0c;使用 Gin 吧。 特点&#xff1a;gin是golang的net/http库封装的web框架&#xff0c;api友好&#xff0c;注…

Git安装及基础学习

Git学习 Git安装 概述&#xff1a; Git是一个开源的分布式版本控制系统&#xff0c;可以有效、高速的处理 从很小到非常大的项目版本管理&#xff0c;是目前使用范围最广的版本 管理工具。 下载安装&#xff1a; 下载地址&#xff1a;https://git-scm.com/ 下载后傻瓜式一键安…

【Rust自学】4.2. 所有权规则、内存与分配

4.2.0 写在正文之前 在学习了Rust的通用编程概念后&#xff0c;就来到了整个Rust的重中之重——所有权&#xff0c;它跟其他语言都不太一样&#xff0c;很多初学者觉得学起来很难。这个章节就旨在让初学者能够完全掌握这个特性。 本章有三小节&#xff1a; 所有权&#xff1…

git stash 的文件如何找回

在Git中&#xff0c;如果你使用了git stash命令来保存你的工作进度&#xff0c;但之后想要找回这些被stash的文件&#xff0c;你可以按照以下步骤进行操作&#xff1a; 1. 查看stash列表 首先&#xff0c;使用git stash list命令来查看当前保存的所有stash记录。这个命令会列出…

如何构建一个可信的联邦RAG系统。

今天给大家分享一篇论文。 题目是&#xff1a;C-RAG&#xff1a;如何构建一个可信的联邦检索RAG系统。 论文链接:https://arxiv.org/abs/2412.13163 论文概述 尽管大型语言模型 (LLM) 在各种应用中展现出令人印象深刻的能力&#xff0c;但它们仍然存在可信度问题&#xff…

2025年入职/转行网络安全,该如何规划?网络安全职业规划

网络安全是一个日益增长的行业&#xff0c;对于打算进入或转行进入该领域的人来说&#xff0c;制定一个清晰且系统的职业规划非常重要。2025年&#xff0c;网络安全领域将继续发展并面临新的挑战&#xff0c;包括不断变化的技术、法规要求以及日益复杂的威胁环境。以下是一个关…

Ansible playbook 详解与实战操作

一、概述 playbook 与 ad-hoc 相比,是一种完全不同的运用 ansible 的方式&#xff0c;类似与 saltstack 的 state 状态文件。ad-hoc 无法持久使用&#xff0c;playbook 可以持久使用。 playbook 是由一个或多个 play 组成的列表&#xff0c;play 的主要功能在于将事先归并为一…

ai绘图丨中国新年春节背景第二弹(附关键词

使用工具&#xff1a;千鹿AI 咒语&#xff1a;圆形平面讲台&#xff0c;5 个礼品盒和台灯交错排列&#xff0c;红色背景上的圆形&#xff0c;中国唐朝风格&#xff0c;红色和金色主题&#xff0c;3D 效果图&#xff0c;摄影棚灯光&#xff0c;简约产品展示模型&#xff0c;逼真…

Envoy 进阶指南(下):深入探究Envoy服务和架构

接上篇&#xff1a;《Envoy 进阶指南&#xff08;上&#xff09;&#xff1a;从入门到核心功能全掌握》 链接 文章目录 3.深入探究Envoy3.1 Envoy服务发现机制3.1.1文件订阅3.1.2 gRPC 流式订阅3.1.3 REST-JSON 轮询订阅 3.2监听器&#xff08;Listener&#xff09;3.3.架构3.3…

关于ftp.ncbi.nlm.nih.gov数据下载路由调整的记录

经查防火墙看到ftp.ncbi.nlm.nih.gov的流量比较大&#xff0c;对专线带宽使用造成比较大的负担。 于是把ftp.ncbi.nlm.nih.gov改从PPOE线出&#xff0c;发现下载速度下降好多。通过流量图进行分析&#xff0c; 可以看出路由走PPOE时&#xff0c;仅HTTPS协议有通迅流量&#xf…

upload-labs靶场保姆级攻略

第一关&#xff1a;删除前端js校验 写一个一句话木马&#xff0c;命名为1.php 一句话木马 浏览上传 我们发现不可以上传&#xff0c;右键检查&#xff0c;依次点击 找到return checkFile()删掉&#xff0c;再上传 去看一下是否已经写入进去一句话木马 页面什么也没有&#xff…

鸿蒙项目云捐助第十五讲云数据库的初步使用

鸿蒙项目云捐助第十五讲云数据库的初步使用 在华为云技术使用中&#xff0c;前面使用了云函数&#xff0c;接下来看一下华为云技术中的另外一个技术云数据库的使用。 一、云数据库的创建 这里使用华为云数据库也需要登录到AppGallery Connect平台中&#xff0c;点击进入到之…

写入hive metastore报问题Permission denied: user=hadoop,inode=“/user/hive”

背景 使用Doris创建hive catalog后&#xff0c;想在hive上的库中创建一个表&#xff0c;报如下图片错误 解决办法 hdfs dfs -ls /看到如下图片所示&#xff0c;只有root用户有写的权限 所以通过export HADOOP_USER_NAMEroot将hadoop的用户名改成root&#xff0c;然后再hdfs…

GPT-Omni 与 Mini-Omni2:创新与性能的结合

近年来&#xff0c;随着人工智能技术的飞速发展&#xff0c;各种模型和平台应运而生&#xff0c;以满足从个人用户到企业级应用的多样化需求。在这一领域&#xff0c;GPT-Omni 和 Mini-Omni2 是两款备受瞩目的技术产品&#xff0c;它们凭借独特的设计和强大的功能&#xff0c;在…

Android代码结构图

Android架构 AOSP 的软件堆栈包含以下层&#xff0c;如图&#xff1a; Android app&#xff1a;系统原生一些应用&#xff0c;位于system/app&#xff0c;像图库、文件管理器等Privileged app&#xff1a;系统原生一些高特权应用&#xff0c;位于system/priv-app&#xff0c…

深入解析与防范:基于缓冲区溢出的FTP服务器攻击及调用计算器示例

深入解析与防范&#xff1a;基于缓冲区溢出的FTP服务器攻击及调用计算器示例 摘要 本文将详细探讨一种利用缓冲区溢出漏洞对FTP服务器进行远程攻击的技术&#xff0c;并通过分析给定代码示例&#xff0c;揭示其工作原理和潜在风险。我们将重点讨论如何在靶机上实现调用计算器…

ansible的流程控制

Ansible 剧本的流程控制通过任务的顺序执行、条件语句&#xff08;when&#xff09;、循环&#xff08;with_items 等&#xff09;、错误处理&#xff08;ignore_errors 和 block&#xff09;、以及任务标签和角色来实现。可以根据条件动态控制任务执行&#xff0c;使用循环处理…

CAD图纸加密措施有哪些,CAD图纸加密禁止复制打印工具

CAD图纸加密措施有哪些&#xff0c;CAD图纸加密禁止复制打印工具 CAD图纸作为核心的设计成果&#xff0c;其安全性和保密性至关重要。 为了有效防止图纸数据泄露&#xff0c;企业需采取一系列加密措施&#xff0c;并借助专业的加密工具来实现这一目标。 域智盾软件&#xff0…

laya游戏引擎中打包之后图片模糊

如下图正常运行没问题&#xff0c;打包之后却模糊 纹理类型中的默认类型都是精灵纹理&#xff0c;改为默认值即可。注意&#xff1a;要点击“应用”才可有效。精灵纹理类型会对图片进行渲染处理&#xff0c;而默认值 平面类型不会处理图片。