当前位置: 首页 > news >正文

QtGUI模块功能详细说明,图标和光标(七)

目录

一.窗口和屏幕管理

二. 绘图和渲染

三. 图像处理

四. 字体和文本

五. 事件和输入处理

六. OpenGL 和硬件加速

七. 颜色和外观

八. 图标和光标

1、QIcon: 图标管理

1.1、QIcon 简介

1.2、图标的来源与创建

1.3、多分辨率与 DPI 支持

1.4、图标的状态管理

2、QCursor: 鼠标光标样式和自定义形状

2.1、QCursor 简介

2.2、预定义光标样式

2.3、自定义光标形状

2.4、光标的设置与管理

3、QIconEngine: 自定义图标渲染引擎

3.1、QIconEngine 简介

3.2、QIconEngine 的工作原理

3.3、实现自定义图标引擎

3.4、将自定义引擎与 QIcon 关联使用

九. 平台和渲染后端

十. 国际化(GUI 相关)


一. 窗口和屏幕管理

请跳转章节,此处不再重复:QtGUI模块功能详细说明,窗口和屏幕管理(一)

二. 绘图和渲染

 请跳转章节,此处不再重复:QtGUI模块功能详细说明,图形绘制与渲染(二)

三. 图像处理

 请跳转章节,此处不再重复:QtGUI模块功能详细说明,图像处理(三)

四. 字体和文本

 请跳转章节,此处不再重复:QtGUI模块功能详细说明, 字体和文本渲染(四)

五. 事件和输入处理

 请跳转章节,此处不再重复:QtGUI模块功能详细说明,事件与输入处理(五)

六. OpenGL 和硬件加速

支持 OpenGL 和 Vulkan 渲染,适用于高性能图形。暂不说明。

七. 颜色和外观

 请跳转章节,此处不再重复:QtGUI模块功能详细说明,颜色和外观(六)

八. 图标和光标

1、QIcon: 图标管理

1.1、QIcon 简介

QIcon 是一个跨平台的图标管理工具,能够加载和显示图像(例如 PNG、JPG、SVG 等格式)作为应用程序中的视觉元素。QIcon 不直接存储图像数据,而是通过引用图像文件或资源来管理图标的显示。

  • 多模式支持:QIcon 支持多种模式(如 QIcon::Normal、QIcon::Disabled、QIcon::Active、QIcon::Selected),允许为不同交互状态指定不同图像。

  • 多状态支持:支持 On 和 Off 状态,常用于切换控件(如复选框或按钮)。

  • 多种构造方式:可以通过文件路径、资源文件、QPixmap 或 QImage 创建 QIcon。

  • 自动缩放:根据控件大小或高 DPI 设置,QIcon 能自动调整图标尺寸。

1.1.1、QIcon 在 Qt 部件中的应用

按钮(QPushButton、QToolButton 等)

  • QPushButton:通过 setIcon() 方法为按钮设置图标。

    QPushButton *button = new QPushButton;
    QIcon icon(":/images/save.png"); // 从资源文件加载图标
    button->setIcon(icon);
    button->setIconSize(QSize(24, 24)); // 设置图标大小
  • QToolButton:工具按钮通常只显示图标,不显示文本,QIcon 是其核心视觉元素。

    QToolButton *toolButton = new QToolButton;
    toolButton->setIcon(QIcon(":/images/open.png"));
  • 状态支持:QIcon 可以为按钮的不同状态(如禁用或按下)设置不同图标:

    QIcon icon;
    icon.addFile(":/images/save_normal.png", QSize(), QIcon::Normal);
    icon.addFile(":/images/save_disabled.png", QSize(), QIcon::Disabled);
    button->setIcon(icon);

动作(QAction)

QAction 是 Qt 中用于表示菜单项、工具栏按钮等抽象动作的类,QIcon 为其提供视觉标识。

  • 菜单项:在 QMenu 中,QAction 使用 QIcon 显示图标。

    QAction *openAction = new QAction(QIcon(":/images/open.png"), "Open", this);
    QMenu *fileMenu = menuBar()->addMenu("File");
    fileMenu->addAction(openAction);
  • 工具栏:在 QToolBar 中,QAction 的图标由 QIcon 提供,点击工具栏按钮会触发相应的动作。

    QToolBar *toolbar = addToolBar("Main Toolbar");
    toolbar->addAction(openAction);

窗口图标(QMainWindow、QDialog 等)

QIcon 可用于设置窗口的标题栏图标或任务栏图标,增强应用程序的品牌识别:

  • 设置窗口图标:

    QMainWindow *window = new QMainWindow;
    window->setWindowIcon(QIcon(":/images/app_icon.png"));
  • 系统托盘图标:在 QSystemTrayIcon 中,QIcon 用于显示托盘图标。

    QSystemTrayIcon *trayIcon = new QSystemTrayIcon(QIcon(":/images/tray_icon.png"), this);
    trayIcon->show();

其他部件

  • QListWidget、QTreeWidget 等:QIcon 用于为列表项或树节点设置图标。

    QListWidgetItem *item = new QListWidgetItem(QIcon(":/images/folder.png"), "Folder");
    listWidget->addItem(item);
  • QTabBar/QTabWidget:为选项卡设置图标。

    QTabWidget *tabWidget = new QTabWidget;
    tabWidget->addTab(new QWidget, QIcon(":/images/tab.png"), "Tab 1");
  • QLabel:虽然 QLabel 通常显示文本或图像,但可以通过 QIcon 转换为 QPixmap 显示图标。

    QLabel *label = new QLabel;
    label->setPixmap(QIcon(":/images/icon.png").pixmap(32, 32));

1.2、图标的来源与创建

1.2.1、从文件加载(PNG, JPG, SVG 等格式)

QIcon 可以通过文件路径直接加载图像文件,支持多种常见格式,包括 PNG、JPG、SVG、ICO 等。

  • 使用 QIcon 的构造函数或 addFile() 方法加载图像文件。

  • 可以为不同状态(如 Normal、Disabled)或尺寸指定不同的图像文件。

// 简单加载单个图像文件
QIcon icon("path/to/icon.png"); // PNG 文件
QPushButton *button = new QPushButton;
button->setIcon(icon);// 为不同状态加载不同图像
QIcon multiStateIcon;
multiStateIcon.addFile("path/to/normal.png", QSize(), QIcon::Normal);   // 正常状态
multiStateIcon.addFile("path/to/disabled.png", QSize(), QIcon::Disabled); // 禁用状态
button->setIcon(multiStateIcon);// 加载 SVG 文件(支持矢量缩放)
QIcon svgIcon("path/to/icon.svg");
button->setIcon(svgIcon);

1.2.2、从 QPixmap 或 QImage 创建

 QIcon 可以通过 QPixmap 或 QImage 对象创建,适合需要动态生成图标或从内存中加载图像的场景。QPixmap 适用于与显示设备相关的像素数据,而 QImage 更适合图像处理。

  • 使用 QIcon 的构造函数直接从 QPixmap 或 QImage 创建。

  • 也可以通过 addPixmap() 方法为不同状态或模式添加图像。

// 从 QPixmap 创建
QPixmap pixmap(32, 32);
pixmap.fill(Qt::red); // 创建一个红色矩形
QIcon icon(pixmap);
QPushButton *button = new QPushButton;
button->setIcon(icon);// 从 QImage 创建
QImage image(32, 32, QImage::Format_ARGB32);
image.fill(Qt::blue); // 创建一个蓝色矩形
QIcon imageIcon(QPixmap::fromImage(image));
button->setIcon(imageIcon);// 为不同状态添加不同 QPixmap
QIcon multiIcon;
multiIcon.addPixmap(QPixmap("path/to/normal.png"), QIcon::Normal);
multiIcon.addPixmap(QPixmap("path/to/disabled.png"), QIcon::Disabled);
button->setIcon(multiIcon);

注意事项:

  • 性能:QPixmap 与显示设备相关,适合直接渲染;QImage 更适合图像操作(如缩放、滤镜)。

  • 格式转换:QImage 需通过 QPixmap::fromImage() 转换为 QPixmap 再创建 QIcon。

  • 内存管理:QIcon 内部会对 QPixmap 或 QImage 进行深拷贝,确保原始对象的生命周期不会影响图标。

