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

关于Qt适配不同分辨率和缩放率时可能遇到的问题和解决方案

如果没有特殊的处理,Qt的UI窗口在不同的分辨率和缩放率下,其显示效果可能会出现问题,常见的有:

  • 子控件堆叠,无法显示完整

  • 窗口尺寸变大,超出屏幕的显示范围

  • 控件变形,长宽比不合理

  • 界面模糊

  • 字体变大,控件尺寸却没有变化

    有两种方式可以对UI界面进行良好的缩放:

  • Qt不做任何事情,由windows系统负责缩放

  • windows系统不做任何事情,由Qt负责进行缩放

1.解决方案:Windows适配

使用qt.conf,在资源qrc里添加,`:/qt/etc/qt.conf`, qt.conf文件内容为:
[Platforms][Platforms]
WindowsArguments = dpiawareness=0

这样的效果就是直接让windows来接管和控制缩放。它通过类似缩放图片这样的方式来实现界面缩放,好处是各种情况下界面都可以使用,而且子界面不至于变形,坏处是放大后界面会变得模糊。

2.解决方案:Qt适配(Qt5.6版本及以后)

如果只是想单纯地解决问题,而不想深入了解高DPI的相关原理,那么只需知道对应的操作即可。

想要Qt适配不同分辨率和缩放率,即可以在高DPI下正常显示,我们需要做如下的工作:

2.1 开启支持高DPI的属性

在Qt5.6以及后续的版本中,添加了对高DPI显示的支持,这个特性默认是关闭的,需要我们手动打开这个特性,注意以下代码必须在main函数中,实例化QApplication对象之前调用,否则是不会起效果的

	QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling, true);QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps, true);QApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::PassThrough);

以上代码做了三件事情,分别是:

  • 开启Qt对高DPI显示的支持

  • 开启Qt对高分辨率版本pixmap(High resolution versions of pixmaps)的支持

  • 设置对高DPI(也就是大于1的DPI值)值的四舍五入规则

    第一个没什么好说的,打开这个开关,Qt才会启动对高DPI特性适配的功能

    第二个在后续会解释相关概念和原理,本节会介绍如何使用这个特性。

    第三个需要解释一下,当设置高DPI的时候,我们假设它的值为 originDPI,它是一个大于等于1的浮点数,常见取值有:1.0,1.25,1.5,1.75,2.0 等等,具体取决于操作系统中的设置。而Qt提供了一个机制,让我们决定是否采用这个原始值,也就是可以对原始值进行舍入的操作,实际使用的是舍入后的值,即实际应用的DPI值。

    在网络上很多关于讲解Qt适配不同分辨率和缩放比的文章中,都会提到Qt仅支持整数倍的DPI值,这是错误的,因为它们没有修改对DPI的射入政策,使用的默认值为:Qt::HighDpiScaleFactorRoundingPolicy::Round,它会将小数点后大于等于 0.5 的部分取整,因此结果如下:

window下设置的缩放比Qt实际应用的缩放比
100%1x
125%1x
150%2x
175%2x
200%2x
225%2x
250%3x

而Qt::HighDpiScaleFactorRoundingPolicy::PassThrough这个策略,则不会对原始值做任何修改,他会直接使用,所以实际的缩放比和设置的缩放比是完全一样的。

2.2 图片对高DPI的支持

当UI被放大的时候,原本的图片会显得比较模糊,这是因为同一张的图片被显示到了更大的物理矩形框中导致的。

为了解决这个问题,我们需要开启Qt对高分辨率版本pixmap(High resolution versions of pixmaps)的支持,然后按照如下策略提供图片资源。

2.2.1 外部图片

QImageReader类负责读取图片资源,它提供了自动识别并读入高分辨率版本pixmap的功能。例如,我们在DPI为1.0时,需要一个20x20的图片,它的路径为 :/icons/basename.png 。当DPI为2时,这个图片实际显示的尺寸就会被拉伸为原来的两倍,显示就会变得模糊。为了解决这个问题,我们应该提供这个图片的高分辨率版本pixmap

