【Qt移植LVGL】QWidget手搓LVGL软件仿真模拟器(非直接运行图形库)

【Qt移植LVGL】QWidget手搓LVGL软件仿真模拟器(非直接运行图形库)

打包开源地址:
Qt函数库gitee地址

更新以gitee为准

移植后的demo工程:
gitee
有些没实现的 后续我会继续优化

文章目录

  • 别碰瓷看清楚:是移植,不是直接运行LVGL
  • Qt的C/C++混编
  • Qt的模拟显示触摸屏
  • LVGL的API函数编写
  • LVGL文件移植
  • LVGL工程配置
  • LVGL显示配置
  • LVGL触摸配置
  • 主线程初始化和定时器轮询
  • 测试
  • 附录:C语言到C++的入门知识点(主要适用于C语言精通到Qt的C++开发入门)
    • C语言与C++的不同
    • C++中写C语言代码
    • C语言到C++的知识点
    • Qt开发中需要了解的C++基础知识
      • namespace
      • 输入输出
      • 字符串类型
      • class类
        • 构造函数和析构函数(解析函数)
        • 类的继承

别碰瓷看清楚:是移植,不是直接运行LVGL

LVGL是一种轻量级嵌入式图像界面库 且不需要多线程就能跑通
这里的在Qt上面移植LVGL并不是用Qt的IDE去建立一个没有Qt应用的工程 然后编译运行带SDL2等图形库的程序 从而实现在PC上运行LVGL
而是将Qt的窗口作为一个完整的嵌入式设备进行移植 使LVGL调用Qt窗口来进行显示和输入

说到FreeRTOS和LVGL这两种模拟多线程代表 我的个人理解就是:
FreeRTOS是硬件上的系统移植 其根据不同架构调用了硬件底层中断 systick等外设 以实现任务调度 属于用外设硬件模拟的多线程
LVGL的多线程是用两个定时器中断 不断刷新页面 进行操作 其触摸延迟至少得5ms 属于软件层面的多线程运行 实际上就相当于一个while 1里面不断刷新页面罢了
很早之前用51单片机+LCD1602写界面也是用一个while+状态判断来写的

Qt的C/C++混编

C++是兼容C的
在Qt的工程里面 可以直接添加C文件
但是调用C文件时 却不能直接拿来用
除了导入C文件对应的头文件函数声明外
还需要加上extern "C"来表示下面代码按C语言文件的方式编译
譬如

#ifdef __cplusplus
extern "C" {
#endif...//C文件的函数声明#ifdef __cplusplus
}
#endif

这样才能正常调用不报错

另外 在C文件中 当然就用不了C++的函数
不过又想实现交互 有两种解决方式:
分别导入<csignal><signal.h>
自己给自己的进程发送信号
或者 直接将要调用C++函数的C文件改成cpp文件

显然 后者更方便

但在混编时 只需要写一个总的接口函数文件用于调用即可 该接口文件可以调用C++的函数
另外也可以调用子类的C语言函数

譬如A.cpp操作B.c 直接调用即可
但是B.c如果想给A.cpp的槽函数信号 再去判断做什么事(调用emit函数) 则可以定义一个C.cpp 在C.cpp中发送emit来做判断 然后再去操作B.c

Qt的模拟显示触摸屏