1.2.3、从 Qt 资源系统 (.qrc) 加载图标

Qt 资源系统允许将图像文件嵌入应用程序的可执行文件中,通过 .qrc 文件管理资源。QIcon 可以直接从资源路径加载图标,路径以 :/ 开头。这种方式适合打包应用程序,确保图标文件不会丢失。

  • 创建 .qrc 文件(如 resources.qrc),列出资源文件。

  • 使用 QIcon 构造函数或 addFile() 加载资源路径。

创建 .qrc 文件:可直接使用QtCreator 添加资源文件界面操作实现创建

<!DOCTYPE RCC>
<RCC version="1.0"><qresource><file>images/icon.png</file><file>images/icon_disabled.png</file></qresource>
</RCC>

编译资源:

在 Qt 项目文件(.pro)中添加:使用 qmake 或 CMake 编译,资源将被嵌入可执行文件。

RESOURCES += resources.qrc
// 加载单个资源图标
QIcon icon(":/images/icon.png");
QPushButton *button = new QPushButton;
button->setIcon(icon);// 为不同状态加载资源图标
QIcon multiIcon;
multiIcon.addFile(":/images/icon.png", QSize(), QIcon::Normal);
multiIcon.addFile(":/images/icon_disabled.png", QSize(), QIcon::Disabled);
button->setIcon(multiIcon);

1.2.4、QIcon 的拷贝和赋值语义

QIcon 是一个轻量级类,采用隐式共享(copy-on-write)机制,类似于 QString 和 QPixmap。这意味着拷贝和赋值操作非常高效,多个 QIcon 对象可以共享相同的底层数据,直到其中一个对象被修改。

  • 拷贝构造:创建 QIcon 的副本时,共享相同的图像数据。

  • 赋值操作:将一个 QIcon 赋值给另一个时,共享数据,引用计数增加。

  • 修改操作:当修改 QIcon(如调用 addFile() 或 addPixmap())时,触发深拷贝,创建独立的数据副本。

// 拷贝构造
QIcon icon1(":/images/icon.png");
QIcon icon2(icon1); // 共享数据,高效
QPushButton *button1 = new QPushButton;
button1->setIcon(icon2); // 使用拷贝的图标// 赋值操作
QIcon icon3;
icon3 = icon1; // 共享数据
icon3.addFile(":/images/new_icon.png"); // 触发深拷贝,icon1 不受影响// 验证共享状态
qDebug() << icon1.isDetached(); // false(共享数据)
qDebug() << icon3.isDetached(); // true(深拷贝后独立)

1.3、多分辨率与 DPI 支持

1.3.1、为不同 DPI 提供多个尺寸的图像

为了支持高 DPI 显示,开发者可以为 QIcon 提供多个分辨率的图像版本(例如 1x、2x、3x),以适应不同的设备像素比。Qt 会根据屏幕的 DPR 和控件的需求尺寸选择最合适的图像。

  • 使用 QIcon::addFile() 或 QIcon::addPixmap() 方法,为同一图标的不同分辨率指定图像。

  • 通常通过文件名后缀(如 @2x、@3x)或显式指定尺寸来区分不同分辨率的图像。

  • 资源文件或文件系统中的图像可以按分辨率组织。

// 为不同分辨率提供图像(通过文件)
QIcon icon;
icon.addFile(":/images/icon.png", QSize(16, 16)); // 1x,标准分辨率
icon.addFile(":/images/icon@2x.png", QSize(32, 32)); // 2x,高分辨率
icon.addFile(":/images/icon@3x.png", QSize(48, 48)); // 3x,超高分辨率
QPushButton *button = new QPushButton;
button->setIcon(icon);
button->setIconSize(QSize(16, 16)); // 控件期望的逻辑尺寸

使用 QPixmap: 如果图标是动态生成的,可以通过 QPixmap 指定不同分辨率:

QIcon icon;
QPixmap pixmap1x(16, 16);
pixmap1x.fill(Qt::red);
QPixmap pixmap2x(32, 32);
pixmap2x.fill(Qt::red);
icon.addPixmap(pixmap1x, QIcon::Normal, QIcon::Off); // 1x
icon.addPixmap(pixmap2x, QIcon::Normal, QIcon::Off); // 2x
QPushButton *button = new QPushButton;
button->setIcon(icon);
button->setIconSize(QSize(16, 16));

1.3.2、Qt 自动选择最佳尺寸图标的机制

Qt 的 QIcon 引擎会根据以下因素自动选择最合适的图标版本:

  • 设备像素比(DPR):由 QScreen::devicePixelRatio() 或 QWindow::devicePixelRatio() 提供。

  • 控件期望的图标尺寸:由 setIconSize() 或控件的默认尺寸(如按钮的 iconSize 属性)指定。

  • 图标状态和模式:如 Normal、Disabled、Active 等。

  • 可用图像的分辨率:QIcon 中注册的图像尺寸。

选择机制:

  • 计算物理尺寸:

    • Qt 将控件期望的逻辑尺寸(QSize)乘以设备的 DPR,得到物理像素尺寸。

    • 例如:控件设置 iconSize 为 16x16 像素,DPR 为 2.0,则 Qt 会寻找接近 32x32 像素的图像。

  • 匹配最近尺寸:

    • Qt 从 QIcon 中注册的图像列表中选择与目标物理尺寸最接近的图像。

    • 如果没有精确匹配,Qt 会选择尺寸稍大的图像并缩放到目标尺寸(以避免模糊)。

  • 优先级:

    • 优先选择与当前状态(如 Normal、Disabled)和模式匹配的图像。

    • 如果没有特定状态的图像,Qt 会回退到默认状态(通常是 Normal)。

  • 缩放处理:

    • 如果选择的图像尺寸与目标尺寸不匹配,Qt 会使用高质量缩放算法(如平滑缩放)调整图像。

    • 对于 SVG 图像,Qt 会直接渲染到目标尺寸,无需额外图像版本。

// 创建一个支持多分辨率的 QIcon
QIcon icon;
icon.addFile(":/images/icon.png", QSize(16, 16)); // 1x
icon.addFile(":/images/icon@2x.png", QSize(32, 32)); // 2x// 设置按钮图标
QPushButton *button = new QPushButton;
button->setIcon(icon);
button->setIconSize(QSize(16, 16)); // 逻辑尺寸// 假设设备 DPR = 2.0,Qt 将选择 32x32 的图像(icon@2x.png)

验证 DPR 和选择:

开发者可以通过以下代码检查设备的 DPR 和实际使用的图标尺寸:

qDebug() << "Device Pixel Ratio:" << button->window()->windowHandle()->devicePixelRatio();
QPixmap actualPixmap = icon.pixmap(button->iconSize(), QIcon::Normal);
qDebug() << "Selected Pixmap Size:" << actualPixmap.size();

1.4、图标的状态管理

QIcon 支持为不同的交互状态和控件状态提供不同的图像,从而增强用户界面的动态性和直观性。

1.4.1、QIcon::Mode:图标模式

QIcon::Mode 枚举定义了图标的视觉模式,用于表示控件在不同交互状态下的外观。Qt 会根据控件的状态(如启用、禁用、悬停等)自动选择对应的模式。

  • QIcon::Normal:默认模式,表示控件处于正常、启用状态。

  • QIcon::Disabled:禁用模式,表示控件不可交互(例如按钮被禁用)。

  • QIcon::Active:激活模式,通常在,

  • QIcon::Selected:选中模式,表示控件被选中(如在菜单或列表中选中某项)。

使用场景:

  • 按钮在禁用时显示灰色图标(Disabled)。

  • 工具栏按钮在悬停或点击时高亮显示(Active)。

  • 菜单项选中时显示不同图标(Selected).

QIcon icon;
icon.addFile(":/images/button_normal.png", QSize(), QIcon::Normal);   // 正常状态
icon.addFile(":/images/button_disabled.png", QSize(), QIcon::Disabled); // 禁用状态
icon.addFile(":/images/button_active.png", QSize(), QIcon::Active);   // 激活状态
QPushButton *button = new QPushButton;
button->setIcon(icon);
button->setEnabled(false); // 禁用按钮,将显示 disabled 图标

