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

news2025/1/10 10:47:19

【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 0
    emit 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);
#else
    int 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_OBJECT

public:
    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; //输入到a

cout<<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.coloradmin.cn/o/2257180.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Python、R循环神经网络RNN、指数平滑ETS、ARIMA模型预测网络流量、ATM机取款、旅游需求时间序列数据...

全文链接&#xff1a;https://tecdat.cn/?p38496 分析师&#xff1a;Pengyuan Wen 在当今经济研究与商业决策领域&#xff0c;精准的时间序列预测具有极为关键的意义。社会消费品零售总额作为反映人民消费水平以及国民经济状况的核心指标&#xff0c;其发展趋势的精准把握对中…

甘肃美食之选:食家巷方形饼

甘肃食家巷方形饼&#xff0c;顾名思义&#xff0c;其形状呈规整的方形。这种独特的外形并非偶然&#xff0c;而是源于当地传统的制作工艺。制作方形饼的师傅们&#xff0c;精心挑选优质的面粉&#xff0c;加入适量的水和其他配料&#xff0c;揉成光滑的面团。经过一段时间的发…

linux——挂载nfs网络硬盘

&#xff08;一&#xff09;安装nfs服务 1、查看系统是否已经安装nfs rpm -qa | grep nfs rpm -qa | grep rpcbind 2、安装nfs 服务 yum -y install nfs-utils yum -y install rpcbind nfs 固定端口号 2049 rpc 固定端口号 111 &#xff08;二&#xff09;centos中服务…

网络安全中大数据和人工智能应用实践

传统的网络安全防护手段主要是通过单点的网络安全设备&#xff0c;随着网络攻击的方式和手段不断的变化&#xff0c;大数据和人工智能技术也在最近十年飞速地发展&#xff0c;网络安全防护也逐渐开始拥抱大数据和人工智能。传统的安全设备和防护手段容易形成数据孤岛&#xff0…

共筑数字安全防线,2024开源和软件安全沙龙即将启幕

随着数字化转型进程的加快以及开源代码的广泛应用&#xff0c;开源凭借平等、开放、协作、共享的优秀创作模式&#xff0c;逐渐成为推动数字技术创新、加速传统行业转型升级的重要模式。但随着软件供应链日趋复杂多元&#xff0c;使得其安全风险不断加剧&#xff0c;针对软件供…

4K高清壁纸网站推荐

1. Awesome Wallpapers 官网: https://4kwallpapers.com/ 主题: 创意、摄影、人物、动漫、绘画、视觉 分辨率: 4K Awesome Wallpapers 提供了丰富的高质量图片&#xff0c;分为通用、动漫、人物三大类&#xff0c;可以按屏幕比例和分辨率检索&#xff0c;满足你对壁纸的各种…

Java阶段三06

第3章-第6节 一、知识点 理解MVC三层模型、理解什么是SpringMVC、理解SpringMVC的工作流程、了解springMVC和Struts2的区别、学会使用SpringMVC封装不同请求、接收参数 二、目标 理解MVC三层模型 理解什么是SpringMVC 理解SpringMVC的工作流程 学会使用SpringMVC封装请求…

qt-C++语法笔记之mapToGlobal将组件(控件)中的本地坐标系(局部坐标)映射到全局坐标系

qt-C语法笔记之mapToGlobal将组件&#xff08;控件&#xff09;中的本地坐标系&#xff08;局部坐标&#xff09;映射到全局坐标系 code review! 文章目录 qt-C语法笔记之mapToGlobal将组件&#xff08;控件&#xff09;中的本地坐标系&#xff08;局部坐标&#xff09;映射到…

使用Kimi开发自己的问答应用

概述 Kimi是大家常用的一个人工智能助手&#xff0c;本文使用Kimi开发文档&#xff0c;以node作为后端&#xff0c;开发与一个问答系统 实现效果 Kimi简介 Kimi是由Moonshot AI开发的人工智能助手&#xff0c;擅长中文和英文对话。目标是帮助用户解决问题、提供信息和执行任…

从零开始:Linux 环境下的 C/C++ 编译教程

个人主页&#xff1a;chian-ocean 文章专栏 前言&#xff1a; GCC&#xff08;GNU Compiler Collection&#xff09;是一个功能强大的编译器集合&#xff0c;支持多种语言&#xff0c;包括 C 和 C。其中 gcc 用于 C 语言编译&#xff0c;g 专用于 C 编译。 Linux GCC or G的安…

