11、数码相框编写程序之MainPage显存管理与页面规划

2023-10-12 07:59

本文主要是介绍11、数码相框编写程序之MainPage显存管理与页面规划,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • 1、显存的分配和获取
    • 1.1、构造显存链表的结构体
    • 1.2、显存分配函数
      • 1、将我们自己分配的显存加入显存链表
      • 2、 将LCD 实际设备FB 显存加入链表
    • 1.3、显存获取函数
  • 2、显示页面图标函数框架构思
  • 3、编写MainPage页面
    • 3.1、获得显存
    • 3.2、描画数据
      • 1、判断或得到的显存是否已经存在像素数据
      • 2、 获得 LCD 的分辨率
      • 3、确定缩放尺寸
      • 4、首张图标在 LCD 的位置
      • 5、提供缩放后的目标图标的图片数据描述结构体
      • 6、定义一个图标位置描述结构体
      • 7、循环获取原始图片的像素数据,图标的左边数据,缩放、合并
      • 8、释放空间和修改显存数据状态标志位
    • 3.3、数据刷入LCD
    • 3.4、解放显存
  • 4、输入功能
    • 4.1、修改事件类型结构体
    • 4.2、修改输入设备的获取事件函数
    • 4.3、实现对应页面中获取事件并处理的部分
  • 5、测试
    • 5.1、修改之前的代码
    • 5.2、启动开发板

上一节:10、数码相框编写程序之图标显示

下一节:12、数码相框编写程序之效果演示与代码讲解

在上一小节中实现了图标的显示,基本工作就准备好了。现在要来做的是显示下面这些页面:
在这里插入图片描述
先做主页面的显示:
在这里插入图片描述
我们要在显示main_page.c页面的三个图标出来,其实完成的就是我们之前每个页面的框架中的第一步显示页面,即完成如下截图部分的代码。
在这里插入图片描述

1、显存的分配和获取

在写这个代码之前,我们先来了解一下硬件上面是怎么回事:不管你用的是什么开发板,在我们的板子上面,2440 也好或者其他单板也好,里面会有 LCD 控 制 器 或 者 称 为 显 卡 ,外 面 接 有LCDLCD 控制器或者显卡上面对应要有显存。我们写显示器的驱动程序的时候会在内存里面分配一块所谓的显存,在我们这里称为 framebuffer。而 LCD 控制器或者显卡会从 framebuffer 里把数据取出来,发给 LCD。当我们想显示图片的话,直接把图片写到 framebuffer 里就可以了。

那我们写应用程序时怎么做呢?可以先打开驱动程序,得到这块framebuffer,然后就可以在这块显存里面直接写数据了。但是这样有缺点,如果你的程序运行得很慢,当你在 LCD 上面描图片的时候就会发现是一行一行很慢地描。就是说内容更新的很慢。

那我们到底一般会这么做呢?会先 malloc 一块内存,这块内存和 framebuffer 的大小是一样的。我们事先将要显示的图片数据全部放到这块内存里,弄好之后再一股脑 memcpyframebuffer 里面。这样 LCD 的图片就一下子更新好了。就不会出现逐行逐行或者逐块逐块地显示了。
在这里插入图片描述
所以针对于每个页面我们要先获得分配好的内存,然后设置里面的内容(主要是RGB数据部分和一些flag),然后写到我们实际的FB的显存中。

代码见:第 1 个 项 目 数 码 相 框 全 部 源 码 _ 图 片 _ 文 档 \ 源 码 ( 含 讲 课 过 程 中 即 时 编 写 的 文 档 )\12. 数 码 相 框 项 目\14.digital_photo_frame_8.4.2_图片_源码\14.digital_photo_frame_8.4.2 节_图片_源码\14.digial_photo_frame

应用程序事先分配好多块内存,用于显存:
在这里插入图片描述

1.1、构造显存链表的结构体