1.4.2、QIcon::State:图标状态

QIcon::State 枚举定义了图标的开关状态,主要用于表示可切换控件(切换按钮)的两种状态。

  • QIcon::On:表示控件处于“开启”状态(如复选框被选中)。

  • QIcon::Off:表示控件处于“关闭”状态(如复选框未选中)。

#include <QApplication>
#include <QToolButton>
#include <QIcon>int main(int argc, char *argv[]) {QApplication app(argc, argv);QIcon icon;icon.addFile(":/images/checkbox_on.png", QSize(), QIcon::Normal, QIcon::On);   // 选中状态icon.addFile(":/images/checkbox_off.png", QSize(), QIcon::Normal, QIcon::Off); // 未选中状态QToolButton *toggleButton = new QToolButton;toggleButton->setCheckable(true); // 启用切换状态toggleButton->setIcon(icon);toggleButton->setIconSize(QSize(16, 16));toggleButton->setText("Toggle");toggleButton->show();return app.exec();
}

2、QCursor: 鼠标光标样式和自定义形状

2.1、QCursor 简介

QCursor 用于表示和管理应用程序中的鼠标光标(cursor)。它提供了对光标形状、位置以及行为的控制,允许开发者自定义光标的外观和功能,以适应不同的用户交互场景。

  • 设置光标形状:QCursor 允许开发者设置不同的光标形状,例如箭头(Qt::ArrowCursor)、十字(Qt::CrossCursor)、等待(Qt::WaitCursor)等。

  • 自定义光标:开发者可以通过加载图像(如位图或图标)创建自定义光标形状,使用 QCursor(QPixmap) 构造函数加载自定义图像。

  • 控制光标位置:QCursor 提供方法(如 QCursor::setPos() 和 QCursor::pos())来设置或获取鼠标光标的屏幕位置,常用于需要程序化控制光标移动的场景,如游戏或绘图应用。

  • 动态光标管理:支持在特定控件或窗口区域内动态切换光标。通过 QWidget::setCursor() 设置某个控件的光标形状,或者通过 QApplication::setOverrideCursor() 全局覆盖光标。

2.1.1、关键方法与属性:

  • QCursor(Qt::CursorShape shape):基于预定义形状创建光标。

  • QCursor(const QPixmap &pixmap, int hotX = -1, int hotY = -1):基于自定义图像创建光标,指定热点位置。

  • QCursor::pos():获取当前光标在屏幕上的位置。

  • QCursor::setPos(int x, int y):将光标移动到指定屏幕坐标。

  • QWidget::setCursor(const QCursor &cursor):为特定控件设置光标。

  • QApplication::setOverrideCursor(const QCursor &cursor):临时覆盖全局光标。

  • QApplication::restoreOverrideCursor():恢复被覆盖的光标。

#include <QApplication>
#include <QWidget>
#include <QCursor>int main(int argc, char *argv[]) {QApplication app(argc, argv);QWidget window;// 设置窗口的光标为手形window.setCursor(QCursor(Qt::PointingHandCursor));// 全局设置等待光标QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));window.show();return app.exec();
}

2.2、预定义光标样式

2.2.1、Qt::CursorShape 枚举的各种标准光标样式

Qt::CursorShape 是 Qt 框架中定义的一个枚举类型,位于 Qt 命名空间内,用于指定预定义的鼠标光标形状。

  • Qt::ArrowCursor:

    • 描述:标准的箭头光标,通常为一个向左上方倾斜的箭头。

    • 用途:默认光标,用于表示普通选择或导航状态,适用于大多数非特定交互场景(如窗口背景、普通控件)。

    • 典型场景:桌面应用程序的主窗口、文件浏览器中的非交互区域。

  • Qt::PointingHandCursor:

    • 描述:手形光标,显示为一个指向的手指,通常表示可点击的元素。

    • 用途:提示用户可以点击某个控件或区域,例如超链接、按钮或可交互的图标。

    • 典型场景:Web 浏览器中的超链接、GUI 中的按钮。

  • Qt::IBeamCursor:

    • 描述:I 形光标(或称文本光标),形似一个垂直的“I”或光标线。

    • 用途:表示用户可以选择或编辑文本,常见于文本输入区域。

    • 典型场景:文本编辑器、输入框(如 QLineEdit、QTextEdit)。

  • Qt::WaitCursor:

    • 描述:等待光标,通常显示为沙漏(Windows)或旋转的圆圈(macOS/Linux)。

    • 用途:提示用户程序正在执行耗时操作,暂时无法响应用户输入。

    • 典型场景:文件加载、数据处理、网络请求期间。

  • Qt::BusyCursor:

    • 描述:忙碌光标,通常与 Qt::WaitCursor 类似,但可能带有额外的箭头,表示程序忙碌但仍允许部分交互。

    • 用途:用于程序忙碌但仍可接受某些输入的场景。

    • 典型场景:后台任务运行时,允许用户继续操作其他控件。

  • Qt::CrossCursor:

    • 描述:十字光标,显示为一个十字形。

    • 用途:表示精确选择或定位,常见于绘图或设计工具中。

    • 典型场景:图像编辑软件中的选择工具、CAD 软件中的定位操作。

  • Qt::OpenHandCursor:

    • 描述:张开的手形光标,表示可以抓取或拖动。

    • 用途:提示用户可以拖动对象或平移视图。

    • 典型场景:地图应用程序中的平移操作、可拖动的界面元素。

  • Qt::ClosedHandCursor:

    • 描述:握紧的手形光标,表示正在拖动或抓取。

    • 用途:表示拖动操作正在进行,通常与 Qt::OpenHandCursor 配合使用。

    • 典型场景:拖动窗口、调整图形元素时。

  • Qt::SizeVerCursor:

    • 描述:垂直双向箭头光标,表示可以上下调整大小。

    • 用途:提示用户可以调整控件或窗口的垂直尺寸。

    • 典型场景:调整窗口高度、表格行高。

  • Qt::SizeHorCursor:

    • 描述:水平双向箭头光标,表示可以左右调整大小。

    • 用途:提示用户可以调整控件或窗口的水平尺寸。

    • 典型场景:调整窗口宽度、表格列宽。

  • Qt::SizeFDiagCursor:

    • 描述:对角线双向箭头光标(从左上到右下),表示可以沿对角线调整大小。

    • 用途:提示用户可以同时调整宽度和高度。

    • 典型场景:调整窗口的右下角大小。

  • Qt::SizeBDiagCursor:

    • 描述:对角线双向箭头光标(从右上到左下),表示可以沿另一对角线调整大小。

    • 用途:与 Qt::SizeFDiagCursor 类似,用于调整窗口或控件大小。

    • 典型场景:调整窗口的左下角或右上角。

  • Qt::UpArrowCursor:

    • 描述:向上箭头光标。

    • 用途:较少使用,通常用于特定场景,如表示向上选择或导航。

    • 典型场景:自定义工具栏或导航控件。

  • Qt::BlankCursor:

    • 描述:空光标,即隐藏光标。

    • 用途:用于完全隐藏光标,常见于全屏游戏或触摸屏应用。

    • 典型场景:第一人称射击游戏、视频播放器。

  • Qt::DragMoveCursor:

    • 描述:表示移动操作的光标,通常为一个箭头加四向箭头图标。

    • 用途:提示用户正在执行拖放操作中的移动。

    • 典型场景:文件拖放到新文件夹、拖动界面元素。

  • Qt::DragCopyCursor:

    • 描述:表示复制操作的光标,通常为一个箭头加加号图标。

    • 用途:提示用户正在执行拖放操作中的复制。

    • 典型场景:文件复制到新位置。

  • Qt::ForbiddenCursor:

    • 描述:禁止光标,通常为一个圆形加斜杠。

    • 用途:提示用户当前操作不被允许。

    • 典型场景:尝试将文件拖放到不可写入的区域。

2.2.2、如何设置标准光标到部件或应用程序

Qt 提供了灵活的方式来设置标准光标样式,可以针对特定部件(QWidget 及其子类)或整个应用程序进行设置。

为特定部件设置光标

通过 QWidget::setCursor() 方法,可以为特定的控件或窗口设置光标样式。当鼠标进入该控件区域时,光标会自动切换为指定的形状。