ElasticSearch如何做性能优化?

大家好&#xff0c;我是锋哥。今天分享关于【ElasticSearch如何做性能优化&#xff1f;】面试题。希望对大家有帮助&#xff1b; ElasticSearch如何做性能优化&#xff1f; 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 在 Elasticsearch 中&#xff0c;性能优化是…

Flask 是什么?

近期开发chatbot 程序&#xff0c;过程中要使用Flask&#xff0c;所以收集资料记录这个套件的信息&#xff1a; Flask 是什么&#xff1f; Flask 是一个轻量级、模块化的 Python Web 框架&#xff0c;用于构建 Web 应用程序和 API。它被设计为简单、灵活且可扩展&#xff0c;…

北京大学《操作系统原理》(陈向群主讲)课堂笔记(一)

北京大学《操作系统原理》&#xff08;陈向群主讲&#xff09;课堂笔记&#xff08;一&#xff09; 一、操作系统概述 1.1、操作系统做了什么&#xff1f; 以c语言helloworld为例子&#xff1a; #include<stdio.h> int main(int argc, char *argv[]) {puts("hello…

计算c++11 lambada表达式的大小

lambada表达式是什么? 详解&#xff1a;lambada表达式详解 我们知道lambada其实是一个匿名函数 &#xff0c; 它属于 可调用对象 类型。在 C 中&#xff0c;lambda 表达式会生成一个隐式定义的类&#xff0c;这个类重载了 operator()&#xff0c;使得该对象可以像函数一样被…

【unity小技巧】分享vscode如何进行unity开发,且如何开启unity断点调试模式,并进行unity断点调试(2024年最新的方法,实测有效)

文章目录 前言一、前置条件1、已安装Visual Studio Code&#xff0c;并且unity首选项>外部工具>外部脚本编辑器选择为Visual Studio Code [版本号]&#xff0c;2、在Visual Studio Code扩展中搜索Unity&#xff0c;并安装3、同时注意这个插件下面的描述&#xff0c;需要根…

亚马逊云科技 re:Invent 2024!Amazon Aurora DSQL 闪亮登场,跨区域提供强一致性,带来全新突破!

在 AWS re:Invent 2024 的主题演讲中&#xff0c;Amazon 正式发布了支持多区域 Active/Active 架构的关系型数据库 Aurora DSQL&#xff0c;目前已开放预览。 我正在拉斯维加斯现场观看 Keynote&#xff0c;刚刚听到这一令人振奋的消息。Aurora DSQL 的亮点在于能够跨区域写入…

计算机视觉在科学研究(数字化)中的实际应用

计算机视觉是一种利用计算机技术来解析和理解图像和视频的方法。.随着计算机技术的不断发展&#xff0c;计算机视觉被广泛应用于科学研究领域&#xff0c;为科学家提供了无限的可能。 一、生命科学领域 在生命科学领域&#xff0c;计算机视觉被广泛用于图像识别、分类和测量等…

Springboot美食分享平台

文末获取源码和万字论文&#xff0c;制作不易&#xff0c;感谢点赞支持。 Springboot美食分享平台 一、 绪论 1.1 研究意义 当今社会作为一个飞速的发展社会&#xff0c;网络已经完全渗入人们的生活&#xff0c; 网络信息已成为传播的第一大媒介&#xff0c; 可以毫不夸张说…

如何在组织中塑造和强化绩效文化?

在组织中塑造和强化绩效文化是一个系统性的工程。 一、明确绩效目标与期望 设定清晰目标 组织应根据自身战略规划&#xff0c;将长期目标分解为具体、可衡量、可实现、相关联、有时限&#xff08;SMART&#xff09;的短期和中期绩效目标。例如&#xff0c;一家连锁餐饮企业的…

WireShark 下载、安装和使用

1、下载 官网下载太慢&#xff0c;本人另外提供下载地址【下载WireShark】 2、安装 全部默认下一步即可&#xff0c;但如下图所示的这一步值得拿出来说一下。这一步是要你安装Npcap&#xff0c;但是你的电脑如果已经安装了WinPcap&#xff0c;那么可以选择不再安装Npcap。Npca…