但是要考虑由于我们是嵌入式系统,针对于某些型号可能内存不够用,所以分配多个显存并非对应每种型号都适用的,所以我们要兼容这些型号,我们在构造显存的链表的时候,应该在最头部加上设备实际分配的fb的显存,对应这些内存不够用的设备,我们可以只使用这个显存链表的第一个成员即可,那么对于每个显存链表中结构体的成员应该如何考虑呢?(实际上也就是每个显存里面除了要保存RGB数据供实际的设备显存fb使用,还需要哪些表示来表示和区分这些其余的显存的,比如我现在有5个页面,也就是要分配5个显存,外加一个fb的实际设备的显存,假如我要显示main_page这个页面,我们首先要把main_page页面对应的显存里面对应的数据给fb就可以显示,但是要解决几个问题:怎么从显存链表里面找到main_page的显存呢?main_page里面的显存里面的RGB数据有没有准备好呢?等等),从如上几点考虑,我们的显存链表结构体构造成员如下:

  • 1、由于我们的目的是为了让所有的页面都对应分配一个显存,那样对应每个页面都会有对应的显存保存它的数据,我们之后用户操作返回,或者前进时,在每个页面的显存就不用再次去设置里面的内容,所以我们需要一个ID来标识每个显存,当用户去返回,或者跳转到另外的页面时,就可以直接利用原来的对应的显存来进行显示里面的数据,所以需要以ID来辨别显存;
  • 2、我们之前有提到过,在用户点击触摸之后,会有一段时间的间隙,我们利用这段间隙,把可能下次要准备的页面通过多线程的方式准备好,所以我们还需要一个成员用来判断这个显存是给主线程使用,还是prepare线程使用的,另外给个初始状态是未被使用的,所以需要一个显存的进程使用状态eVideoMemState
  • 3、我们所分配的显存中主要还是用来存放要显示的每一页的数据,我们需要定义一个标志位来表示这个显存里面的对应的数据的情况,,是已经有了数据,还是正在产生数据,还是空的,成员为ePicState
  • 4、最开始我们说了我们要在链表的头部加上一个实际LCD设备的fb的显存,但是我们如何标识出链表中的成员是不是fb的实际设备显存呢,用标志位bDevFrameBuffer表示;
  • 5、最主要的还是给每个显存里面提供要现实页面的RGB数据,也就是我们之前有定义的T_PixelDatas tPixelDatas
  • 6、最后就是要提供链表的指向下一个链表的成员struct VideoMem *ptNext

最终的结构体定义如下:
在这里插入图片描述
构造完显存的链表的结构体之后,我们就要实现这个链表,我们肯定要提供一个分配显存的函数int AllocVideoMem(int iNum),其次我们最终是要把链表里面的某一个显存成员memcpyfb实际的显存,所以我们还需要一个从链表中提取显存的函数,我们分配显存肯定能是在应用层最开始就配分的,比如说我们要分配5块显存,里面的具体内容在最开始分配的时候基本上都是一样的,比如ID都设置为0,当具体的页面比如main_page去取显存的时候,发现5个的ID都是0,就会随机取一块然后再具体分配ID和对应的页面的RGB数据给显存,下次相同的页面只需要再取到同样的ID的显存就可以了。

1.2、显存分配函数

提供一个分配显存的函数给最顶层使用,我们先来看分配显存的函数如何实现。

1、将我们自己分配的显存加入显存链表

针对于我们要分配的显存,我们肯定是用malloc来分配,那么要分配多大呢?要注意的是并非sizeof(T_VideoMem)这么大,T_VideoMem这个结构体只是用来标识我们的分配的显存的,里面虽然有定义对应页面的数据的指针,但sizeof(T_VideoMem)并没有包含页面对应数据的大小,所以还要分配对应页面数据的大小,其实我们的数据也就是我们LCD的分辨率的大小:sizeof(T_VideoMem) + LCD的数据大小

  • 1、获取LCD的分辨率
    要获得我们LCD的数据大小,就是要获取我们LCD的分辨率来计算的,我们之前的代码有获取x、y值,但要知道要分配多少个字节,还需要知道bpp参数,所以修改代码:
    在这里插入图片描述
    然后我们就可以获取bpp了:
    在这里插入图片描述
  • 2、然后就是初始化PT_VideoMem ptNew里面成员的各项
    在这里插入图片描述
    PT_VideoMem ptNew中有一个指向对应页面数据的指针,分配到我们链表结构体后面即可:
    在这里插入图片描述
    也就是说我们分配的显存的结构就是前面有个PT_VideoMem类型的显存描述结构体指针,后面紧接着显存的实际页面数据,让PT_VideoMem里面的显存某个指向数据的指针指向后面的实际数据。
  • 3、初始化完成之后就是要这项显存放入链表中
    在这里插入图片描述
    如何理解这样就把新的显存结构体加入了链表呢?
    在这里插入图片描述
    我们每次都让刚定义的结构体的下一项指向链表头部ptNew->ptNext = g_ptVideoMemHead;,然后让链表的头部更新为刚才最后加入的结构体g_ptVideoMemHead = ptNew;这种方式就是链表的头部永远是最后更新的结构体。