#include <QApplication>
#include <QPushButton>
#include <QVBoxLayout>int main(int argc, char *argv[]) {QApplication app(argc, argv);// 创建主窗口QWidget window;QVBoxLayout *layout = new QVBoxLayout(&window);// 创建按钮并设置不同的光标样式QPushButton *button1 = new QPushButton("Click Me");button1->setCursor(QCursor(Qt::PointingHandCursor)); // 手形光标QPushButton *button2 = new QPushButton("Edit Text");button2->setCursor(QCursor(Qt::IBeamCursor)); // 文本光标// 添加按钮到布局layout->addWidget(button1);layout->addWidget(button2);window.setLayout(layout);window.show();return app.exec();
}

为整个应用程序设置全局光标

通过 QApplication::setOverrideCursor() 方法,可以临时覆盖整个应用程序的光标样式。这种方法适合在程序执行特定任务(如耗时操作)时统一显示光标。

#include <QApplication>
#include <QPushButton>
#include <QTimer>int main(int argc, char *argv[]) {QApplication app(argc, argv);// 创建主窗口和按钮QWidget window;QPushButton *button = new QPushButton("Start Long Task", &window);// 按钮点击时模拟耗时操作,显示等待光标QObject::connect(button, &QPushButton::clicked, [&]() {// 设置全局等待光标QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));// 模拟耗时任务(3秒后恢复光标)QTimer::singleShot(3000, []() {QApplication::restoreOverrideCursor();});});window.show();return app.exec();
}

动态切换光标(结合事件)

在某些场景下,需要根据用户交互动态切换光标样式,例如鼠标悬停或拖放操作。可以通过重写控件的事件处理函数(如 enterEvent、leaveEvent)或使用信号槽机制实现。

#include <QApplication>
#include <QWidget>
#include <QEvent>class CustomWidget : public QWidget {
protected:void enterEvent(QEvent *event) override {setCursor(QCursor(Qt::PointingHandCursor)); // 鼠标进入时设置为手形光标QWidget::enterEvent(event);}void leaveEvent(QEvent *event) override {unsetCursor(); // 鼠标离开时恢复默认光标QWidget::leaveEvent(event);}
};int main(int argc, char *argv[]) {QApplication app(argc, argv);CustomWidget widget;widget.resize(200, 200);widget.show();return app.exec();
}

2.3、自定义光标形状

2.3.1、使用 QPixmap 和 QBitmap 定义光标图像和掩码

可以通过 QPixmap 创建光标图像,并结合 QBitmap 定义光标的掩码(mask)来控制光标的透明区域和形状。

  • 创建光标图像 (QPixmap):使用 QPixmap 加载或绘制光标图像。图像可以是 PNG、BMP 等格式,通常建议大小为 32x32 像素或更小,以符合系统光标大小限制。

  • 创建光标掩码 (QBitmap):掩码是一个单色位图,用于指定光标的哪些部分是透明的(黑色表示透明,白色表示不透明)。

  • 创建自定义光标 (QCursor):使用 QPixmap 和 QBitmap 创建 QCursor 对象。

  • 应用光标:将光标应用到窗口或控件上:

  • 注:如果 QPixmap 包含透明通道,掩码可以省略,直接使用 QCursor cursor(pixmap);。

#include <QApplication>
#include <QWidget>
#include <QEvent>
#include <QBitmap>
#include <QPixmap>
#include <QPainter>int main(int argc, char *argv[]) {QApplication app(argc, argv);QWidget window;window.resize(300,400);QPixmap pixmap(":/images/save.png");//从 QPixmap 生成掩码QBitmap mask = pixmap.createMaskFromColor(Qt::transparent);//    //手动绘制掩码:
//    QBitmap mask(pixmap.size());
//    QPainter painter(&mask);
//    mask.fill(Qt::color0); // 黑色(透明)
//    painter.setBrush(Qt::color1); // 白色(不透明)
//    painter.drawEllipse(0, 0, 16, 16); // 绘制圆形不透明区域QCursor customCursor(pixmap, mask);// 创建自定义光标 (QCursor)window.setCursor(customCursor); // 设置到当前窗口window.show();return app.exec();
}

2.3.2、设置光标热点(Hotspot)

光标热点(Hotspot)是光标图像中表示点击位置的点(x, y 坐标)。例如,箭头光标的热点通常在其尖端,十字光标的热点在其中心。

指定热点坐标:

在创建 QCursor 时,通过参数指定热点的 x 和 y 坐标(相对于光标图像的左上角)。

QPixmap pixmap(":/cursor.png");
QCursor customCursor(pixmap, 16, 16); // 热点位于图像中心(假设图像为 32x32)

动态计算热点:

如果热点位置需要根据图像内容动态计算,可以分析图像的透明区域或关键点。例如,检测图像的最左侧不透明像素作为热点。

int hotX = pixmap.width() / 2;
int hotY = pixmap.height() / 2;
QCursor customCursor(pixmap, hotX, hotY);

注意:热点坐标必须在图像范围内(0 ≤ x < pixmap.width(), 0 ≤ y < pixmap.height()),否则可能导致光标行为异常。

2.3.3、动态或动画光标(通过定时器或事件循环更新)

动态或动画光标通过定时器或事件循环定期更新光标图像,实现光标的动态效果,例如旋转、闪烁或帧动画。

准备多帧图像:

创建一组 QPixmap 图像,用于表示动画的每一帧。例如,旋转光标可能包含 8 个不同角度的图像。

QList<QPixmap> frames;
frames << QPixmap(":/frame1.png") << QPixmap(":/frame2.png") << QPixmap(":/frame3.png");

使用定时器切换帧:

使用 QTimer 定期触发帧切换,更新光标。

class MyWidget : public QWidget {
public:MyWidget(QWidget *parent = nullptr) : QWidget(parent), currentFrame(0) {frames << QPixmap(":/frame1.png") << QPixmap(":/frame2.png") << QPixmap(":/frame3.png");QTimer *timer = new QTimer(this);connect(timer, &QTimer::timeout, this, &MyWidget::updateCursor);timer->start(100); // 每 100ms 更新一次}private:void updateCursor() {currentFrame = (currentFrame + 1) % frames.size(); // 循环切换帧QCursor cursor(frames[currentFrame]);setCursor(cursor);}QList<QPixmap> frames;int currentFrame;
};

2.4、光标的设置与管理

2.4.1、部件级别的光标设置 (QWidget::setCursor(), unsetCursor())

件级别的光标设置允许为特定的 QWidget(如窗口、按钮或自定义控件)设置自定义光标或系统预定义光标。QWidget 类提供了 setCursor() 和 unsetCursor() 方法来管理光标。

设置光标 (QWidget::setCursor()):

//设置系统箭头光标:
QWidget *widget = new QWidget;
widget->setCursor(Qt::ArrowCursor);//设置自定义光标(基于 QPixmap):
QPixmap pixmap(":/cursor.png");
QCursor customCursor(pixmap, 16, 16); // 热点坐标 (16, 16)
widget->setCursor(customCursor);

恢复默认光标 (QWidget::unsetCursor()):

调用 unsetCursor() 移除部件的自定义光标,恢复到父部件或应用程序的默认光标(通常是 Qt::ArrowCursor)。

widget->unsetCursor();

2.4.2、应用程序级别的全局光标设置 (QApplication::setOverrideCursor())

应用程序级别的光标设置允许临时覆盖整个应用程序的所有光标,通常用于表示全局状态(如等待或繁忙状态)。QApplication 类提供了 setOverrideCursor() 和 restoreOverrideCursor() 方法来实现这一功能。

设置全局光标 (QApplication::setOverrideCursor()):

//设置等待光标:
QApplication::setOverrideCursor(Qt::WaitCursor);//自定义光标
QPixmap pixmap(":/busy_cursor.png");
QCursor customCursor(pixmap, 16, 16);
QApplication::setOverrideCursor(customCursor);

恢复先前光标 (QApplication::restoreOverrideCursor()):

调用 restoreOverrideCursor() 移除当前全局光标,恢复之前的全局光标或部件级光标。

QApplication::restoreOverrideCursor();

光标栈管理:

setOverrideCursor() 支持光标栈,多次调用会将光标压栈,restoreOverrideCursor() 会弹出栈顶光标。

QApplication::setOverrideCursor(Qt::WaitCursor); // 压栈:等待光标
QApplication::setOverrideCursor(Qt::CrossCursor); // 压栈:十字光标
QApplication::restoreOverrideCursor(); // 弹出:恢复到等待光标
QApplication::restoreOverrideCursor(); // 弹出:恢复到默认光标

3、QIconEngine: 自定义图标渲染引擎

3.1、QIconEngine 简介

QIconEngine 是 Qt 中用于渲染 QIcon 对象的底层接口。QIcon 是一个高层次类,用于表示可在不同上下文(如按钮、工具栏、菜单等)中显示的图标,而 QIconEngine 负责实际的图标渲染逻辑。每个 QIcon 实例都关联一个 QIconEngine(或其子类),由 Qt 内部管理。

核心功能