:/icons/basename.png
:/icons/basename@2x.png
:/icons/basename@3x.png
:/icons/basename@4x.png

其尺寸分别为:20x20,40x40,60x60,80x80。
QImageReader会根据当前的DPI设置,自动读取对应版本的pixmap,然后设置其devicePixelRatio属性为DPI值。例如,上面的代码,在DPI为1时,读取:/icons/basename.png图片,devicePixelRatio为1.0;当DPI为2时,读取:/icons/basename@2x.png,devicePixelRatio为2.0;依次类推。
这样,通过在不同DPI时应用不同的图片(事实上,在qt底层,会使用这些整数倍的图片进行缩放,获取当前dpi缩放率对应的高分辨率版本pixmap),就不会有图片模糊的情况发生。
qss中设置的图片支持这样的机制。

但要注意的是,如果使用的是QPixmap,则并非如此,它不会自动读取对应dpi的图片。
例如:

	QPixmap pix(":/icons/basename.png");

那么,在任何情况下,无论dpi的值是多少,它读取的都是:/icons/basename.png,而不是其他图片。
QIcon类型,查看文档,它是一个提供了可缩放图标的类型,也就是说QIcon没有size这个说法,要使用它时,先给定一个size将其转化为QPixmap,然后才能使用。
QIcon在构造时,会根据dpi自动读取对应的图片。假如我们提供了上面的四张图片,那么当dpi为1的时候,它仅读取1倍图;当dpi为1.25,1.5,1.75,2.0 时,它会读取1倍图,2倍图;当dpi大于2小于3时,会读取1倍图,2倍图,3倍图。也就是说,QIcon只读取它当前可能会用到的图,用不到的图不会读取。另外要注意:QIcon是根据图片名称来读取的,例如basename.png实际是3倍图,那么它仍然读取的是这个图。是根据名称而不是其他来读取图片的。
此时,可以使用 QIcon::availableSizes()来返回它读取的图片列表的尺寸,尺寸的顺序对应1倍图,2倍图,3倍图这样的顺序。
QIcon::pixmap() 函数,传入指定的size,返回一个pixmap。pixmap的尺寸和传入的size可能不同,可能相同。大概规则如下:

  • 未开启Qt::AA_UseHighDpiPixmaps,当size小于QIcon::availableSizes()中的最大尺寸时,pixmap的大小为size;否则,pixmap的大小为QIcon::availableSizes()中的最大尺寸
  • 开启了Qt::AA_UseHighDpiPixmaps,,此时这个函数会获取dpi的scale缩放系数,然后尝试获取 sizescale 尺寸的pixmap,是否允许的规则和上述类似,如果 sizescale 小于QIcon::availableSizes()中的最大尺寸时,pixmap的大小为 size*scale ,devicePixelRatio为scale;否则,pixmap的大小为QIcon::availableSizes()中的最大尺寸,devicePixelRatio则是一个未知的值。

所以,如果想要获取一个图片对应当前dpi的高分辨率版本pixmap,代码如下:

QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps, true); const QString path = "C:\\Users\\mech-mind_xpp\\Desktop\\icon.png";QSize size(22, 22);
#if 1QIcon icon(path);  // 实际应存在1倍图,2倍图,3倍图// size最好是一倍图的尺寸,或等比例缩小的尺寸,例如11x11;其他情况后果自负auto pxm = icon.pixmap(size); ui->svg->setPixmap(pxm);
#elseQPixmap pxm(path); //icon.png实际为三倍图或者其他N倍图qreal pixelRatio = qApp->devicePixelRatio();pxm = pxm.scaled(size * pixelRatio, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);pxm.setDevicePixelRatio(pixelRatio);ui->svg->setPixmap(pxm);
#endif
2.2.2 自绘制图片

在UI中使用的图片,有些是自己通过代码绘制得来的,和从外部读取的图片一样,也会有模糊的问题。此时就必须通过一定的策略来让自己绘制的图片成为高分辨率版本pixmap