通过QWidget可以模拟出一个显示屏
【Qt开发】QWidget的虚拟触摸显示屏配置 QPainter、QPixmap以及resizeEvent、paintEvent、mouseEvent鼠标输入事件
同时采样信号队列的形式
去捕获按键输入等等

        connect(this, SIGNAL(goto_setStyle(int)),this, SLOT(setStyle(int)),Qt::QueuedConnection);connect(this, SIGNAL(goto_setWidth(int)),this, SLOT(setWidth(int)),Qt::QueuedConnection);connect(this, SIGNAL(goto_setColor(QColor)),this, SLOT(setColor(QColor)),Qt::QueuedConnection);connect(this, SIGNAL(goto_setBack(QColor)),this, SLOT(setBack(QColor)),Qt::QueuedConnection);connect(this, SIGNAL(goto_clear()),this, SLOT(clear()),Qt::QueuedConnection);connect(this, SIGNAL(goto_drawPoint(QPoint)),this, SLOT(drawPoint(QPoint)),Qt::QueuedConnection);connect(this, SIGNAL(goto_drawPoints(QPoint*,int)),this, SLOT(drawPoints(QPoint*,int)),Qt::QueuedConnection);connect(this, SIGNAL(goto_drawLine(QPoint,QPoint)),this, SLOT(drawLine(QPoint,QPoint)),Qt::QueuedConnection);connect(this, SIGNAL(goto_setTextStyle(int)),this, SLOT(setTextStyle(int)),Qt::QueuedConnection);connect(this, SIGNAL(goto_setTextFont(QString,int)),this, SLOT(setTextFont(QString,int)),Qt::QueuedConnection);connect(this, SIGNAL(goto_drawText(QRectF,QString)),this, SLOT(drawText(QRectF,QString)),Qt::QueuedConnection);connect(this, SIGNAL(goto_fillRect(QPoint,QPoint)),this, SLOT(fillRect(QPoint,QPoint)),Qt::QueuedConnection);
signals:void goto_setStyle(int s);void goto_setWidth(int w);void goto_setColor(QColor c);void goto_clear(void);void goto_setBack(QColor c);void goto_setTextStyle(int text_style);void goto_setTextFont(QString strfont,int size);void goto_drawText(QRectF rectangle,QString text);void goto_drawPoint(QPoint p);void goto_drawPoints(QPoint *p,int pointCount);void goto_drawLine(QPoint p1,QPoint p2);void mouse_signal(int mode,QPoint p);void goto_fillRect(QPoint p1,QPoint p2);

模拟的触摸屏只需要触摸功能即可

LVGL的API函数编写

在触摸显示屏上移植LVGL 涉及到的API只有画点、面,触摸按下、松开,触摸坐标函数
以上面的模拟显示屏为接口 编写LVGL的API函数如下:

#include "LVGL_API.h"LVGL_API_Class *LVGL_API;void drawPoint(int x,int y,unsigned short color)
{emit LVGL_API->display->goto_setStyle(1);QPoint p(x,y);int r=0;int g=0;int b=0;r=(color>>11)*8;g=((color>>5)&0x003F)*4;b=(color&0x001F)*8;QColor c(r,g,b);emit LVGL_API->display->goto_setColor(c);emit LVGL_API->display->goto_drawPoint(p);emit LVGL_API->display->goto_setStyle(0);
}void drawLine(int x1,int y1,int x2,int y2,unsigned short color)
{emit LVGL_API->display->goto_setStyle(1);QPoint p1(x1,y1);QPoint p2(x2,y2);int r=0;int g=0;int b=0;r=(color>>11)*8;g=((color>>5)&0x003F)*4;b=(color&0x001F)*8;QColor c(r,g,b);emit LVGL_API->display->goto_setColor(c);emit LVGL_API->display->goto_drawLine(p1,p2);emit LVGL_API->display->goto_setStyle(0);
}void fillRect_drawLine(int x1,int y1,int x2,int y2)
{QPoint p1(x1,y1);QPoint p2(x2,y2);emit LVGL_API->display->goto_drawLine(p1,p2);
}void fillRect(int x1,int y1,int x2,int y2,unsigned short color)
{
#if 0emit LVGL_API->display->goto_setStyle(1);QPoint p1(x1,y1);QPoint p2(x2,y2);QPoint p3(x1,y2);QPoint p4(x2,y1);int r=0;int g=0;int b=0;r=(color>>11)*8;g=((color>>5)&0x003F)*4;b=(color&0x001F)*8;QColor c(r,g,b);emit LVGL_API->display->goto_setColor(c);emit LVGL_API->display->goto_drawLine(p1,p3);emit LVGL_API->display->goto_drawLine(p1,p4);emit LVGL_API->display->goto_drawLine(p2,p3);emit LVGL_API->display->goto_drawLine(p2,p4);emit LVGL_API->display->goto_fillRect(p1,p2);emit LVGL_API->display->goto_setStyle(0);
#elseint i=0;emit LVGL_API->display->goto_setStyle(1);int r=0;int g=0;int b=0;r=(color>>11)*8;g=((color>>5)&0x003F)*4;b=(color&0x001F)*8;QColor c(r,g,b);emit LVGL_API->display->goto_setColor(c);for(i=0;i<=y2-y1;i++){fillRect_drawLine(x1,y1+i,x2,y1+i);}emit LVGL_API->display->goto_setStyle(0);
#endif
}void Init_LVGL_API(MY_Display *dis)
{LVGL_API = new LVGL_API_Class(dis);
}
#ifndef LVGL_API_H
#define LVGL_API_H
#include "MY_QT_DEF.h"void drawPoint(int x,int y,unsigned short color);
void fillRect(int x1,int y1,int x2,int y2,unsigned short color);
void drawLine(int x1,int y1,int x2,int y2,unsigned short color);class LVGL_API_Class;
class LVGL_API_Class: public QObject
{Q_OBJECTpublic:int Touch_x;int Touch_y;int Touch;MY_Display *display;LVGL_API_Class(MY_Display *dis=nullptr){Touch=0;if(dis!=nullptr){display=dis;connect(display, SIGNAL(mouse_signal(int,QPoint)),this, SLOT(TouchEvent(int,QPoint)),Qt::QueuedConnection);emit display->goto_setStyle(0);}}~LVGL_API_Class(void){}
public slots:void TouchEvent(int mode,QPoint p){if(mode==2){Touch=0;}else{Touch=1;}Touch_x=p.x();Touch_y=p.y();}
};extern LVGL_API_Class *LVGL_API;void Init_LVGL_API(MY_Display *dis);#endif // LVGL_API_H