2、 将LCD 实际设备FB 显存加入链表

加入完链表之后别忘了我们在链表里面还要添加一个FB的实际设备的显存,对于我们的LCD的真正的设备显存,由于我们在初始化display设备的时候就已经分配了,这里我们只需要分配一个显存链表结构体的大小,然后让显存链表结构体里面的实际像素数据成员指向我们之前分配的LCD的设备显存即可,然后再初始化实际显存对应的链表结构体各项,最后加入链表。

  • 1、分配实际链表显存对应的结构体
    在这里插入图片描述
  • 2、初始化实际显存对应的链表结构体各项
    在这里插入图片描述
  • 3、加入链表
    在这里插入图片描述
    最终的分配显存的代码如下:
    在这里插入图片描述

1.3、显存获取函数

下面来看看取显存的函数,我们肯定是根据ID来取

PT_VideoMem GetVideoMem(int iID, int bCur) {1. 优先: 取出空闲的、ID相同的videomem2. 取出任意一个空闲videomem
}

在这里插入图片描述

2、显示页面图标函数框架构思

回到我们本节的主要目的就是为了显示main_page上面的三个图标,之前的我们完成了准备工作,显存的分配和提取函数,接下来我们看看如何显示图标,也就是完成下面的第一步显示页面:
在这里插入图片描述
创建显示页面的函数,并构思实现的步骤:

  • 1、获得显存:应用层通过调用刚才的分配显存函数,分配了若干个显存,我们们首先要获取一个显存(这个显存可能是已经被使用过的相同ID的显存,也可能是块空显存)。
  • 2、描画数据:我们要将我们的main_page里面的图标对应的像素数据提取出来,经过图片缩放和合并之后,最终将像素数据放到刚才分配的显存中。
  • 3、刷到设备上去:由于我们之前只是把数据放到了我们自己分配的显存中,并没有放到LCD真正的设备FB显存,所以并不会显示,我们需要想之前显存的数据拷贝到FB显存中。
  • 4、解放显存:使用完我们分配的显存之后,我们要把他的状态置为VMS_FREE状态,供给下次或者别人使用,这是不是释放掉而是置标志位而已。

3、编写MainPage页面

上面我们知道针对于每个页面我们要先获得分配好的内存,然后设置里面的内容(主要是RGB数据部分和一些flag),然后写到我们实际的FB的显存,上一节中我们已经写好了分配内存和提取内存的函数,这一节,我们来按照上面的步骤针对于每一页具体的来显示一个一个页面的内容:
在这里插入图片描述
具体的就是实现上面的显示页面的函数:
在这里插入图片描述
应该如何实现上面的函数呢?

3.1、获得显存

在这里插入图片描述
第二参数1,代表这个显存用于主线程,而不是prepare线程。我们这里的ID并不是简单的1,2,3,4,而是根据名字字符串转换为一个int型数据:
在这里插入图片描述

3.2、描画数据

我们要把main_page里面的所有图标的数据经过缩放和合并之后保存到我们的上面一步获得的显存中,那么要缩放和合并的话,我们首先就要知道原始图片的数据和我们想缩放到什么尺寸,其次合并的话我们还要确定我们每个图标在LCD上显示的位置,我们的图片的位置是根据LCD的实际分辨率来按比例设置的。