  • 图标渲染:根据请求的大小、模式(如正常、禁用、选中)和状态(如激活、悬停)生成图标图像。

  • 多分辨率支持:提供不同尺寸或像素密度的图标,适配高 DPI 显示。

  • 动态生成:支持运行时生成图标,而非依赖静态图像文件。

内置的 QIconEngine 

  • QPixmapIconEngine:基于 QPixmap 的静态图像渲染。

  • QImageIconEngine:基于 QImage 的渲染。

  • QSvgIconEngine:用于 SVG 矢量图标的渲染。

3.2、QIconEngine 的工作原理

QIconEngine 是一个抽象基类,开发者需要实现其核心虚函数以定义图标的渲染逻辑。

3.2.1、抽象基类及其核心虚函数

QIconEngine 定义在 <QIconEngine> 头文件中。

virtual void paint(QPainter *painter, const QRect &rect, QIcon::Mode mode, QIcon::State state) = 0

  • painter:用于绘制的画笔。

  • rect:目标矩形区域,定义图标的绘制大小和位置。

  • mode:图标模式(QIcon::Normal、QIcon::Disabled、 QIcon::Active、QIcon::Selected)。

  • state:图标状态(QIcon::On 或 QIcon::Off,例如复选框的选中/未选中状态)。

virtual QPixmap pixmap(const QSize &size, QIcon::Mode mode, QIcon::State state)

  • 返回指定大小、模式和状态的图标图像(QPixmap)。

  • 默认实现通过调用 paint() 渲染到 QPixmap,通常无需重写。

  • 参数同 paint(),但以 QSize 指定尺寸。

virtual QSize actualSize(const QSize &size, QIcon::Mode mode, QIcon::State state)

  • 返回图标的实际大小,可能受限于图标的固有尺寸。

  • 默认实现返回请求的 size,可重写以支持特定约束。

virtual QIconEngine *clone() const:

  • 创建引擎的副本,用于 QIcon 的复制操作。

  • 必须实现,通常返回一个新的引擎实例。

virtual QString key() const:

  • 返回引擎的唯一标识符,用于缓存或比较。

  • 默认实现返回类名,可重写以提供更具体的值。

virtual void addPixmap(const QPixmap &pixmap, QIcon::Mode mode, QIcon::State state):

  • 添加静态 QPixmap 作为图标内容(可选)。

  • 常用于混合静态和动态渲染。

virtual void addFile(const QString &fileName, const QSize &size, QIcon::Mode mode, QIcon::State state):

  • 从文件加载图标(可选)。

  • 常用于支持文件路径的图标加载。

virtual QStringList availableSizes(QIcon::Mode mode, QIcon::State state) const:

  • 返回支持的图标尺寸(可选)。

  • 用于多分辨率图标支持。

3.2.2、paint() 方法的实现(核心渲染逻辑)

paint() 是 QIconEngine 的核心方法,负责实际的图标绘制。

初始化画笔:配置 QPainter 的属性(如抗锯齿、画刷、笔)以确保高质量渲染。

处理模式和状态:根据 state 切换图标内容(例如开关的开/关状态)。根据 mode 调整渲染效果:

  • QIcon::Normal:标准渲染。

  • QIcon::Disabled:降低透明度或使用灰度。

  • QIcon::Active:高亮或加粗。

  • QIcon::Selected:更改颜色或背景。

绘制图标:使用 QPainter 绘制形状、路径或图像,适配目标 rect。

适配大小:确保绘制内容填充 rect,必要时缩放或裁剪。

3.2.3、pixmap() 方法的实现(获取缓存图像)

pixmap() 方法用于生成指定大小、模式和状态的 QPixmap,通常由 Qt 内部调用以缓存渲染结果。默认实现通过调用 paint() 完成渲染,开发者可以选择重写以优化性能。

默认实现

默认的 pixmap() 方法创建一个 QPixmap,调用 paint() 绘制内容:

QPixmap QIconEngine::pixmap(const QSize &size, QIcon::Mode mode, QIcon::State state) {QPixmap pixmap(size);pixmap.fill(Qt::transparent);QPainter painter(&pixmap);paint(&painter, QRect(QPoint(0, 0), size), mode, state);return pixmap;
}

自定义实现

如果需要优化(如缓存特定尺寸的图像),可以重写 pixmap():使用 QCache 或 QMap 存储已渲染的 QPixmap,避免重复渲染。

3.2.4、示例代码

展示动态圆形图标的渲染,支持不同模式和状态,并使用缓存优化 pixmap():

#include <QApplication>
#include <QPushButton>
#include <QIconEngine>
#include <QPainter>
#include <QCache>class CircleIconEngine : public QIconEngine {
public:CircleIconEngine() = default;QIconEngine *clone() const override { return new CircleIconEngine(); }void paint(QPainter *painter, const QRect &rect, QIcon::Mode mode, QIcon::State state) override {painter->setRenderHint(QPainter::Antialiasing, true);// 根据模式和状态调整颜色QColor color = (mode == QIcon::Disabled) ? Qt::gray :(mode == QIcon::Selected) ? Qt::blue :(mode == QIcon::Active) ? Qt::green : Qt::red;if (mode == QIcon::Disabled) {painter->setOpacity(0.5);}// 根据状态调整形状if (state == QIcon::On) {painter->setBrush(color);painter->drawEllipse(rect); // 实心圆} else {painter->setPen(QPen(color, 2));painter->setBrush(Qt::NoBrush);painter->drawEllipse(rect); // 空心圆}}QPixmap pixmap(const QSize &size, QIcon::Mode mode, QIcon::State state) override {QString cacheKey = QString("%1_%2_%3_%4").arg(size.width()).arg(size.height()).arg(mode).arg(state);if (cache.contains(cacheKey)) {return *cache.object(cacheKey);}QPixmap pixmap(size);pixmap.fill(Qt::transparent);QPainter painter(&pixmap);paint(&painter, QRect(QPoint(0, 0), size), mode, state);cache.insert(cacheKey, new QPixmap(pixmap));return pixmap;}private:static QCache<QString, QPixmap> cache;
};QCache<QString, QPixmap> CircleIconEngine::cache(100);int main(int argc, char *argv[]) {QApplication app(argc, argv);// 创建 QIcon 使用自定义引擎QIcon icon(new CircleIconEngine());// 创建按钮并设置图标QPushButton button;button.setIcon(icon);button.setIconSize(QSize(64, 64));button.setText("Dynamic Icon");button.setCheckable(true); // 支持 On/Off 状态button.resize(200, 100);button.show();return app.exec();
}

3.3、实现自定义图标引擎

3.3.1、子类化 QIconEngine

要创建自定义图标引擎,需要继承 QIconEngine 并实现其核心虚函数,尤其是 paint() 和 clone()。

  • 继承 QIconEngine:创建一个新类,继承自 QIconEngine

  • 实现核心虚函数:

    • paint(QPainter *painter, const QRect &rect, QIcon::Mode mode, QIcon::State state):定义图标的绘制逻辑。

    • clone() const:返回引擎的副本,用于 QIcon 复制。

    • 可选实现 pixmap()、actualSize() 等函数以优化性能或支持特定功能。