其关键点如下:

  • 图片的尺寸和DPI相关

  • QPixmap(或者其他图片类)设置 devicePixelRatio属性,值为DPI的值

  • 由于图片的尺寸会随着DPI变化,因此实际绘制的细节中所使用的尺寸也都需要跟着DPI变化。由于DPI是一个浮点数,所以QPainter应该尽量使用那些参数为qreal的重载函数。

    代码梗概如下:

QSize size(64,64);
qreal dpi = window()->devicePixelRatioF();QPixmap pix(size * dpi);
pix.setDevicePixelRatio(dpi);QPainter painter(&pix);
... ...

事实上,自绘制的图片和从外部读取的图片,其要点是完全一样的。

2.2.3 另一种选择

以上是Qt提供的非常正规的办法,但缺点是每个图标都需要提供多张图片,会导致app的尺寸变得更大。一种比较偏门的办法是直接提供一张N倍图,例如3倍图或者4倍图。比如,当显示效果为20x20,那么我们可以提供一个尺寸为60x60的图片(3倍图),或者80x80的图片(4倍图)。这样,即使是在高DPI下,图片显示仍然是清晰的,这是因为将大尺寸的图片缩小后设置给了控件,因此避免了模糊的问题,同时资源文件的大小也不会变得太大,算是一种折中的办法。

接下来说明这种做法的具体操作细节:

2.2.3.1 qss使用border-image而不是image

假设现在有一个图标,我们的本意是想将它作为20x20的图标使用。但为了解决模糊的问题,现在给了一个3倍图,是60x60。此时如果使用qss设置图片,那么我们应该使用border-image而不是image,这是因为image默认并不会缩放图片,而是使用图片的原始尺寸,所以实际并不能表现为20x20的效果,而是60x60;而border-image则是会进行缩放填满控件范围,因此不需要担心尺寸问题,反而因为是大尺寸图片渲染到小尺寸,可以解决图片模糊的问题。

2.2.3.2 QLabel设置图片

还是上面的问题,QLabel默认的属性scaleContents是false,此时如果设置一个pixmap,QLabel会缩放自身的size来使用pixmap的尺寸。而为了解决模糊的问题,应该反过来:给QLabel设置尺寸,设置属性scaleContents为true,然后设置pixmap。

	label->setFixedSize(20,20);label->setScaledContents(true);label->setPixmap(QPixmap(":/icons/back.png")); // back.png的尺寸为60x60

但需要注意的是,此时不能将pixmap进行缩放操作,然后再设置给label,这样由于从大尺寸图片缩小为了小尺寸,就丢失了图片的细节,仍然不能解决图片模糊的问题:

	label->setFixedSize(20,20);label->setScaledContents(true);QPixmap pix = QPixmap(":/icons/back.png"); // back.png的尺寸为60x60pix = pix.scaled(QSize(20,20));	//错误,这样和直接给一个20x20的图片是一样的,仍然会模糊label->setPixmap(pix); 
2.2.3.3 QPainter绘制图片

在代码中,有时候会使用QPainter绘制图片,这种操作也会导致图片模糊。还是上面的情况,由于QPainter的drawPixmap不会缩放图片,它使用的是pixmap的原始尺寸,所以绘制出来是60x60的大小;而如果提前将pixmap进行scale操作,和2.2.3.2中一样,图片仍然会模糊,此时我们应该按照**高分辨率版本pixmap **的逻辑来解决这个问题:
注意:pixmap的dpr最好和当前dpi的设置一致。否则,可能会出现图片变形的问题。