1、判断或得到的显存是否已经存在像素数据

判断获得到的显存结构体里面对应的像素数据是否已经生成过了,首先要判断显存的里面的RGB数据是否已经存在,只要判断ePicState就行。
在这里插入图片描述

2、 获得 LCD 的分辨率

在这里插入图片描述

3、确定缩放尺寸

在这里插入图片描述
由于我们的原始图片的大小为256*128,我们自己定义下要显示的图片的位置(这是我们自己规划的),如下图:红色的边框就认为是LCD的边界。
在这里插入图片描述
即缩放后的长和宽是多少?(矩形图片只要知道这两个值就好)
在这里插入图片描述
在我们main_page页面中有三个单元要显示,每个大小是一样的,都是:
在这里插入图片描述

4、首张图标在 LCD 的位置

在这里插入图片描述

5、提供缩放后的目标图标的图片数据描述结构体

由于我们知道我们的缩放函数出入的参数是原图片和目标图片的图片数据结构体
在这里插入图片描述
缩放前后bpp值不变(LCDbpp),长宽为缩放后的数据,即如下:
在这里插入图片描述

6、定义一个图标位置描述结构体

我们知道了缩放后目标图片的大小,现就待会要去合并,合并需要提供一个显示起点的左标,我们有3个图标,可以通过定义一个结构体,这个结构体用来描述每个图标应该位于的左边,和图标的名字,然后通过循环去一个个缩放合并。
我们现在自己定义了每个图标的位置,我们对于每个图标抽象出一个结构体来描述这个图标的。我们知道每个图标都是矩形,我们只要知道了图标的左上和右下的坐标就基本上知道了图标的位置。在page_manager.h里面定义如下结构体:
在这里插入图片描述
接下来我们在main_page.c里面针对于每个图标都定义一个该结构体,所以定义一个结构体数组:
在这里插入图片描述
一开始我们都设置前面的坐标都为0,由于我们待会要循环去显示给每个图标赋值,那么我们怎么知道图标结尾了呢?我们就添加了最后一项,每个成员都设置为空。现在我们就是要在描绘图标里面把前面的上面的结构体的前面几项描绘出来,所以我们直接把每个图标作为参数传递给显示的函数就比较方便了:
在这里插入图片描述
这也是我们这个函数参数的由来,知道了这些我们就可以设置我们显存中关于图片的信息的数据了。

7、循环获取原始图片的像素数据,图标的左边数据,缩放、合并

由于我们每个图标只有Y值会变,X不变(右下的x,y都是根据左上来计算的)我们设定好了缩放后的图片的数据,现在要获取原始图片的像素数据
在这里插入图片描述
分析上面的重点部分,上面的:
在这里插入图片描述
他需要传入一个原始图片的数据信息和新图片的数据信息,那么我们如何获得一个原始图片的信息呢?我们之前8.3.3测试的main函数里面是先open一个文件,然后再去获取的,现在我们就参照之前的步骤:
在这里插入图片描述
定义一个函数,传入图标的名字来获取对应图标的像素数据,该函数的步骤:

  • 1、定义一个文件的描述结构体,里面有文件的路径、大小、描述符、还有一个指针(是用来指向文件的内容的)
    在这里插入图片描述
  • 2、通过传入的图标名构造正确的文件路径,并保存在上面的一个结构体变量中
    在这里插入图片描述
  • 3、构造一个MapFile去打开刚才路径的图标文件,并将文件的内容映射到内存中
    在这里插入图片描述
    MapFile的实现如下:
    在这里插入图片描述
    这里就让我们的传入的PT_FileMap变量中的一个指针pucFileMapMem指向了我们分配的内存,而这个内存里面的数据就是文件内容,我们想要知道文件的像素数据,就只要操作这个pucFileMapMem就可以了,同时构造一个取消映射的函数:
    在这里插入图片描述
  • 4、之后去解析刚才的放到内存的文件的数据,判断是否为bmp格式文件,通过判断文件内容的第一个和第二个内容数据是否为424d
    在这里插入图片描述
    g_tBMPParser这个结构体变量是个全局结构体变量,都可以用。
  • 5、在获取原始图片的像素的数据之前,由于GetPixelDatas函数需要对不同的bpp有不同的数据返回,我们要先获取lcdbpp
    在这里插入图片描述