  • 添加自定义逻辑:根据需求添加成员变量或构造函数,用于存储图标的参数(如形状、颜色)。

#include <QIconEngine>
#include <QPainter>class CustomIconEngine : public QIconEngine {
public:CustomIconEngine() = default;QIconEngine *clone() const override {return new CustomIconEngine(*this);}void paint(QPainter *painter, const QRect &rect, QIcon::Mode mode, QIcon::State state) override {painter->setRenderHint(QPainter::Antialiasing, true);painter->setBrush(Qt::red);painter->drawEllipse(rect); // 示例:绘制红色圆形}
};

3.3.2、集成第三方 SVG 渲染库或字体图标库

假设使用 Font Awesome 字体,需先将字体文件(如 fa-solid-900.ttf)加载到应用中。确保字体文件已经拷贝到执行目录下:

#include <QApplication>
#include <QPushButton>
#include <QIconEngine>
#include <QPainter>
#include <QCache>#include <QPainter>
#include <QFontDatabase>
#include <QFont>class FontIconEngine : public QIconEngine {
public:FontIconEngine(const QString &iconCode, const QColor &color, qreal size): iconCode_(iconCode), color_(color), size_(size) {// 加载字体QFontDatabase db;int fontId = db.addApplicationFont("fa-solid-900.ttf");fontFamily_ = db.applicationFontFamilies(fontId).first();}QIconEngine *clone() const override {return new FontIconEngine(iconCode_, color_, size_);}void paint(QPainter *painter, const QRect &rect, QIcon::Mode mode, QIcon::State state) override {painter->setRenderHint(QPainter::Antialiasing, true);// 设置字体QFont font(fontFamily_);font.setPixelSize(qMin(rect.width(), rect.height()) * 0.8);painter->setFont(font);// 根据模式调整颜色QColor renderColor = color_;if (mode == QIcon::Disabled) {renderColor = renderColor.lighter(150);painter->setOpacity(0.5);} else if (mode == QIcon::Selected) {renderColor = Qt::blue;}painter->setPen(renderColor);// 居中绘制图标painter->drawText(rect, Qt::AlignCenter, iconCode_);}private:QString iconCode_; // 字体图标的 Unicode 码点(如 "\uf015" 表示家图标)QColor color_;qreal size_;QString fontFamily_;
};int main(int argc, char *argv[]) {QApplication app(argc, argv);// 创建 Font Awesome 家图标,QIcon homeIcon(new FontIconEngine(QString(QChar(0xf015)), Qt::black, 32));// 创建按钮并设置图标QPushButton button;button.setIcon(homeIcon);button.setIconSize(QSize(64, 64));button.setText("Home Icon");button.resize(200, 100);button.show();return app.exec();
}

效果:

3.4、将自定义引擎与 QIcon 关联使用

创建引擎实例:实例化自定义的 QIconEngine 子类。

DynamicIconEngine *engine = new DynamicIconEngine(DynamicIconEngine::Circle, Qt::red);

创建 QIcon:使用 QIcon(QIconEngine *engine) 构造函数,将引擎传递给 QIcon。

QIcon icon(engine);

应用到控件:将 QIcon 设置到按钮、工具栏或其他支持图标的控件上。

QPushButton button;
button.setIcon(icon);
button.setIconSize(QSize(64, 64));

九. 平台和渲染后端

提供平台特定集成和渲染后端支持。

  • QPlatformIntegration: 平台特定的窗口系统集成(Windows、X11、Wayland 等)。

  • QRasterPaintEngine: 软件光栅化渲染引擎。

  • QPlatformSurface: 平台特定的渲染表面。

  • QPlatformTheme: 平台主题(如按钮样式、对话框风格)。

  • QPlatformGraphicsBuffer: 平台特定的图形缓冲区。

  • QPlatformSharedGraphicsCache: 共享图形缓存,加速渲染。

十. 国际化(GUI 相关)

支持 GUI 相关的字符编码和区域设置。

  • QTextCodec(部分):字符编码支持(仅限 GUI 文本显示)。