其中 画面提供了两种方式 一个是for循环画线遍历 一个是直接填充然后再画边框
但这两个在Qt上实现对LVGL的兼容性不太好(Qt会将比较小的像素点给优化掉)
所以在LVGL显示方面 还是选择画点函数吧
譬如画点是正常的:
在这里插入图片描述
画面就糊掉了
在这里插入图片描述

LVGL文件移植

移植与在嵌入式设备上移植相似
直接按照STM32的移植方式进行即可
这里用的LVGL库版本是8.3
下载后 实际需要移植的就下面三个文件夹和两个文件
在这里插入图片描述
将这些文件复制到一个单独的文件夹 比如LVGL
在这里插入图片描述
并且删除掉_template后缀
在examples中只保留porting 文件夹
同样删除_template后缀
在这里插入图片描述
然后这个LVGL文件夹里面的内容就是我们要移植的文件 适用于所有工程
包括STM32、Qt、C工程等等

LVGL工程配置

将上面的文件拷贝到Qt工程中
不要将LVGL文件夹整个拷贝 而是将里面的内容拷贝过来
用命令表示的区别就是 一个是cp ./ 一个是 cp ./* 这里是后者
这是因为Qt的搜素头文件路径默认就是根目录
而LVGL里面的文件导入则是以相对路径来的 譬如src下的文件:
在这里插入图片描述
这样一看就明白了吧
当然 你直接拷个文件夹过来也不是不行 那你就得弄好相对路径

在源文件和头文件中添加
在这里插入图片描述
直接点击Add Existing Directory 即可筛选

要添加的文件如下:

首先是两个主要头文件:
lv_conf.h
lvgl.h

porting目录 下的四个文件
lv_port_disp.c 、lv_port_disp.h、 lv_port_indev.c、lv_port_indev.h

src 下的所有C文件

除此之外 其他的一律不要添加
可以按如下进行添加:
在这里插入图片描述
另外 如果你用的不是Qt Creator 那么就需要添加头文件搜素路径

LVGL显示配置

打开 lv_conf.h 修改文件
表示启用
在这里插入图片描述
打开 lv_port_disp.h
同样启用 并且头文件路径改一下
在这里插入图片描述
打开 lv_port_disp.c
启用 并且删除后缀
在这里插入图片描述
在 lv_port_disp.c中添加我们的LVGL_API.h
注意 LVGL_API.cpp是一个C++文件 所以为了能使用 需要将 lv_port_disp.c改成 lv_port_disp.cpp
同理 触摸的文件也要改
在这里插入图片描述
然后定义屏幕可用的大小
在这里插入图片描述
LVGL提供了三种缓存方式 选择一种 其他的注释
在这里插入图片描述
第一种最简单 而且不需要添加什么东西
先配置 配好了以后有时间自己再研究就好了

然后关联画点函数即可
在这里插入图片描述
这里有一种更为优化 刷新率更高的方式 就是直接移植填充一块区域的函数
但是就如上面所说的 Qt这块给优化掉了 导致细小边界看不清 所以就只能用画点函数

LVGL触摸配置

LVGL可以设置触摸、按键、鼠标事件
这里我们只用触摸
虽然Qt的鼠标事件也可以捕获 但是我们把所有的鼠标事件都定义为触摸就行了

配置如显示类似
在这里插入图片描述
一样导入文件定义区域
在这里插入图片描述
在93行以后 只保留触摸 注释掉鼠标和按键 一直到170行(除非你要使用)
在这里插入图片描述
添加检测触摸函数接口和获取坐标接口
在这里插入图片描述
即可

如果想看看触摸能不能生效 那么就添加一个画点的函数在触摸获取xy坐标的后面即可

帧率和触摸率还有待优化:
有些没实现的 后续我都会继续优化
在这里插入图片描述

主线程初始化和定时器轮询

在main中导入库:

#include "lvgl.h"                // 它为整个LVGL提供了更完整的头文件引用
#include "examples/porting/lv_port_disp.h"        // LVGL的显示支持
#include "examples/porting/lv_port_indev.h"       // LVGL的触屏支持

在窗口的构造函数中初始化模拟触摸屏后 进行LVGL初始化

    lv_init();                             // LVGL 初始化lv_port_disp_init();                   // 注册LVGL的显示任务lv_port_indev_init();                  // 注册LVGL的触屏检测任务

建立两个定时器线程 一个1ms 一个5ms 分别调用lv_tick_inc(1);lv_timer_handler();

void timer0_callback(void * pCBParam,uint32_t Event,void * pArg)
{lv_tick_inc(1);
}void timer1_callback(void * pCBParam,uint32_t Event,void * pArg)
{lv_timer_handler();
}Timer0 = new MY_Timer(timer0_callback,1,true);Timer1 = new MY_Timer(timer1_callback,5,true);Timer0->Start_Timer();Timer1->Start_Timer();

这就是LVGL的心跳

测试

建立几个控件测试一下:


void button_evnet(lv_event_t * event)
{qDebug()<<event->code;lv_obj_t *btn = lv_event_get_target(event);                    // 获得调用这个回调函数的对象if (event->code == LV_EVENT_CLICKED){static uint8_t cnt = 0;cnt++;lv_obj_t *label = lv_obj_get_child(btn, NULL);             // 获取第1个子对象(我们在设计时,已安排了它的第1个子对象是一个label对象)lv_label_set_text_fmt(label, "Button: %d", cnt);           // 设置标签的文本,写法类似printf}
}//按钮lv_obj_t *myBtn = lv_btn_create(lv_scr_act());                               // 创建按钮; 父对象:当前活动屏幕lv_obj_set_pos(myBtn, 10, 10);                                               // 设置坐标lv_obj_set_size(myBtn, 120, 50);                                             // 设置大小lv_obj_add_event_cb(myBtn, button_evnet, LV_EVENT_CLICKED, NULL); //添加事件// 按钮上的文本lv_obj_t *label_btn = lv_label_create(myBtn);                                // 创建文本标签,父对象:上面的btn按钮lv_obj_align(label_btn, LV_ALIGN_CENTER, 0, 0);                              // 对齐于:父对象lv_label_set_text(label_btn, "Test");                                        // 设置标签的文本// 独立的标签lv_obj_t *myLabel = lv_label_create(lv_scr_act());                           // 创建文本标签; 父对象:当前活动屏幕lv_label_set_text(myLabel, "Hello world!");                                  // 设置标签的文本lv_obj_align(myLabel, LV_ALIGN_CENTER, 0, 0);                                // 对齐于:父对象lv_obj_align_to(myBtn, myLabel, LV_ALIGN_OUT_TOP_MID, 0, -20);               // 对齐于:某对象

运行后效果:
在这里插入图片描述
帧率信息显示在:
lv_conf.h中第282行,找到:LV_USE_PERF_MONITOR,原值:0, 修改为:1

内存显示则在:
lv_conf.h中第289行,找到:LV_USE_MEM_MONITOR,原值:0, 修改为:1

附录:C语言到C++的入门知识点(主要适用于C语言精通到Qt的C++开发入门)

C语言与C++的不同

C语言是一门主要是面向工程的语言
C++则是面向对象

C语言中 某些功能实现起来较为繁琐
比如结构体定义:

一般写作:

typedef struct stu_A
{
}A;

也可以写作:

typedef struct 
{
}A;

但 大括号后面的名称是不可省去的

不过 C++的写法就比较简单
除了支持上述写法外

也支持直接声明

typedef struct A
{
}

另外 C++是完全支持C语言库和语法的
不过C++里面的库也有些很方便的高级功能用法 只不过实现起来可能不如C的速度快

再者 C语言与C++的编译流程不一样
C语言没有函数重载 所以给编译器传参就是直接传函数名称
但是C++除了传函数名称外 还会穿函数的参数、类型等等 以实现函数重载

C++中写C语言代码

上文提到 C++可以完全兼容C的写法
但是编译流程也还是不一样
所以如果在编译层面进行C语言代码编译 则通常用以下方法:

extern "C"
{
...
}

表面大括号内的内容用C的方法进行编译

另外 如果还是用C++的编译器 但要实现C语言函数 则需要用到C语言的库

在C语言中 我们一般用如下方法导入库

#include <stdio.h>

此方法同样适用于C++ 但是C++可以更方便的写成去掉.h的方式
比如:

#include <iostream>

在C++中 为了调用C语言的库 可以采用在原库名称前加一个"c"的方式导入
如:

#include <cstdio>

这样就可以使用printf等函数了 甚至比C++的std方法更快

C语言到C++的知识点

在这里插入图片描述

Qt开发中需要了解的C++基础知识

namespace

C++面向对象的特性下诞生的一个名称
表示某个函数、变量在某个集合下 用作namespace
比如 <iostream>库中的关键字cin在std下 则写作std::cin
std就是namespace
::表示某空间下的某某
前面是空间名称 后面是变量、函数名称

using namespace可以告诉编译器以下都用xx名称空间
比如:

using namespace std;
cout<<"a";

如果没有告诉编译器所使用的空间名称 则要写成:

std::cout<<"a";

同样 可以自定义某一段代码属于哪个空间:

namespace xx
{
...
}

输入输出

在C++中 用iostream作为输入输出流的库

#include <iostream>

用cin和cout关键字进行输入和输出
如:

using namespace std;
int a=0;
cin>>a; //输入到acout<<a;  //输出a

类比scanf和printf
同样 还有一个关键字endl表示换行
cout和cin的传参是不固定的
由编译器自行裁定

字符串类型

在C语言中 常用char *表示字符串
但是在C++中 可以直接用string类型
比如:

char * s="456";
string str="123";

由于cout的特性 这两种字符串都可以直接打印
但如果使用C语言中printf的打印方式时 采用%s方式打印字符串 则不能传入string类型

class类

C++的核心就是class
同Python等支持面向对象的语言一样
可以理解成一个支持函数、继承、自动初始化、销毁的结构体
在class类中 有private私有、public公有变量
前者只能内部访问 后者可以外部调用使用
如:

class A
{
public:
int a;
private:
int b;
}

a可以用A.a的方式方位 b则外部无法访问

构造函数和析构函数(解析函数)

构造函数可以理解成对类的初始化 反之析构函数则是退出时进行销毁前的函数
两者需要与类的名称相同 析构函数则在前面加一个~表示非
如:

class A
{
public:
int a;
A();
~A();
private:
int b;
}A::A()
{
...
}A::~A()
{
...
}

构造函数可以定义传参 析构函数则不行

类的继承

如果有两个类A和B 想让A里面包含B 则可以写作继承的写法
继承后 A类的变量可以直接调用B下面的成员
如:

class B
{
int b;
}
class A: public B
{
int a;
}

在定义A后 可以访问到B的成员b 当然 继承也可以私有

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

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

相关文章

Spring Data Elasticsearch

简介说明 spring-data-elasticsearch是比较好用的一个elasticsearch客户端&#xff0c;本文介绍如何使用它来操作ES。本文使用spring-boot-starter-data-elasticsearch&#xff0c;它内部会引入spring-data-elasticsearch。 Spring Data ElasticSearch有下边这几种方法操作El…

JavaWeb学习(3)(Servlet详细、Servlet的三种实现方式(面试)、Servlet的生命周期、传统web.xml配置Servlet(了解))

目录 一、Servlet详细。 &#xff08;1&#xff09;基本介绍。 &#xff08;2&#xff09;基本作用。 1、接收客户端请求数据。 2、处理请求。 3、完成响应结果。 二、Servlet的三种实现方式。 &#xff08;1&#xff09;实现javax.servlet.Servlet接口。 1、基本介绍。 2、代码…

如何利用内链策略提升网站的整体权重?

内链是谷歌SEO中常常被低估的部分&#xff0c;实际上&#xff0c;合理的内链策略不仅能帮助提升页面间的关联性&#xff0c;还可以增强网站的整体权重。通过正确的内链布局&#xff0c;用户可以更流畅地浏览你的网站&#xff0c;谷歌爬虫也能更快地抓取到更多页面&#xff0c;有…

jeecg-uniapp 跨域问题解决方法记录

今天折腾这个很恶心的问题,工作需要经验才行,根本没有什么技术难点,都是经验而已 问题在此 发现没有替换掉前缀 :8085/#/pages/login/login:1 Access to XMLHttpRequest at http://192.168.152.32:8194/h5api/api/user/login from origin http://localhost:8085 has been bloc…

解决Jupyter Notebook无法转化为Pdf的问题(基于Typora非常实用)

笔者在完成各项作业和做笔记时&#xff0c;经常用到jupyter notebook&#xff1b;其因为可以同时运行python并提供格式化的数字公式的输入方式&#xff0c;得到了广大用户的喜爱。 当我们想要将.ipynb文件导出为pdf时&#xff0c;有两种常用方法。 1.Ctrlp 2.通过File ->…

69 mysql 中 is null 的实现

前言 Mysql 中我们偶尔会用到 字段为 NULL 的情况 这时候 我们只能使用查询 “select * from tz_test_02 where field1 is null;” 来进行 field1 字段为 null 的行的查询 然后如果是使用 “select * from tz_test_02 where field1 null;” 你会发现查询 不出数据 但是如…

Java进阶(注解,设计模式,对象克隆)

Java进阶(注解&#xff0c;设计模式&#xff0c;对象克隆) 一. 注解 1.1 什么是注解 java中注解(Annotation)&#xff0c;又称java标注&#xff0c;是一种特殊的注释 可以添加在包&#xff0c;类&#xff0c;成员变量&#xff0c;方法&#xff0c;参数等内容上 注解会随同…

数据结构考研考点(持续更新)

一、绪论 1、数据元素是数据的基本单位&#xff0c;一个数据元素可以由若干数据项组成&#xff0c;数据项是构成数据元素的不可分割的最小单位。 2、数据结构是数据元素与数据元素之间的关系。 3、数据结构三要素&#xff1a;逻辑结构&#xff1a;独立于计算机&#xff08;线…

C# Dapper在项目中的使用(mvvm)

Dapper 简介 Dapper 是一个轻量级的对象关系映射&#xff08;Object - Relational Mapping&#xff0c;ORM&#xff09;工具&#xff0c;它在.NET 应用程序中用于简化数据库访问操作。它提供了高性能、简单易用的方式来执行 SQL 查询和命令&#xff0c;并且与ADO.NET紧密集成。…

如何抽象策略模式

策略模式是什么 策略设计模式&#xff08;Strategy Pattern&#xff09;是一种面向对象设计模式&#xff0c;它定义了一系列算法&#xff0c;并将每个算法封装起来&#xff0c;使它们可以相互替换。这种模式使得算法可以独立于使用它们的客户端而变化。 策略设计模式包含三个主…

算法-字符串-5.最长回文子串

一、题目&#xff1a; 二、思路解析 1.思路&#xff1a; 最长子串——动态数组 2.常用方法&#xff1a; a.字符串的截断 ress.substring(start,end1); 3.核心逻辑&#xff1a; 1.特殊情况&#xff1a;字符串为空或字符串的长度为0 if(snull||s.length())return ""…

【3D AIGC】Img-to-3D、Text-to-3D、稀疏重建(2024年文章汇总)

文章目录 1. Wonderworld&#xff1a;拓展图片边界&#xff0c;生成3D场景2. 3DTopia-XL&#xff1a;扩散模型辅助生成3. 3DGS-Enhancer: 通过视图一致2D Diffusion&#xff0c;提升无界3D Gaussian Splatting (NlPs2024 Spotlight)4. L3DG&#xff1a;Latent 3D Gaussian Diff…

基于图神经网络的个性化医疗决策算法研究:结合GNN与MSF-CNN,实现95.21%诊断准确率的个性化医疗方案

基于图神经网络的个性化医疗决策算法研究&#xff1a;结合GNN与MSF-CNN&#xff0c;实现95.21%诊断准确率的个性化医疗方案 论文大纲理解要点1. 确认目标2. 问题分解基础问题层技术问题层 3. 实现步骤4. 效果展示5. 金手指分析应用案例&#xff1a; 全流程分析多题一解分析一题…

C语言(一维数组练习)

键盘录入一组数列&#xff0c;利用冒泡排序将数据由大到小排序 #include <stdio.h>int main(int argc,char *argv[]) {int i,j,tmep;int arr[10];printf("请输入10个测试整数&#xff1a;\n");int lensizeof(arr)/sizeof(arr[0]);for(i0;i<len;i){scanf(&q…

webpack 题目

文章目录 webpack 中 chunkHash 和 contentHash 的区别loader和plugin的区别&#xff1f;webpack 处理 image 是用哪个 loader&#xff0c;限制 image 大小的是...&#xff1b;webpack 如何优化打包速度 webpack 中 chunkHash 和 contentHash 的区别 主要从四方面来讲一下区别&…

银行项目网上支付接口调用测试实例

&#x1f345; 点击文末小卡片&#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 公司最近有一个网站商城项目要开始开发了&#xff0c;这几天老板和几个同事一起开着需求会议&#xff0c;讨论了接下来的业务规划和需求策略&#xff0c;等技术需求…

软体机器人动态手内笔旋转研究

人工智能咨询培训老师叶梓 转载标明出处 软体机器人因其在安全互动方面的优势而备受关注&#xff0c;但在高速动态任务中却面临挑战。最近&#xff0c;卡内基梅隆大学机器人研究所的研究团队提出了一种名为SWIFT的系统&#xff0c;旨在通过学习和试错来实现软体机器人手的动态…

Spark实训

实训目的: 介绍本实训的基本内容,描述知识目标、,以及本实训的预期效果等。 1、知识目标 (1)了解spark概念、基础知识、spark处理的全周期,了解spark技术是新时代对人才的新要求。 (2)掌握Linux、hadoop、spark、hive集群环境的搭建、HDFS分布文件系统的基础知识与应用…

二叉树的深搜(不定期更新。。。。。)

二叉树的深搜 验证二叉搜索树 给你一个二叉树的根节点 root &#xff0c;判断其是否是一个有效的二叉搜索树。 有效 二叉搜索树定义如下&#xff1a; 节点的左 子树 只包含 小于 当前节点的数。 节点的右子树只包含 大于 当前节点的数。 所有左子树和右子树自身必须也是二叉…

# 深入浅出 快速认识JAVA常用数据结构【栈, 队列, 链表, 数组】

快速认识JAVA常用数据结构【栈, 队列, 链表】 前言 什么是数据结构 一种用来存储和组织数据的方法&#xff0c;描述了数据之间的关系和操作方式。通过合理选择和使用数据结构&#xff0c;可以大幅提高程序的运行效率、存储效率以及代码可维护性。 数据结构的重要性 数据结构…