8、释放空间和修改显存数据状态标志位

在这里插入图片描述

3.3、数据刷入LCD

我们前面已经获取完显存,然后把要显示的数据放到了我们获取到的显存上,现在我们要把这个显存的数据复制到FB的实际显存上才能显示,构造如下函数来实现:
在这里插入图片描述
函数实现如下:
在这里插入图片描述
要先判断得到的显存不是实际的FB的显存,因为我们的FB显存也是在显存链表中的。

3.4、解放显存

在这里插入图片描述
实现如下:
在这里插入图片描述

4、输入功能

在上一小节里面,我们描绘了在 LCD 上显示的主页面的三个图标,这一节讲输入功能。
在这里插入图片描述
我们前面完成了显示页面,按照流程我们还有创建parepare线程获取输入事件处理,我们先做后面一个环节,然后就可以调试了。
在这里插入图片描述
现在我们要实现,当用触摸笔在 LCD 上点击图标时,图标就要改变一下颜色。当松开触摸笔时,图标恢复原来的颜色。

4.1、修改事件类型结构体

我们这个要产生触摸事件的代码目前还是参照在电子书的基础上的代码,我们回顾下电子书关于触摸事件的代码,input文件里面定义的结构体是:
在这里插入图片描述
进入产生事件的函数的代码,发现是根据我们的触摸位置来产生翻页等几个简单的动作,肯定是不能满足我们目前的需求的:
在这里插入图片描述
对于我们数码相框而言,我们需要知道更精确的触摸位置是点下还是松开,我们现在要修改获取触摸事件的函数,先修改我们的事件类型的结构体:
在这里插入图片描述
之前我们只抽象出事件的时间值,还有事件触发的类型(标准输入还是ts),还有事件值(翻页等动作)现在我们要定义一个抽象出一个事件的结构体,他既能描述触摸点事件和按键事件,对于触摸点事件,我们要有触摸的x,y坐标,按下还是松开,对于按键事件,要有按下和松开,还有是哪个按键按下,结构体如下:
在这里插入图片描述
其实上面的这个结构体可以参考tslib,上面的结构体中
类别:当我的type是触摸屏的时候,我们用到成员有x、y、还有压力
当我的type是按键或者标准输入的时候,用到key和压力

上面的结构体中的x、y坐标对触摸有用;
上面的压力值对于按键和触摸都用,按键松开时压力为0,按下为1;
上面的IKEY对按键有用。

4.2、修改输入设备的获取事件函数

修改完结构体后,我们修改touchscreen.c中的TouchScreenGetInputEvent函数,之前是根据触摸在LCD的位置来返回事件,现在我们要在获取事件后返回真实的数据,也就是上面定义的事件的结构体:
在这里插入图片描述
对于触摸屏基本就这样就可以了,接下来我们改下标准输入的事件获取函数StdinGetInputEvent,由于我们目前还没确定每个图标对应哪个按键来触发,所以暂时先不管StdinGetInputEvent,我们先暂时只考虑从触摸屏来触发事件。

4.3、实现对应页面中获取事件并处理的部分

接下来我们要看下我们的page里面的main_page.c,我们要通过获取到事件,然后进行动作:
在这里插入图片描述
接下来我们来实现MainPageGetInputEvent函数,肯定这个函数里面也是调用我们之前input里面的int GetInputEvent(PT_InputEvent ptInputEvent)所以我们传入一个事件类型的结构体,用来保存触发的事件的相关信息,另外我们要判断触发的事件为我们页面中的哪个图标,所以需要传入我们的图标描述的结构体PT_Layout atLayout确认了函数的参数,继续构想要如何实现main_page里面的获取事件函数

  • 1、通过input层提供的GetInputEvent来获取事件
    在这里插入图片描述
    没获取到事件就休眠,有事件后触发,由于现在只考虑触摸屏触发,我们要知道我们触摸到了哪一个图标,由于我们之前有定义过每个页面中的每个图标的左上和右下的坐标的结构体:
    在这里插入图片描述
    我们就可以根据这个结构体来判断我们的触摸的位置是否在这个图标的坐标之内来判断,由于我们要返回一个哪个Layout的图标被触发了,所以我们把ptInputEvent里面新增一个Layout成员。
  • 2、根据mian_page里面的图标的坐标和刚才通过事件获取函数记录到的x,y等信息来判断
    在这里插入图片描述
    这个函数返回:事件触发的图标的序号。