  • QLocale(部分):区域设置(仅限 GUI 格式,如日期、数字显示)。

相关文章:

QtGUI模块功能详细说明,图标和光标(七)

目录 一.窗口和屏幕管理 二. 绘图和渲染 三. 图像处理 四. 字体和文本 五. 事件和输入处理 六. OpenGL 和硬件加速 七. 颜色和外观 八. 图标和光标 1、QIcon: 图标管理 1.1、QIcon 简介 1.2、图标的来源与创建 1.3、多分辨率与 DPI 支持 1.4、图标的状态管理 2、…...

【图像处理基石】如何入门OCR技术?

入门OCR&#xff08;Optical Character Recognition&#xff0c;光学字符识别&#xff09;技术需要结合理论学习、工具实践和项目实战&#xff0c;以下是分步骤的学习指南&#xff0c;适合零基础学习者&#xff1a; 一、明确OCR技术的核心概念 OCR的基本原理 核心流程&#xf…...

数据库知识沉浸式游戏化学习设计研究

数据库知识沉浸式游戏化学习设计研究 摘要: 本研究旨在设计一款以数据库知识为主题的沉浸式游戏化学习系统。通过对数据库知识体系的深入剖析,结合游戏化学习理论,构建了一个多层次、多任务的游戏架构。玩家在游戏过程中需完成构建数据库结构、编写 SQL 查询等任务来解锁关…...

大疆无人机

在大疆上云API中&#xff0c;​​DRC 链路​​通常指 ​​Device-Cloud Remote Control Link&#xff08;设备-云端远程控制链路&#xff09;​​&#xff0c;它是无人机&#xff08;或设备&#xff09;与云端服务之间建立的​​实时控制与数据传输通道​​&#xff0c;用于实现…...

撤回不了一点 v1.0.2,支持微信QQ钉钉飞书等消息防撤回

如今生活节奏快得飞起&#xff0c;社交软件和工作通讯软件成了咱日常交流的核心阵地。大家肯定都有过这些闹心事儿&#xff1a;和朋友聊得正嗨&#xff0c;对方突然撤回一条消息&#xff0c;好奇心瞬间爆棚&#xff0c;却怎么也看不到撤回的内容&#xff1b;工作群里关键信息刚…...

什么是Git?

“Git”是目前非常火、广泛使用的版本控制系统&#xff0c;尤其在软件开发领域中扮演着核心角色。 一、什么是Git&#xff1f;它到底是什么&#xff1f; Git 是一种版本控制系统&#xff08;Version Control System, VCS&#xff09;。它的主要作用是帮助开发者管理“代码的不…...

微信小程序 自定义图片分享-绘制数据图片以及信息文字

一 、需求 从数据库中读取头像&#xff0c;姓名电话等信息&#xff0c;当分享给女朋友时&#xff0c;每个信息不一样 二、实现方案 1、先将数据库中需要的头像姓名信息读取出来加载到data 数据项中 data:{firstName:, // 姓名img:, // 头像shareImage:,// 存储临时图片 } 2…...

langchain提示词的使用

一、概述 提示词是指向人工智能大模型提供的输入信息&#xff0c;通常包含关键词、问题或指令&#xff0c;可以引导大模型生成与用户期望相符的回应。我们在豆包&#xff0c;DeepSeek等大模型中输入的问题都可以认为一个简单的提示词&#xff0c;不过为了真正得到我们需要的结…...

C语言| extern的用法作用

C语言| 局部变量、全局变量 extern定义的变量&#xff0c;只对全局变量有用。 掌握extern的用法及其作用。extern主要用于在不同.c文件间扩展全局变量的作用范围。 扩展全局变量的使用范围&#xff0c;操作方法&#xff1a; 1 在一个文件内扩展全局变量的使用范围 全局变量…...

Rust 环境变量管理秘籍:从菜鸟到老鸟都爱的 dotenv 教程

前言 写代码的你,是否遭遇过这些灵魂拷问: “我现在在哪个环境?开发?测试?还是直接在生产线上裸奔?”“少写一个 .env,测试脚本在数据库里上演清空大法,客户当场破防。”“每次手动设置 RUST_ENV,命令敲到一半就开始怀疑人生,还怕输错一个字符引发灭世级事故。”别慌…...

Leetcode (力扣)做题记录 hot100(49,136,169,20)

力扣第49题&#xff1a;字母异位词分组 49. 字母异位词分组 - 力扣&#xff08;LeetCode&#xff09; 遍历数组&#xff0c;将每一个字符串变成char数组 然后排序&#xff0c;如果map里面有则将他的值返回来&#xff08;key是排序好的字符串&#xff09; class Solution {pu…...

Slitaz 系统深度解析

Slitaz 系统深度解析&#xff1a;从系统架构到设计哲学 一、系统定位与核心目标 Slitaz&#xff08;Simplified Lightweight IT Automatic Zen&#xff09;是一个基于 Linux 的超轻量级发行版&#xff0c;设计目标是极致轻量化、快速启动、低资源消耗&#xff0c;专为老旧硬件…...

Deepseek+Xmind:秒速生成思维导图与流程图

deepseekxmind&#xff0c;快速生成思维导图和流程图 文章目录 思维导图deepseek笔记本 txt文件xmind 流程图deepseekdraw.io 思维导图 deepseek 笔记本 txt文件 将deep seek的东西复制到文本文件中&#xff0c;然后将txt文件拓展名改成md xmind 新建思维导图----左上角三…...

理解计算机系统_并发编程(5)_基于线程的并发(二):线程api和基于线程的并发服务器

前言 以<深入理解计算机系统>(以下称“本书”)内容为基础&#xff0c;对程序的整个过程进行梳理。本书内容对整个计算机系统做了系统性导引,每部分内容都是单独的一门课.学习深度根据自己需要来定 引入 接续上一篇理解计算机系统_并发编程(4)_基于线程的并发(一…...

java刷题基础知识

List<int[]> merged new ArrayList<int[]>(); return merged.toArray(new int[merged.size()][]); 表示一个存储 int[] 类型元素的列表&#xff0c;list灵活支持扩展&#xff0c;因为不知道最后有几个区间&#xff0c;所以用list&#xff0c;最后toArray返回成数组…...

MATLAB语音情感识别神经网络方法

在MATLAB中使用神经网络进行语音情感识别通常涉及以下步骤&#xff1a;数据准备、特征提取、神经网络模型构建、训练与评估。以下是详细说明和示例代码&#xff1a; 1. 数据准备 数据集&#xff1a;推荐使用公开情感语音数据集&#xff08;如RAVDESS、CREMA-D、EMODB等&#x…...

PostgreSQL 服务器信号函数

PostgreSQL 服务器信号函数 PostgreSQL 提供了一组服务器信号函数&#xff08;Server Signaling Functions&#xff09;&#xff0c;允许数据库管理员向 PostgreSQL 服务器进程发送特定信号以控制服务器行为。这些函数提供了对数据库服务器的精细控制能力。 一、核心信号函数…...

流动式起重机Q2的培训内容有哪些?

流动式起重机 Q2 的培训内容主要分为理论知识和实际操作两部分&#xff0c;具体如下&#xff1a; 理论知识 基础理论知识&#xff1a;涵盖机械原理、液压原理、电气原理等内容&#xff0c;帮助学员理解起重机的基本工作原理。例如&#xff0c;通过机械原理知识&#xff0c;学员…...

虹科应用 | 探索PCAN卡与医疗机器人的革命性结合

随着医疗技术的不断进步&#xff0c;医疗机器人在提高手术精度、减少感染风险以及提升患者护理质量方面发挥着越来越重要的作用。医疗机器人的精确操作依赖于稳定且高效的数据通信系统&#xff0c;虹科提供的PCAN四通道mini PCIe转CAN FD卡&#xff0c;正是为了满足这一需求而设…...

Linux系统编程---Signal信号集

0、前言 在上一篇博客笔记文章中&#xff0c;对Linux进程间通信的信号进行了讲解&#xff0c;本章将接着上一篇文章的内容&#xff0c;继续对Linux进程间通信中信号部分的信号集这个小知识点进行梳理。 如果有对Linux系统编程有不了解的地方&#xff0c;欢迎查阅博主的Linux系统…...

上电单次复位触发电路

SA1相当于是另外一个触发信号&#xff0c;S2A是手动触发信号&#xff0c;当S1A和S2A开关都断开时,示波器A入口所连接线路为上拉状态&#xff0c;高电平为3V。 当S2A闭合&#xff0c;相当于手动拉低&#xff0c;可以用于唤醒单片机之类的。 当S1A闭合&#xff0c;模拟电源接入&…...

talk-linux 不同用户之间终端通信

好的&#xff01;下面是一个完整的指南和脚本&#xff0c;用于在两台 Linux 主机上配置并使用 talk 聊天功能&#xff08;假设它们在同一个局域网内&#xff09;。 ⸻ &#x1f9fe; 一、需求说明 我们需要在两台主机上&#xff1a; 1. 安装 talk 和 talkd 2. 启用 talkd 服…...

QGIS 将 Shapefile 导入 PostGIS 数据库

一、背景介绍&#xff1a;QGIS、PostgreSQL 和 PostGIS 的关系和用途 在开始动手操作之前&#xff0c;我们先简单了解一下 QGIS、PostgreSQL 和 PostGIS 之间的关系及其用途。 QGIS&#xff08;Quantum GIS&#xff09;&#xff1a;一款开源免费的桌面地理信息系统&#xff0…...

《内网渗透测试:绕过最新防火墙策略》

内网渗透测试是检验企业网络安全防御体系有效性的核心手段&#xff0c;而现代防火墙策略的持续演进&#xff08;如零信任架构、AI流量分析、深度包检测&#xff09;对攻击者提出了更高挑战。本文系统解析2024年新型防火墙的防护机制&#xff0c;聚焦协议隐蔽隧道、上下文感知绕…...

CSS结构性伪类、UI伪类与动态伪类全解析:从文档结构到交互状态的精准选择

一、结构性伪类选择器&#xff1a;文档树中的位置导航器 结构性伪类选择器是CSS中基于元素在HTML文档树中的层级关系、位置索引或结构特征进行匹配的一类选择器。它们无需依赖具体的类名或ID&#xff0c;仅通过文档结构即可精准定位元素&#xff0c;是实现响应式布局和复杂文档…...

【大模型LLM学习】MiniCPM的注意力机制学习

【大模型LLM学习】MiniCPM的注意力机制学习 前言1 Preliminary1.1 MHA1.2 KV-cache 2 GQAGQA的MiniCPM实现 3 MLAMLA的MiniCPM-3-4b的实现 TODO 前言 之前MiniCPM3-4B是最早达到gpt-3.5能力的端侧小模型&#xff0c;其注意力机制使用了MLA。本来想借着MiniCPM从MHA过到MLA的&am…...

stm32之PWR、WDG

目录 1.PWR1.1 简介1.2 电源框图1.3 上电复位和掉电复位1.4 可编程电压监测器1.5 低功耗模式1.5.1 模式选择1.5.2 睡眠模式1.5.3 停止模式1.5.4 待机模式 1.6 实验1.6.1 修改主频1.6.2 睡眠模式串口发送接收1.6.3 停止模式对射式红外传感器计次1.6.4 待机模式实时时钟 2.看门狗…...

分布式任务调度XXL-Job

​ XXL-Job 是一款轻量级、分布式的任务调度平台&#xff0c;其核心设计解决了传统任务调度&#xff08;如Quartz&#xff09;在分布式场景下的‌任务分片‌、‌高可用‌、‌可视化管控‌等痛点。以下从原理、核心架构、应用场景、代码示例及关联中间件展开详解 一、主流任务…...

内存泄漏与OOM崩溃根治方案:JVM与原生内存池差异化排查手册

内存泄漏与OOM崩溃根治方案&#xff1a;JVM与原生内存池差异化排查手册 一、问题描述与快速解决方案 1. 核心问题分类 内存泄漏&#xff08;Memory Leak&#xff09; 现象&#xff1a;应用运行时间越长&#xff0c;内存占用持续攀升&#xff0c;GC回收效率下降&#xff0c;最…...

火山引擎发展初始

火山引擎是字节跳动旗下的云计算服务品牌&#xff0c;其云服务业务的启动和正式商业化时间线如下&#xff1a; 1. **初期探索&#xff08;2020年之前&#xff09;** 字节跳动在早期为支持自身业务&#xff08;如抖音、今日头条等&#xff09;构建了强大的基础设施和技术中…...

使用光标测量,使用 TDR 测量 pH 和 fF

时域反射计 &#xff08;TDR&#xff09; 是一种通常用于测量印刷电路板 &#xff08;PCB&#xff09; 测试试样和电缆阻抗的仪器。TDR 对于测量过孔和元件焊盘的电感和电容、探针尖端电容和电感&#xff0c;甚至寄生电感收发器耦合电容器也非常有用。这也是验证仿真或提取您自…...

mybatisplus 集成逻辑删除

一开始&#xff0c;没去查资料&#xff0c;后面要被AI气死了&#xff0c;先看它的的话 一开始&#xff0c;看ai的描述&#xff0c;我还以为&#xff0c;不需要改数据库&#xff0c;mybatis-puls自动拦截集成就可以实现逻辑删除&#xff0c;c&#xff0c;最后还是要给数据库加一…...

ABAP+旧数据接管的会计年度未确定

导资产主数据时&#xff0c;报错旧数据接管的会计年度未确定 是因为程序里面使用了下列函数AISCO_CALCULATE_FIRST_DAY&#xff0c;输入公司代码&#xff0c;获取会计年度&#xff0c;这个数据是在后台表T093C表中取数的&#xff0c;通过SE16N可以看到后台表数据没有数&#xf…...

KT148A语音芯片发码很难播放_将4脚对地一下再发正常,什么原因?

问题描述如下&#xff1a;您好&#xff0c;遇到一点问题请帮忙支持一下&#xff1a; KT148A 这颗芯片&#xff0c; 我们上电后发码很难触发播放&#xff0c; 但用镊子将4pin PB0对地短接触发一下&#xff0c;再发码就很正常&#xff0c;这是什么原因&#xff1f; 根据现象来看…...

【大模型】DeepResearcher:通用智能体通过强化学习探索优化

DeepResearcher&#xff1a;通过强化学习在真实环境中扩展深度研究 一、引言二、技术原理&#xff08;一&#xff09;强化学习与深度研究代理&#xff08;二&#xff09;认知行为的出现&#xff08;三&#xff09;模型架构 三、实战运行方式&#xff08;一&#xff09;环境搭建…...

SpringBoot 3.X 开发自己的 Spring Boot Starter 和 SpringBoot 2.x 的区别

SpringBoot 2.x 在模块中创建 src/main/resources/META-INF/spring.factories 文件 文件内容如下&#xff1a; org.springframework.boot.autoconfigure.EnableAutoConfiguration\com.xxx.xxx.yourfilejava1,\com.xxx.xxx.yourfilejava2 SpringBoot 3.x 在模块中创建 src/m…...

NY164NY165美光固态闪存NY166NY172

美光NY系列固态闪存深度解析&#xff1a;技术、体验与行业洞察 一、技术架构与核心特性解析 美光NY系列&#xff08;NY164/NY165/NY166/NY172&#xff09;作为面向企业级市场的固态闪存产品&#xff0c;其技术设计聚焦高可靠性与性能优化。从架构上看&#xff0c;该系列可能采…...

Spring Boot中HTTP连接池的配置与优化实践

精心整理了最新的面试资料和简历模板&#xff0c;有需要的可以自行获取 点击前往百度网盘获取 点击前往夸克网盘获取 一、HTTP连接池的核心价值 在微服务架构和分布式系统场景中&#xff0c;HTTP客户端频繁创建/断开连接会产生显著的性能损耗。通过连接池技术可以实现&#x…...

【docker】--镜像管理

文章目录 拉取镜像启动镜像为容器连接容器法一法二 保存镜像加载镜像镜像打标签移除镜像 拉取镜像 docker pull mysql:8.0.42启动镜像为容器 docker run -dp 8080:8080 --name container_mysql8.0.42 -e MYSQL_ROOT_PASSWORD123123123 mysql:8.0.42 连接容器 法一 docker e…...

Logisim实验--华科计算机组成原理(保姆级教程) 头歌-存储系统设计实验(汉字库存储芯片扩展实验、MIPS寄存器文件设计)

汉字库存储芯片扩展实验 电路一&#xff1a; 电路二&#xff1a;电路和译码器设置。 两个电路的分线器设计&#xff1a; 只要把电路正确连接就能提交了&#xff0c;但要看到正确的实验结果就想要进行如下操作&#xff1a; 打开参考电路&#xff0c;我要做的就是将每个存储器内…...

Hapi.js知识框架

一、Hapi.js 基础 1. 核心概念 企业级Node.js框架&#xff1a;由Walmart团队创建&#xff0c;现由社区维护 配置驱动&#xff1a;强调声明式配置而非中间件 插件架构&#xff1a;高度模块化设计 安全优先&#xff1a;内置安全最佳实践 丰富的生态系统&#xff1a;官方维护…...

Baklib知识中台架构与智能引擎实践

知识中台架构设计实践 在数字化转型进程中&#xff0c;Baklib基于企业级知识管理需求&#xff0c;构建了模块化分层架构的知识中台体系。该架构采用数据湖仓融合技术&#xff0c;通过统一元数据管理打通业务系统间的信息壁垒&#xff0c;形成覆盖数据采集、清洗、标注的全链路…...

传输层协议UDP

传输层 负责数据能够从发送端传输接收端 . 再谈端口号 端口号 (Port) 标识了一个主机上进行通信的不同的应用程序 ; 在 TCP/IP 协议中 , 用 " 源 IP", " 源端口号 ", " 目的 IP", " 目的端口号 ", " 协议号 " 这样一…...

在Java中实现Parcelable接口和Serializable接口有什么区别?

在 Java 中&#xff0c;Parcelable 和 Serializable 接口都用于对象的序列化和反序列化&#xff0c;但它们的实现方式、性能和使用场景有很大区别。以下是它们的核心对比&#xff1a; 1. 实现方式 Serializable 是 Java 原生接口&#xff0c;只需声明 implements Serializable…...

MinIO WebUI 页面使用

上传文件到桶&#xff0c;选择Share 如果桶是pulic权限&#xff0c;则可以有以下两种方式访问到该对象文件&#xff1a; http://ip:9001/api/v1/download-shared-object/aHR0cDovLzEyNy4wLjAuMTo5MDAwL3dhcmVob3VzZS9wYWltb24vRmxpbmstTG9nby5wbmc_WC1BbXotQWxnb3JpdGhtPUFXU…...

Python | Dashboard制作

运行环境&#xff1a;jupyter notebook (python 3.12.7) Pyecharts 1.安装pyecharts !pip install pyecharts 验证安装是否成功&#xff1a; from pyecharts import __version__ print("Pyecharts版本:", __version__) # 应显示1.x以上版本 2.运行基础版代码&am…...

视频编辑软件无限音频、视频、图文轨

威力导演APP的特色功能包括无限音频、视频、图文轨&#xff0c;以及上百种二/三维特技转场、音/视频滤镜和多种音视频混编输出。此外&#xff0c;它还支持实时高清HDV格式、模拟信号输出&#xff0c;并具有DV25、DVACM、DV、HDV输入和输出等功能。在视频编辑领域&#xff0c;威…...

HttpSession 的运行原理

HttpSession 的运行原理&#xff08;基于 Java Web&#xff09; HttpSession 是 Java Web 开发中用于在服务器端存储用户会话数据的机制&#xff0c;它的核心作用是跟踪用户状态&#xff08;如登录信息、购物车数据等&#xff09;。 1. HttpSession 的基本概念 会话&#xff0…...

Axure应用交互设计:表格跟随菜单移动效果(超长表单)

亲爱的小伙伴,在您浏览之前,烦请关注一下,在此深表感谢!本文如有帮助请订阅 Axure产品经理精品视频课已登录CSDN可点击学习https://edu.csdn.net/course/detail/40420 课程主题:表格跟随菜单移动 主要内容:表格交互设计、动态面板嵌套、拖动时事件、移动动作 应用场景…...

Flannel vxlan模式的优缺点

VXLAN 模式的特点、优缺点 优点 高性能&#xff1a;VXLAN 利用内核态处理封装/解封装&#xff0c;性能优于用户态方案&#xff08;如 UDP&#xff09;&#xff0c;适合大规模集群。网络隔离&#xff1a;通过 VNI&#xff08;VXLAN Network Identifier&#xff0c;24 位&#…...