QPixmap pix(":/icons/back.png"); // back.png的尺寸为60x60
QSize size(20,20);
qreal pixelRatio = qApp->devicePixelRatio();
pix = pix.scaled(size * pixelRatio, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
pix.setDevicePixelRatio(pixelRatio);QPainter painter;
painter.drawPixmap(...);

2.3 其他注意事项

  • QPainter中应该尽量使用qreal类型的重载函数。
    这是因为,当dpi为1.25,1.5这样的值时,对应的尺寸也必须跟着scale倍数放大,如果参数是整数类型,那么可能会因为丢失小数部分而不能体现scale效果
  • 如有必要,可以根据屏幕的尺寸,也就是分辨率,以及dpi的倍数,来调整window和dialog的大小
  • 尽量不要给控件设置固定尺寸,而是通过QSizePolicy给定一个弹性的尺寸范围,然后使用layout自适应窗口尺寸的变化
2.3.1 高DPI下窗口尺寸超出屏幕范围

在100%的缩放率下,窗口的宽度为 width x height,那么在大于100的缩放率下,就会有 width * scale 大于 屏幕分辨率宽度 或者 height * scale 大于 屏幕分辨率高度的情况。这种情况下,建议将 width 和 height 的值修改为当前屏幕支持的最大值,或者直接showMax或者ShowFullScreen 。
注意:上面说的屏幕支持的最大值为:screenSize.width() / dpi 。例如当前缩放率为200%,屏幕分辨率为1920x1080,那么此时如果窗口不想超出屏幕,那么支持的最大宽高为:960x540.
示例代码:

void showEvent(QShowEvent* event) override
{auto dlgSize = this->size();const qreal scale = window()->screen()->devicePixelRatio();const auto screenSize = window()->screen()->size();dlgSize = dlgSize * scale;qDebug() << "....scale" << scale;if (dlgSize.width() > screenSize.width() || dlgSize.height() >= screenSize.height()) {// setFixedWidth(screenSize.width() / scale);// setFixedHeight(screenSize.height() / scale);// showMaximized();showFullScreen();}QDialog::showEvent(event);
}

然而在很多情况下,窗口的尺寸并不能随意变化。例如某些窗口要维持一定的长宽比,否则就不好看;或者将高度或者宽度缩小后,由于其中的子控件设置了固定尺寸而导致子控件堆叠等等。
所以尽量不要设置固定尺寸,使用layout管理子控件,让窗口可以自适应size的变化,这是非常重要的。对于UI设计人员来讲,也应该尽量克制自己对细节的追求,尽量不要使用例如指定固定尺寸,严格指定控件位置等等,这种只适合静态布局的方法,而是要考虑到窗口尺寸变化时子控件跟随变化的合理性。

3.控件堆叠与Unable to set geometry问题

在实际中,会发生子控件堆叠,不能显示完全的问题,或者报警告:Unable to set geometry等。

发生这两种情况的根本原因就是:父窗口的尺寸不足以容纳全部子窗口,或者即使能容纳,子窗口之间也会非常拥挤,甚至发生堆叠,显示不完全。

解决这个问题的思路,大致分为两种:

  • 动态设置window的尺寸,而不是设置固定尺寸

    • 可以调用adjustSize()函数,让window自动按照内容调节大小
    • 根据当前分辨率和缩放率,调整window的尺寸
  • 使用QScrollArea管理子控件

    为了让window拥有可以调节尺寸的能力,这就要求各个子控件的尺寸是可调节的(或者大多数子控件的尺寸是可调节的),因此控件的尺寸只要不要设置为固定尺寸,而是通过QSizePolicy设置为可调节的,这样当window窗口需要放大或者缩小时,layout才能适应这样的尺寸变化。

4. DPI基本概念

首先,我们了解两个概念:

  • Dots per inch (DPI):每英寸点数

  • Device-independent pixel (DIPs):独立于设备像素,设备自由像素

    DPI这个概念,最早来自于文本印刷行业。在这个行业中,文本的大小使用一种叫做(points)的概念作为单位来衡量,其中:

    1 pt = 1 / 72 inch

    也就是说,一个点是七十二分之一英寸大小,一英寸为72个点。

    我们现在使用的字体中的大小,就叫做point size,就是从印刷行业继承下来的。例如一个12-point大小的字体,它的高度就是 12 / 72 = 1 / 6 英寸。

    但当回到屏幕显示的时候,就出现了问题。我们知道,屏幕是以像素为单位的,但在不同的屏幕中,一个像素对应的实际物理宽度是不一样的,这取决于屏幕真实的物理尺寸和屏幕的分辨率。

    所以,定义了一个新的单位来表示字体的大小,新单位就是:逻辑单元logical units)。一个72 point大小的字体被定义为一个逻辑单元高。然后,再将逻辑单元转化为像素。在Windows的发展历史中,默认定义一个逻辑单元的大小为96像素。也就是说,此时一个 72 point大小的字体将被绘制为96个像素。一个12 point 大小的字体会被绘制成为 16 个像素。

    此时,DPI的概念就从打印中转移到了屏幕显示中,虽然名字叫 dots per inch,但已经是屏幕显示中的概念了。默认的DPI为96,即每英寸96个像素。(一个逻辑单元为72 point,72 point在印刷中为一英寸)。

    而操作系统中设置缩放率,其本质就是在修改DPI的值。如果用户将DPI修改为了144,那么72 point 大小的字体就会显示为144个像素高。标准DPI被设置为100%(96 DPI),125%(120 DPI),150(144 DPI),此外还有其他的设置。

    这样,我们就明白了,为什么缩放率改变时,文本的大小会变。这是因为字体的point size没有变化,它的逻辑单元也不会变化,但一个逻辑单元对应的像素发生了变化,最后显示的像素高度就发生了变化。

5.Qt对高DPI的支持

本节内容是对Qt文档《High DPI Displays》的概述。

有两种方式可以对UI界面进行缩放:

  • Qt不做任何事情,由windows系统负责缩放

  • windows系统不做任何事情,由Qt负责进行缩放

    第一种方法是通过设置相关的环境变量实现的,此时windows会按照缩放图片的方式缩放整个界面,因为无论是文字还是UI,都会同时放大缩小。好处是程序是可用的,坏处是界面必然会模糊。

    第二种方法则由Qt来负责缩放,其思路是:为了支持高DPI, Qt会自动缩放字体,并提供一个DPI值,应用程序代码可以使用它来缩放其余的UI。

    第二种情况下,所需的内容,已在第一节中说明。

6.Pixmap中的devicePixelRatio

dpr的概念,最初是来自于屏幕,引用网上一段话解释:

	我们的主人公是乔帮主和比尔盖茨。此时乔帮主面前有一台mac,屏幕的分辨率是1280*720,这就是物理分辨率。乔帮主对比尔盖茨说,给我的mac开发一个word软件吧。盖茨说OK,于是写了一个软件,这个软件显示的时候长度是1280像素,宽度是720像素,正好能够盖满整个mac屏幕。乔帮主看了之后很满意。有一天,乔帮主看自己的mac屏幕觉得很粗糙,一点都不清晰锐利。于是聪明的乔帮主想到,同样是15寸的屏幕,我把像素点翻倍,不就可以更清晰了吗?于是他把mac的物理分辨率改成了2560*1440的分辨率,相当于每个像素点的尺寸减少了4倍(保持原来每个像素占据的面积不变,放了4个像素,这每个像素占据的面积是原来像素占据面积的1/4),这下再也看不出颗粒感了,乔帮主很满意。但是,当乔帮主打开盖茨给他写的word的时候,傻眼了,原本全屏的word现在只占屏幕的四分之一,而且文字非常的小。乔帮主打电话给盖茨说,你的软件怎么出问题了?盖茨回答说,我开发的时候你的mac分辨率就是1280*720,你自己改了硬件尺寸怪我咯,我很忙没空给你改软件代码,你就凑合着用吧。乔帮主稍作思考,马上想出了一个非常聪明的主意!他在软件和硬件之间的系统层加了一层逻辑分辨率。虽然屏幕横向有2560个像素点,但是告诉软件我只有1280个像素点!当word的宽度要占1280个像素的时候,实际上已经占了2560个像素。于是我们的word又占满屏幕了!于是乔帮主把这个机智的想法命名为逻辑分辨率,不管我显示器的硬件有多少个像素点,我只会告诉软件我的逻辑分辨率,这样软件的代码就不用修改也能在不同的屏幕上显示效果一致。在多年后,mac的物理分辨率已经达到了5120 x 2880,但是告诉软件的时候还是说我的分辨率1280*720,相当在盖茨看来的一个逻辑像素点,背后实际上已经有16个物理像素点为其工作了!
而pixmap的dpr概念与之类似,表示的是pixmap的size和想要绘制的设备无关像素之间的比例。例如,一个200x200大小的pixmap,如果它的dpr为2,那么表示它将会被绘制到100x100的设备无关像素矩形内。我们引用QPainter文档中的《Drawing High Resolution Versions of Pixmaps and Images》一节:
	所谓pixmap的高分辨率版本,指的是device pixel ratio的值大于1的pixmap。当pixmap的dpr和底层的QPinterDevice的ptr一致时,pixmap无需转化,就可以直接绘制到相关设备上。例如,一张64x64大小的图片,dpr为2,当他绘制在一个高DPI而且dpr也正好为2的屏幕上时,最后实际绘制出来的时一个32x32像素大小的内容。当Qt中的代码根据pixmap的size来计算布局的尺寸时,会使用图片的dpr得到真实有效的尺寸。这导致pixmap会按照给分辨率版本的形式显示(32x32,但由于将图片提前进行了缩放,显示后的图片不会变得模糊),而不是显示为一个大的图片(64x64)。
简言之,如果想要最终显示为32x32像素大小,那么在dpi为1时,需要提供32x32的图片;dpi为2时,提供32x32的两倍大小的图片,图片的dpr需要设置为2,这样图片会先缩小2倍在放大2倍显示,图片不会变得模糊;依次类推。

相关文章:

关于Qt适配不同分辨率和缩放率时可能遇到的问题和解决方案

如果没有特殊的处理&#xff0c;Qt的UI窗口在不同的分辨率和缩放率下&#xff0c;其显示效果可能会出现问题&#xff0c;常见的有&#xff1a; 子控件堆叠&#xff0c;无法显示完整 窗口尺寸变大&#xff0c;超出屏幕的显示范围 控件变形&#xff0c;长宽比不合理 界面模糊 …...

第1篇 目标检测概述 —(1)目标检测基础知识

前言&#xff1a;Hello大家好&#xff0c;我是小哥谈。目标检测是计算机视觉领域中的一项任务&#xff0c;旨在自动识别和定位图像或视频中的特定目标&#xff0c;目标可以是人、车辆、动物、物体等。目标检测的目标是从输入图像中确定目标的位置&#xff0c;并使用边界框将其标…...

Discuz论坛网站标题栏Powered by Discuz!版权信息如何去除或是修改?

当我们搭建好DZ论坛网站后&#xff0c;为了美化网站&#xff0c;想把标题栏的Powered by Discuz&#xff01;去除或是修改&#xff0c;应该如何操作呢&#xff1f;今天飞飞和你分享&#xff0c;在操作前务必把网站源码和数据库都备份到本地或是网盘。 Discuz的版权信息存在两处…...

springboot整合aop,实现日志操作

前言&#xff1a; 整合之前&#xff0c;我们要明白aop是什么&#xff0c;为什么要用aop&#xff0c;aop能帮我们做什么。 答&#xff1a;AOP是面向切面编程&#xff08;Aspect-Oriented Programming&#xff09;的简称&#xff0c;它是一种编程思想&#xff0c;旨在在面向对象…...

openjdk和oracle jdk的区别

OpenJDK 和 Oracle JDK 都是 Java Development Kit (JDK) 的不同实现&#xff0c;用于开发和运行 Java 应用程序。它们有一些区别&#xff0c;但也有很多相似之处。以下是它们之间的主要区别&#xff1a; 开源性质&#xff1a; OpenJDK 是开源的&#xff0c;由一个社区维护和开…...

深度学习-Python调用ONNX模型

目录 ONNX模型使用流程 获取ONNX模型方法 使用ONNX模型 手动编写ONNX模型 Python调用ONNX模型 常见错误 错误raise ValueError...&#xff1a; 错误&#xff1a;Load model model.onnx failed 错误&#xff1a;CUDAExecutionProvider is not in available provider 错…...

[2023.09.24]: 今天差点又交白卷

今天周日&#xff0c;搞定了家里装修的一件事情&#xff0c;周末的事特别多&#xff0c;总算在10点的时候&#xff0c;解决了昨天那个输入焦点设置失败的问题。 在探索Rust编写基于web_sys的WebAssembly编辑器&#xff1a;挑战输入光标定位的实践中&#xff0c;我们总结了设置光…...

css,环形

思路&#xff1a; 1.先利用conic-gradient属性画一个圆&#xff0c;然后再叠加 效果图 <template><div class"ring"><div class"content"><slot></slot></div></div> </template> <script> import …...

php食堂点餐系统hsg5815ABA2程序-计算机毕业设计源码+数据库+lw文档+系统+部署

php食堂点餐系统hsg5815ABA2程序-(毕业设计毕设项目源代码课程设计程序设计指导xz2023) php食堂点餐系统hsg5815ABA2程序-计算机毕业设计源码数据库lw文档系统部署...

Vite打包时使用plugin解决浏览器兼容问题

一、安装Vite插件 在终端输入如下命令&#xff1a; npm add -D vitejs/plugin-legacy 二、配置config文件 在项目目录下创建vite.config.js文件夹&#xff0c;配置如下代码&#xff1a; import { defineConfig } from "vite"; import legacy from "vitejs/pl…...

java Excel 自用开发模板

下载导出 import com.hpay.admin.api.vo.Message; import com.hpay.admin.dubbo.IConfigDubboService; import com.hpay.admin.dubbo.IFileExportLogDubboService; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang.StringUtils; import org.apache.poi.hss…...

34.CSS魔线图标的悬停效果

效果 源码 index.html <!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Icon Fill Hover Effects</title> <link rel="stylesheet" h…...

Django — 会话

目录 一、Cookie1、介绍2、作用3、工作原理4、结构5、用途6、设置7、获取 二、Session1、介绍2、作用3、工作原理3、类型4、用途5、设置6、获取7、清空信息 三、Cookie 和 Session 的区别1、存储位置2、安全性3、数据大小4、跨页面共享5、生命周期6、实现机制7、适用场景 四、P…...

SpringBoot集成easypoi实现execl导出

<!--easypoi依赖&#xff0c;excel导入导出--><dependency><groupId>cn.afterturn</groupId><artifactId>easypoi-spring-boot-starter</artifactId><version>4.4.0</version></dependency>通过Exce注解设置标头名字和单…...

第9章 【MySQL】InnoDB的表空间

表空间 是一个抽象的概念&#xff0c;对于系统表空间来说&#xff0c;对应着文件系统中一个或多个实际文件&#xff1b;对于每个独立表空间来说&#xff0c;对应着文件系统中一个名为 表名.ibd 的实际文件。大家可以把表空间想象成被切分为许许多多个 页 的池子&#xff0c;当我…...

工作、生活常用免费api接口大全

手机号码归属地&#xff1a;提供三大运营商的手机号码归属地查询。全国快递物流查询&#xff1a;1.提供包括申通、顺丰、圆通、韵达、中通、汇通等600快递公司在内的快递物流单号查询。2.与官网实时同步更新。3.自动识别快递公司。IP归属地-IPv4区县级&#xff1a;根据IP地址查…...

寻找单身狗

在一个数组中仅出现一次&#xff0c;其他数均出现两次&#xff0c;这个出现一次的数就被称为“单身狗“。 一.一个单身狗 我们知道异或运算操作符 ^ &#xff0c;它的特点是对应二进制位相同为 0&#xff0c;相异为 1。 由此我们容易知道两个相同的数,进行异或运算得到的结果…...

【pytest】 allure 生成报告

1. 下载地址 官方文档; Allure Framework 参考文档&#xff1a; 最全的PytestAllure使用教程&#xff0c;建议收藏 - 知乎 https://github.com/allure-framework 1.2安装Python依赖 windows&#xff1a;pip install allure-pytest 2. 脚本 用例 import pytest class …...

动态链接库搜索顺序

动态链接库搜索顺序 同一动态链接库 (DLL) 的多个版本通常存在于操作系统 (OS) 内的不同文件系统位置。 可以通过指定完整路径来控制从中加载任何给定 DLL 的特定位置。 但是&#xff0c;如果不使用该方法&#xff0c;则系统会在加载时搜索 DLL&#xff0c;如本主题中所述。 DL…...

【CAN、LIN通信的区分】

CAN和LIN是两种不同的通信协议&#xff0c;用于不同的应用场景。CAN&#xff08;Controller Area Network&#xff09;是一种高速、可靠、多节点的串行通信协议&#xff0c;主要用于汽车电子领域的高速数据传输和控制&#xff1b;而LIN&#xff08;Local Interconnect Network&…...

XML Group端口详解

在XML数据映射过程中&#xff0c;经常需要对数据进行分组聚合操作。例如&#xff0c;当处理包含多个物料明细的XML文件时&#xff0c;可能需要将相同物料号的明细归为一组&#xff0c;或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码&#xff0c;增加了开…...

[特殊字符] 智能合约中的数据是如何在区块链中保持一致的?

&#x1f9e0; 智能合约中的数据是如何在区块链中保持一致的&#xff1f; 为什么所有区块链节点都能得出相同结果&#xff1f;合约调用这么复杂&#xff0c;状态真能保持一致吗&#xff1f;本篇带你从底层视角理解“状态一致性”的真相。 一、智能合约的数据存储在哪里&#xf…...

ElasticSearch搜索引擎之倒排索引及其底层算法

文章目录 一、搜索引擎1、什么是搜索引擎?2、搜索引擎的分类3、常用的搜索引擎4、搜索引擎的特点二、倒排索引1、简介2、为什么倒排索引不用B+树1.创建时间长,文件大。2.其次,树深,IO次数可怕。3.索引可能会失效。4.精准度差。三. 倒排索引四、算法1、Term Index的算法2、 …...

高防服务器能够抵御哪些网络攻击呢?

高防服务器作为一种有着高度防御能力的服务器&#xff0c;可以帮助网站应对分布式拒绝服务攻击&#xff0c;有效识别和清理一些恶意的网络流量&#xff0c;为用户提供安全且稳定的网络环境&#xff0c;那么&#xff0c;高防服务器一般都可以抵御哪些网络攻击呢&#xff1f;下面…...

Java 二维码

Java 二维码 **技术&#xff1a;**谷歌 ZXing 实现 首先添加依赖 <!-- 二维码依赖 --><dependency><groupId>com.google.zxing</groupId><artifactId>core</artifactId><version>3.5.1</version></dependency><de…...

10-Oracle 23 ai Vector Search 概述和参数

一、Oracle AI Vector Search 概述 企业和个人都在尝试各种AI&#xff0c;使用客户端或是内部自己搭建集成大模型的终端&#xff0c;加速与大型语言模型&#xff08;LLM&#xff09;的结合&#xff0c;同时使用检索增强生成&#xff08;Retrieval Augmented Generation &#…...

在Ubuntu24上采用Wine打开SourceInsight

1. 安装wine sudo apt install wine 2. 安装32位库支持,SourceInsight是32位程序 sudo dpkg --add-architecture i386 sudo apt update sudo apt install wine32:i386 3. 验证安装 wine --version 4. 安装必要的字体和库(解决显示问题) sudo apt install fonts-wqy…...

return this;返回的是谁

一个审批系统的示例来演示责任链模式的实现。假设公司需要处理不同金额的采购申请&#xff0c;不同级别的经理有不同的审批权限&#xff1a; // 抽象处理者&#xff1a;审批者 abstract class Approver {protected Approver successor; // 下一个处理者// 设置下一个处理者pub…...

推荐 github 项目:GeminiImageApp(图片生成方向,可以做一定的素材)

推荐 github 项目:GeminiImageApp(图片生成方向&#xff0c;可以做一定的素材) 这个项目能干嘛? 使用 gemini 2.0 的 api 和 google 其他的 api 来做衍生处理 简化和优化了文生图和图生图的行为(我的最主要) 并且有一些目标检测和切割(我用不到) 视频和 imagefx 因为没 a…...

WPF八大法则:告别模态窗口卡顿

⚙️ 核心问题&#xff1a;阻塞式模态窗口的缺陷 原始代码中ShowDialog()会阻塞UI线程&#xff0c;导致后续逻辑无法执行&#xff1a; var result modalWindow.ShowDialog(); // 线程阻塞 ProcessResult(result); // 必须等待窗口关闭根本问题&#xff1a…...