接下来返回我们的MainPageRun继续写代码:我们要实现当用触摸笔在 LCD 上点击图标是,图标就要改变一下颜色。当松开触摸笔时,图标恢复原来的颜色。

刚才我们已经可以获取事件,并知道是哪个图标被触摸了,找到了这个图标是否被触摸了之后,那么我们怎么知道他是被点下了还是松开了?针对于我们触发的事件,我们只要按照如下逻辑分类,我们只对所有的触发事件的两个时刻做处理,其余不理会

  • 1、某触摸图标被按下,且之前未被按下
  • 2、某触摸图标未被按下,且之前该图被按下

在这里插入图片描述
我们用bPressed来代表该图标之前是否被按下过,用iIndexPressed来记录触发按键的图标序号。

每次图标的变化动作就将图标的对应的显存的里面的像素数据取反即可(要注意的是这里的的显存是当前用于显示的真正的设备FB显存,而不是给每个页面分配的显存)。

像素取反函数static InvertButton(PT_Layout ptLayout)先获取真正的显存FB
在这里插入图片描述
然后找到要取反的图标的像素数据在FB显存的位置:
在这里插入图片描述
然后一行行取反:
在这里插入图片描述

上一节:10、数码相框编写程序之图标显示

下一节:12、数码相框编写程序之效果演示与代码讲解

5、测试

前面三节讲了 mainpage 的显存管理、页面规划、输入功能。
在这里插入图片描述
现在这一个我们把之前写的程序调试一下,然后在开发板上运行,观察效果。当韦东山录制完这一节之后,会发布一个 8.4.4 源码
在这里插入图片描述
可以跟 8.4.3 源码比较一下,这样就可以看出来做了哪些修改。因为这一节会讲得比较啰嗦,如果你不想从头到尾一句话一句话地改的话,直接比较最终结果。

修改前的代码见:第 1 个项目数码相框全部源码_图片_文档\源码(含讲课过程中即时编写的文档)\12.数码相框项目\14.digital_photo_frame_8.4.3_ 源 码\14.digital_photo_frame_8.4.3 节 _ 源 码\14.digial_photo_frame

修改后的代码见:第 1 个项目数码相框全部源码_图片_文档\源码(含讲课过程中即时编写的文档)\12.数码相框项目\14.digital_photo_frame_8.4.4_源码_文档\14.digital_photo_frame_8.4.4 节_源码_文档\14.digial_photo_frame

以后参考代码时:
8.4.3 里的代码就不要参考了,里面有很多错误。
8.4.4 里的代码可以参考。

5.1、修改之前的代码

修改顶层 Makefile,把所有的警告当做错误处理:
在这里插入图片描述
修改为:
在这里插入图片描述这样就可以编译出一点警告都没有的程序了。顶层 Makefile的其他修改参考说明

修改底层 Makefile: 参考说明文档
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
定位到 132 行:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

5.2、启动开发板

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

上一节:10、数码相框编写程序之图标显示

下一节:12、数码相框编写程序之效果演示与代码讲解

这篇关于11、数码相框编写程序之MainPage显存管理与页面规划的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/194434

相关文章

用Microsoft.Extensions.Hosting 管理WPF项目.

首先引入必要的包: <ItemGroup><PackageReference Include="CommunityToolkit.Mvvm" Version="8.2.2" /><PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.0" /><PackageReference Include="Serilog

JAVA读取MongoDB中的二进制图片并显示在页面上

1:Jsp页面: <td><img src="${ctx}/mongoImg/show"></td> 2:xml配置: <?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001

大语言模型(LLMs)能够进行推理和规划吗?

大语言模型(LLMs),基本上是经过强化训练的 n-gram 模型,它们在网络规模的语言语料库(实际上,可以说是我们文明的知识库)上进行了训练,展现出了一种超乎预期的语言行为,引发了我们的广泛关注。从训练和操作的角度来看,LLMs 可以被认为是一种巨大的、非真实的记忆库,相当于为我们所有人提供了一个外部的系统 1(见图 1)。然而,它们表面上的多功能性让许多研究者好奇,这些模型是否也能在通常需要系

关于如何更好管理好数据库的一点思考

本文尝试从数据库设计理论、ER图简介、性能优化、避免过度设计及权限管理方面进行思考阐述。 一、数据库范式 以下通过详细的示例说明数据库范式的概念,将逐步规范化一个例子,逐级说明每个范式的要求和变换过程。 示例:学生课程登记系统 初始表格如下: 学生ID学生姓名课程ID课程名称教师教师办公室1张三101数学王老师101室2李四102英语李老师102室3王五101数学王老师101室4赵六103物理陈

JavaScript全屏,监听页面是否全屏

在JavaScript中,直接监听浏览器是否进入全屏模式并不直接支持,因为全屏API主要是关于请求和退出全屏模式的,而没有直接的监听器可以告知页面何时进入或退出全屏模式。但是,你可以通过在你的代码中跟踪全屏状态的改变来模拟这个功能。 以下是一个基本的示例,展示了如何使用全屏API来请求全屏模式,并在请求成功或失败时更新一个状态变量: javascriptlet isInFullscreen =

springboot家政服务管理平台 LW +PPT+源码+讲解

3系统的可行性研究及需求分析 3.1可行性研究 3.1.1技术可行性分析 经过大学四年的学习,已经掌握了JAVA、Mysql数据库等方面的编程技巧和方法,对于这些技术该有的软硬件配置也是齐全的,能够满足开发的需要。 本家政服务管理平台采用的是Mysql作为数据库,可以绝对地保证用户数据的安全;可以与Mysql数据库进行无缝连接。 所以,家政服务管理平台在技术上是可以实施的。 3.1

vue同页面多路由懒加载-及可能存在问题的解决方式

先上图,再解释 图一是多路由页面,图二是路由文件。从图一可以看出每个router-view对应的name都不一样。从图二可以看出层路由对应的组件加载方式要跟图一中的name相对应,并且图二的路由层在跟图一对应的页面中要加上components层,多一个s结尾,里面的的方法名就是图一路由的name值,里面还可以照样用懒加载的方式。 页面上其他的路由在路由文件中也跟图二是一样的写法。 附送可能存在

vue+elementui分页输入框回车与页面中@keyup.enter事件冲突解决

解决这个问题的思路只要判断事件源是哪个就好。el分页的回车触发事件是在按下时,抬起并不会再触发。而keyup.enter事件是在抬起时触发。 so,找不到分页的回车事件那就拿keyup.enter事件搞事情。只要判断这个抬起事件的$event中的锚点样式判断不等于分页特有的样式就可以了 @keyup.enter="allKeyup($event)" //页面上的//js中allKeyup(e

vue子路由回退后刷新页面方式

最近碰到一个小问题,页面中含有 <transition name="router-slid" mode="out-in"><router-view></router-view></transition> 作为子页面加载显示的地方。但是一般正常子路由通过 this.$router.go(-1) 返回到上一层原先的页面中。通过路由历史返回方式原本父页面想更新数据在created 跟mounted

vue3项目将所有访问后端springboot的接口统一管理带跨域

vue3项目将所有访问后端springboot的接口统一管理带跨域 一、前言1.安装Axios2.创建Axios实例3.创建API服务文件4.在组件中使用API服务 二、跨域三、总结 一、前言 在Vue 3项目中,统一管理所有访问后端Spring Boot接口的最佳实践是创建一个专门的API服务层。这可以让你的代码更加模块化、可维护和集中管理。你可以使用Axios库作为HTT