欢迎大家踊跃参加

whycan 发布的帖子
-
回复: 【羊毛福利】凡在哇酷淘店购买V853开发板者在社区分享开发经验,最高可返还全部购买费用
资料分享:
【资料汇总】V853资料汇总
https://bbs.aw-ol.com/topic/1560/share/1另有买芯片分享设计退芯片的钱活动,详见:
全志V853可以申请样片了,本站网友开源原理图与PCB送两片V853芯片(不能与其他网友作品雷同)
https://bbs.aw-ol.com/topic/1677/share/1 -
【羊毛福利】凡在哇酷淘店购买V853开发板者在社区分享开发经验,最高可返还全部购买费用
即日(2022年7月7日)起凡在哇酷淘店购买V853开发板并分享开发经验的伙伴,可以获得晕哥给出的现金红包奖励。
奖励标准:
1.分享开箱评测文章或视频发到全志在线论坛及B站——红包奖励50-200元
评判维度:
(1)图片、视频的清晰度;
(2)文字说明清晰、准确;
(3)其他丰富有趣内容加分。
案例分享:
(1)奖励200元案例参考:
《带大家来一次全志V853开发板沉浸式开箱!》
https://bbs.aw-ol.com/topic/1695/share/1
https://www.bilibili.com/video/BV1xa411x72p
(2)奖励100元案例参考:
《【V853开发板试用】nihui大佬的也收到板子了》
https://bbs.aw-ol.com/topic/1710/share/1
https://www.bilibili.com/video/BV1UB4y1W7Vy2.分享开发经验到全志在线论坛或个人博客——红包奖励50-300元
内容包括:
(1)编译、烧写、开发踩坑及填坑经验;
(2)性能评测;
(3)驱动、外设移植经验;
(4)demo开发分享
案例分享:
(1)奖励300元案例参考:
《V853开发板填坑记》
https://bbs.aw-ol.com/topic/1658/share/2
(2)奖励200元案例参考:
《V853 NPU 踩坑记录》
https://bbs.aw-ol.com/topic/1641/share/13.完成大demo项目并分享——红包奖励300元-1999元
案例参考:
(1)奖励1999元案例参考:
《火影忍者结印手势识别器——人人都是copy ninja》
https://bbs.aw-ol.com/topic/1712/share/1(2)奖励800元案例参考:
《AI生成山水画,每一幅都是世间独一无二》
https://bbs.aw-ol.com/topic/1715/share/1(3)奖励300元案例参考:
《我做个RTSP推流demo吧》
https://bbs.aw-ol.com/topic/1705/share/1
(这几个demo还没完全最终输出成果,需要完成并输出开发过程、demo估固件、相关源码或patch后才能获取奖励)活动补充说明:
- 奖励申请请添加微信:whycan_cn,晕哥将以现金红包的形式直接发给您
- 最高可退回金额为开发板的购买费用
- 2022年7月7日前折扣购买开发板的顾客及免费赠送的朋友不参与该活动,但是如果您分享的内容特别好晕哥仍会给您发红包
- 可以借鉴前人的开发经验推陈出新,但是站在巨人的肩膀上只是为了站得更高,也要有自己的创新
- 不允许抄袭,否则将取消资格,圈子很小,请大家做过一个有素质的开发者
-
回复: melis pack失败是什么情况?
sudo apt-get install build-essential subversion git-core repo libncurses5-dev zlib1g-dev \ gawk flex quilt libssl-dev xsltproc libxml-parser-perl \ mercurial bzr ecj cvs unzip lib32z1 lib32z1-dev lib32stdc++6 libstdc++6 \ libncurses-dev zlib1g-dev gawk openssl libssl-dev linux-tools-common gperf -y
-
回复: 哪吒开发板D1编译报错Cannot find lib ld-linux-riscv64-lp64.so.1
@casojie
通用, D1(D1-H) 与 D1s(F133) 区别是内存规格和引脚不同, 其他一样的.SDK也可以百度云下载:
tina v2.0 下载:
链接: https://pan.baidu.com/s/1rTyKuWIwMUlBY4xLJofWEg?pwd=awol
提取码:awol文件:
tina_d1_open_v2.tar.bz2.aa
tina_d1_open_v2.tar.bz2.ab
tina_d1_open_v2.tar.bz2.ac①解压: cat tina_d1_open_v2.tar.bz2.a | tar -xjv*
②从本地repo仓库同步SDK repo sync -l
③ source build/envsetup.sh
④ lunch
⑤ make
⑥ pack -
回复: 当使用虚拟机的时候,adb能否只连接到windows
@sora1874
和vmware版本有关系, 一般不把vmware推到前台,新插入的usb不会挂到vmware 。 -
回复: f1c200s怎么从SD启动,uboot、kernel、
@shz18877605430
那你用前面我发的链接吧,spi nand/spi nor/tfcard 全部都支持。 -
回复: 芒果d1h用sd卡烧录后创建文件夹一直Read-only file system
这个问题是因为 tina 1.x 的时候 e2fsprog 不能成功编译,导致没有 mkfs.ext4,所以不能加载 overlayfs 引起.
参考这个帖子: 在D1的tina上整上overlayfs
后来 tina 2.0 修复了这个问题.
按楼上 @YuzukiTsuru 大佬的意思,把rootfs改成 ext4 一样可以的.
-
回复: D1s 目前的一些玩法:跑Ubuntu rootfs,显示图片,播放音频 (转载)
@soso90
这个问题是因为 tina 1.x 的时候 e2fsprog 不能成功编译,导致没有 mkfs.ext4,所以不能加载 overlayfs 引起.参考这个帖子: 在D1的tina上整上overlayfs
后来 tina 2.0 修复了这个问题.
-
回复: t133替换开机logo打包提示boot-resource分区内存不足
以下是网上复制来的:
DragonFace又名为全志固件修改工具,能够帮助用户对手机固件信息进行修改,能够设置固件版本号、产品型号、公司名、版本信息,还可以对预装APP进行修改,让你的手机更好用,有需要的用户欢迎下载使用!
软件介绍
固件修改工具(DragonFace)是一个高效的固件修改——功能强大、所见即所得、操作便易的工具。只要是用于在某个发布固件中修改OEM 厂家客户的需求,如固件版本信息、产品型号、公司名称等等。
工具还可以修改开机logo、开机动画等等。除了这些可编辑的信息之外,还可以从现有的设备上拷贝预装 APK、桌面预设等功能。DragonFace 可根据用户的需求,修改固件包的参数,让其适应自己的机器。操作 简洁方便。
Dragonface可以将全志方案A10-A31的平板电脑的线刷ROM——img进行修改,可以修改固件版本、厂商信息、开机第一、第二、第三屏、修改开、关机背景音乐、修改系统参数、充电图标、桌面布局、内置APK、按键修改、触屏等,还有更多强大的功能在等待着您去挖掘!
-
回复: 编译decodertest和encodertest报错
@wanglang
可能不是每一个package都验证过, 楼主你试一试找一下文件:
find . -name cdx_log.h然后复制到对应目录,手动修复编译错误.
-
回复: 司徒gpsp游戏机模拟器源码移植到全志V3s/R11等soc (转)
gpsp 源代碼:https://github.com/steward-fu/miyoo/releases/download/v1.2/gpsp.7z
這個 gpsp 源代碼是當初移植給 Miyoo 使用的, 你可以從這份代碼做修改~一般移植模擬器, 思路大致上如下步驟(不包含驅動程式部份):
-
確定可以編譯 (交叉編譯器)
-
確定可以顯示 (SDL)
-
調整顯示比例
-
調整按鍵輸入
-
確定可以編譯 (交叉編譯器)
gpsp 源代碼解壓縮後, 可以看到 bittboy 資料夾, 複製一份成 v3s, 修改 Makefile, 3 個部份需要修改:
(1). CC 指向你的交叉編譯器
CC = arm-linux-gcc
(2). 告知 SDL.h 的位置, 一般使用 sdl-config 取得CFLAGS +=
/opt/miyoo/arm-miyoo-linux-uclibcgnueabi/sysroot/usr/bin/sdl-config --cflags
當然也可以使用固定路徑, 如下:CFLAGS += -I/opt/miyoo/arm-miyoo-linux-uclibcgnueabi/sysroot/usr/include/SDL
(3). 告知 SDL 元件庫, 一般使用 sdl-config 取得LIBS +=
/opt/miyoo/arm-miyoo-linux-uclibcgnueabi/sysroot/usr/bin/sdl-config --libs
當然也可以使用固定名稱, 如下:LIBS += -lSDL
(4). 拿到機器上跑, 確定不會有crash問題- 確定可以顯示 (SDL)
(1). SDL_Init() 初始化顯示驅動, 一般需要判斷回傳值是否初始化成功, 因為有時候, 顯示驅動不支援,
(2). 設定顯示解析度 SDL_SetVideoMode(), 由於這些模擬器幾乎都是從早期 320x240 顯示開始製作,
所以預設是跑 320x240, 假如你的顯示驅動只有支援 640x480, 你可以把 video_scale 設定成 2
void init_video() { SDL_Init(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK | SDL_INIT_NOPARACHUTE); rl_screen = SDL_SetVideoMode(320 * video_scale, 240 * video_scale, 16, SDL_HWSURFACE); screen = SDL_CreateRGBSurface(SDL_SWSURFACE, 240 * video_scale, 160 * video_scale, 16, 0, 0, 0, 0); SDL_ShowCursor(0); }
(3). 拿到機器上跑, 確定可以顯示東西
- 調整顯示比例
(1). flip_screen() 用來顯示模擬器的畫面, 由於經過太多人修改, 很多重複變數使用的問題, 不過這裡是你做顯示的動作, 畫面比例調整可以在這裡實做
void flip_screen() { ... switch(video_scale) { case 2: integer_scale_horizontal(2); break; case 3: integer_scale_horizontal(3); break; default: case 4: integer_scale_horizontal(4); break; } for(y = 159, y2 = (160 * video_scale) - 1; y >= 0; y--) { for(i = 0; i < video_scale; i++) { memcpy(screen_ptr + (y2 * pitch), screen_ptr + (y * pitch), 480 * video_scale); y2--; } } ... }
(2). 拿到機器上跑, 確定顯示正確
- 調整按鍵輸入
(1). 你需要先知道 Input 驅動程式對應的按鍵值, 接著設定按鍵
#if defined(PC_BUILD) u32 key_map(SDLKey key_sym) { switch(key_sym) { case SDLK_LSHIFT: case SDLK_BACKSPACE: return BUTTON_R; case SDLK_SPACE: case SDLK_TAB: return BUTTON_L; case SDLK_DOWN: return BUTTON_DOWN; case SDLK_UP: return BUTTON_UP; case SDLK_LEFT: return BUTTON_LEFT; case SDLK_RIGHT: return BUTTON_RIGHT; case SDLK_RETURN: return BUTTON_START; case SDLK_ESCAPE: return BUTTON_SELECT; case SDLK_LCTRL: return BUTTON_B; case SDLK_LALT: return BUTTON_A; default: return BUTTON_NONE; } } #endif
(2). 拿到機器上跑, 確定按鍵正確
-
-
全志V853可以申请样片了,本站网友开源原理图与PCB送两片V853芯片(不能与其他网友作品雷同)
全志V853可以申请样片了,本站网友开源原理图与PCB送两片V853芯片(不能与其他网友作品雷同)
https://item.taobao.com/item.htm?id=675340119398
① 拍下付款
② 开源原理图与PCB,发布简要的焊接调试记录
③ 加微信whycan_cn截图申请退款
另有买V853开发板分享开发经验退全款活动:
凡在哇酷淘店购买V853开发板者,分享开发经验,可获得现金现金奖励
https://bbs.aw-ol.com/topic/1724/share/1 -
回复: T113S使用外置RTC问题
@y97788
对一下手册, 看下 PG14/PG15 对应的复用寄存器,用devmem把这个寄存器读出来,看下这两条腿的当前复用状态是不是I2C2,如果不是,用devmem 写回去,然后再用i2cdetect扫描试一试。 -
回复: 【极简操作】使用builroot 2021一键编译生成D1 nezha 系统镜像!
@mxlol233
再执行一次 make menuconfig就可以了,原因是有些 package 在新版本过时了,那个只是一个 warning 而已,不是错误。 -
回复: R11 Linux3.4 挂载 4T 移动硬盘出错,请问应该怎么解决呢?
root@sun8i:/# mount -t ntfs /dev/sda2 /mnt/udisk [ 96.146467] NTFS-fs error (device sda2): parse_ntfs_boot_sector(): Volume size (3TiB) is too large for this architecture. Maximum supported is 2TiB. Sorry. mount: mounting /dev/sda2 on /mnt/udisk failed: Invalid argument
看起来有起色了。
-
回复: R11 Linux3.4 挂载 4T 移动硬盘出错,请问应该怎么解决呢?
https://forums.gentoo.org/viewtopic-t-1076996-start-0.html
$ grep EFI_P /usr/src/linux/.config CONFIG_EFI_PARTITION=y
That's a must have for your 4Tb drive.
试一试这个?
-
回复: R11 Linux3.4 挂载 4T 移动硬盘出错,请问应该怎么解决呢?
# fdisk -l Disk /dev/mmcblk0: 7.39 GiB, 7933526016 bytes, 15495168 sectors Units: sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disklabel type: dos Disk identifier: 0x00000000 Device Boot Start End Sectors Size Id Type /dev/mmcblk0p1 141696 15493118 15351423 7.3G b W95 FAT32 /dev/mmcblk0p2 * 41984 43007 1024 512K 6 FAT16 /dev/mmcblk0p3 1 141696 141696 69.2M 85 Linux extended /dev/mmcblk0p5 43008 43263 256 128K 83 Linux /dev/mmcblk0p6 43264 51455 8192 4M 83 Linux /dev/mmcblk0p7 51456 121455 70000 34.2M 83 Linux /dev/mmcblk0p8 121456 141695 20240 9.9M 83 Linux Partition table entries are not in disk order. Disk /dev/sda: 3.64 TiB, 4000787030016 bytes, 7814037168 sectors Disk model: 004-2CV104 Units: sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 4096 bytes I/O size (minimum/optimal): 4096 bytes / 4096 bytes Disklabel type: gpt Disk identifier: DDC2F977-1D93-4541-B48F-CB71B9A58E0B Device Start End Sectors Size Type /dev/sda1 34 32767 32734 16M Microsoft reserved /dev/sda2 32768 7814033407 7814000640 3.6T Microsoft basic data Partition 1 does not start on physical sector boundary. #
fdisk 列出了sda1,却没有列出 sda2,这是什么问题呢?
-
回复: R11 Linux3.4 挂载 4T 移动硬盘出错,请问应该怎么解决呢?
# # # # [ 425.938667] ehci_irq: highspeed device connect [ 426.220057] usb 1-1: new high-speed USB device number 3 using sunxi-ehci [ 426.378206] scsi1 : usb-storage 1-1:1.0 [ 427.406884] scsi 1:0:0:0: Direct-Access ST4000DM 004-2CV104 0 PQ: 0 ANSI: 6 [ 427.428022] sd 1:0:0:0: [sda] Very big device. Trying to use READ CAPACITY(16). [ 427.437739] sd 1:0:0:0: [sda] 7814037168 512-byte logical blocks: (4.00 TB/3.63 TiB) [ 427.446461] sd 1:0:0:0: [sda] 4096-byte physical blocks [ 427.458820] sd 1:0:0:0: [sda] Write Protect is off [ 427.464283] sd 1:0:0:0: [sda] Mode Sense: 43 00 00 00 [ 427.471460] sd 1:0:0:0: [sda] Write cache: enabled, read cache: enabled, doesn't support DPO or FUA [ 427.486642] sd 1:0:0:0: [sda] Very big device. Trying to use READ CAPACITY(16). [ 427.519479] sda: sda1 [ 427.530715] sd 1:0:0:0: [sda] Very big device. Trying to use READ CAPACITY(16). [ 427.553590] sd 1:0:0:0: [sda] Attached SCSI disk
# # mount /dev/sda1 /tmp/aaa [ 461.620756] FAT-fs (sda1): utf8 is not a recommended IO charset for FAT filesystems, filesystem will be case sensitive! mount: mounting /dev/sda1 on /tmp/aaa failed: Invalid argument # # mount /dev/sda /tmp/aaa [ 475.037018] FAT-fs (sda): utf8 is not a recommended IO charset for FAT filesystems, filesystem will be case sensitive! mount: mounting /dev/sda on /tmp/aaa failed: Invalid argument # # #
确实挂载不上,这是什么原因呢?
-
回复: R11的I2S没有MCLK引脚, 如果要驱动声卡,应该怎么处理呢?可以用一个24.576MHz有源晶振代替吗?
@mengxp
不能这么说,刚好S3/R11 没有引出这个腿而已,
F1C有几组MCLK复用,但是只有一个MCLK引脚。 -
回复: R11的I2S没有MCLK引脚, 如果要驱动声卡,应该怎么处理呢?可以用一个24.576MHz有源晶振代替吗?
@mengxp
我也试过PCM5102了,确实如此,如果使用外部MCLK,这个MCLK确实是需要同步时钟,不能用有源晶振这种异步时钟。 -
回复: 触摸屏触摸不了
@shz18877605430
不是不能用,是这个数据不是真实坐标数据,只是一个adc值而已,而app需要的不是这种数据。app需要的是用tslib进行各种滤波去抖和坐标计算后的数据。
-
回复: 芒果的tiny200s板子 gt911电容屏不能中断,一筹莫展中
触摸完全OK:
# evtest /dev/input/event0 Input driver version is 1.0.1 Input device ID: bus 0x18 vendor 0x416 product 0x38f version 0x1060 Input device name: "Goodix Capacitive TouchScreen" Supported events: Event type 0 (EV_SYN) Event type 1 (EV_KEY) Event code 125 (KEY_LEFTMETA) Event code 330 (BTN_TOUCH) Event type 3 (EV_ABS) Event code 0 (ABS_X) Value 0 Min 0 Max 799 Event code 1 (ABS_Y) Value 0 Min 0 Max 479 Event code 47 (ABS_MT_SLOT) Value 0 Min 0 Max 4 Event code 48 (ABS_MT_TOUCH_MAJOR) Value 0 Min 0 Max 255 Event code 50 (ABS_MT_WIDTH_MAJOR) Value 0 Min 0 Max 255 Event code 53 (ABS_MT_POSITION_X) Value 0 Min 0 Max 799 Event code 54 (ABS_MT_POSITION_Y) Value 0 Min 0 Max 479 Event code 57 (ABS_MT_TRACKING_ID) Value 0 Min 0 Max 65535 Properties: Property type 1 (INPUT_PROP_DIRECT) Testing ... (interrupt to exit) Event: time 11.891769, type 3 (EV_ABS), code 57 (ABS_MT_TRACKING_ID), value 0 Event: time 11.891769, type 3 (EV_ABS), code 53 (ABS_MT_POSITION_X), value 435 Event: time 11.891769, type 3 (EV_ABS), code 54 (ABS_MT_POSITION_Y), value 260 Event: time 11.891769, type 3 (EV_ABS), code 48 (ABS_MT_TOUCH_MAJOR), value 29 Event: time 11.891769, type 3 (EV_ABS), code 50 (ABS_MT_WIDTH_MAJOR), value 29 Event: time 11.891769, type 1 (EV_KEY), code 330 (BTN_TOUCH), value 1 Event: time 11.891769, type 3 (EV_ABS), code 0 (ABS_X), value 435 Event: time 11.891769, type 3 (EV_ABS), code 1 (ABS_Y), value 260 Event: time 11.891769, -------------- SYN_REPORT ------------ Event: time 11.943724, type 3 (EV_ABS), code 57 (ABS_MT_TRACKING_ID), value -1 Event: time 11.943724, type 1 (EV_KEY), code 330 (BTN_TOUCH), value 0 Event: time 11.943724, -------------- SYN_REPORT ------------ Event: time 12.207591, type 3 (EV_ABS), code 57 (ABS_MT_TRACKING_ID), value 1 Event: time 12.207591, type 3 (EV_ABS), code 53 (ABS_MT_POSITION_X), value 432 Event: time 12.207591, type 3 (EV_ABS), code 54 (ABS_MT_POSITION_Y), value 238 Event: time 12.207591, type 3 (EV_ABS), code 48 (ABS_MT_TOUCH_MAJOR), value 34 Event: time 12.207591, type 3 (EV_ABS), code 50 (ABS_MT_WIDTH_MAJOR), value 34 Event: time 12.207591, type 1 (EV_KEY), code 330 (BTN_TOUCH), value 1 Event: time 12.207591, type 3 (EV_ABS), code 0 (ABS_X), value 432 Event: time 12.207591, type 3 (EV_ABS), code 1 (ABS_Y), value 238 Event: time 12.207591, -------------- SYN_REPORT ------------ Event: time 12.291078, type 3 (EV_ABS), code 57 (ABS_MT_TRACKING_ID), value -1 Event: time 12.291078, type 1 (EV_KEY), code 330 (BTN_TOUCH), value 0 Event: time 12.291078, -------------- SYN_REPORT ------------ [ 31.842433] vcc3v0: disabling [ 31.845438] vcc5v0: disabling Event: time 94.686680, type 3 (EV_ABS), code 57 (ABS_MT_TRACKING_ID), value 2 Event: time 94.686680, type 3 (EV_ABS), code 53 (ABS_MT_POSITION_X), value 295 Event: time 94.686680, type 3 (EV_ABS), code 54 (ABS_MT_POSITION_Y), value 194 Event: time 94.686680, type 3 (EV_ABS), code 48 (ABS_MT_TOUCH_MAJOR), value 21 Event: time 94.686680, type 3 (EV_ABS), code 50 (ABS_MT_WIDTH_MAJOR), value 21 Event: time 94.686680, type 1 (EV_KEY), code 330 (BTN_TOUCH), value 1 Event: time 94.686680, type 3 (EV_ABS), code 0 (ABS_X), value 295 Event: time 94.686680, type 3 (EV_ABS), code 1 (ABS_Y), value 194 Event: time 94.686680, -------------- SYN_REPORT ------------ Event: time 94.717502, type 3 (EV_ABS), code 57 (ABS_MT_TRACKING_ID), value -1 Event: time 94.717502, type 1 (EV_KEY), code 330 (BTN_TOUCH), value 0 Event: time 94.717502, -------------- SYN_REPORT ------------ Event: time 94.833846, type 3 (EV_ABS), code 57 (ABS_MT_TRACKING_ID), value 3 Event: time 94.833846, type 3 (EV_ABS), code 53 (ABS_MT_POSITION_X), value 293 Event: time 94.833846, type 3 (EV_ABS), code 54 (ABS_MT_POSITION_Y), value 209 Event: time 94.833846, type 3 (EV_ABS), code 48 (ABS_MT_TOUCH_MAJOR), value 37 Event: time 94.833846, type 3 (EV_ABS), code 50 (ABS_MT_WIDTH_MAJOR), value 37 Event: time 94.833846, type 1 (EV_KEY), code 330 (BTN_TOUCH), value 1 Event: time 94.833846, type 3 (EV_ABS), code 0 (ABS_X), value 293 Event: time 94.833846, type 3 (EV_ABS), code 1 (ABS_Y), value 209 Event: time 94.833846, -------------- SYN_REPORT ------------ [ 94.919685] random: crng init done Event: time 94.920955, type 3 (EV_ABS), code 57 (ABS_MT_TRACKING_ID), value -1 Event: time 94.920955, type 1 (EV_KEY), code 330 (BTN_TOUCH), value 0 Event: time 94.920955, -------------- SYN_REPORT ------------ Event: time 95.044346, type 3 (EV_ABS), code 57 (ABS_MT_TRACKING_ID), value 4 Event: time 95.044346, type 3 (EV_ABS), code 53 (ABS_MT_POSITION_X), value 295 Event: time 95.044346, type 3 (EV_ABS), code 54 (ABS_MT_POSITION_Y), value 211 Event: time 95.044346, type 3 (EV_ABS), code 48 (ABS_MT_TOUCH_MAJOR), value 28 Event: time 95.044346, type 3 (EV_ABS), code 50 (ABS_MT_WIDTH_MAJOR), value 28 Event: time 95.044346, type 1 (EV_KEY), code 330 (BTN_TOUCH), value 1 Event: time 95.044346, type 3 (EV_ABS), code 0 (ABS_X), value 295 Event: time 95.044346, type 3 (EV_ABS), code 1 (ABS_Y), value 211 Event: time 95.044346, -------------- SYN_REPORT ------------ Event: time 95.085689, type 3 (EV_ABS), code 57 (ABS_MT_TRACKING_ID), value -1 Event: time 95.085689, type 1 (EV_KEY), code 330 (BTN_TOUCH), value 0 Event: time 95.085689, -------------- SYN_REPORT ------------ Event: time 95.233558, type 3 (EV_ABS), code 57 (ABS_MT_TRACKING_ID), value 5 Event: time 95.233558, type 3 (EV_ABS), code 53 (ABS_MT_POSITION_X), value 296 Event: time 95.233558, type 3 (EV_ABS), code 54 (ABS_MT_POSITION_Y), value 230 Event: time 95.233558, type 3 (EV_ABS), code 48 (ABS_MT_TOUCH_MAJOR), value 14 Event: time 95.233558, type 3 (EV_ABS), code 50 (ABS_MT_WIDTH_MAJOR), value 14 Event: time 95.233558, type 1 (EV_KEY), code 330 (BTN_TOUCH), value 1 Event: time 95.233558, type 3 (EV_ABS), code 0 (ABS_X), value 296 Event: time 95.233558, type 3 (EV_ABS), code 1 (ABS_Y), value 230 Event: time 95.233558, -------------- SYN_REPORT ------------ Event: time 95.264502, type 3 (EV_ABS), code 57 (ABS_MT_TRACKING_ID), value -1 Event: time 95.264502, type 1 (EV_KEY), code 330 (BTN_TOUCH), value 0 Event: time 95.264502, -------------- SYN_REPORT ------------ Event: time 97.795859, type 3 (EV_ABS), code 57 (ABS_MT_TRACKING_ID), value 6 Event: time 97.795859, type 3 (EV_ABS), code 53 (ABS_MT_POSITION_X), value 754 Event: time 97.795859, type 3 (EV_ABS), code 54 (ABS_MT_POSITION_Y), value 9 Event: time 97.795859, type 3 (EV_ABS), code 48 (ABS_MT_TOUCH_MAJOR), value 31 Event: time 97.795859, type 3 (EV_ABS), code 50 (ABS_MT_WIDTH_MAJOR), value 31 Event: time 97.795859, type 1 (EV_KEY), code 330 (BTN_TOUCH), value 1 Event: time 97.795859, type 3 (EV_ABS), code 0 (ABS_X), value 754 Event: time 97.795859, type 3 (EV_ABS), code 1 (ABS_Y), value 9 Event: time 97.795859, -------------- SYN_REPORT ------------ Event: time 97.879491, type 3 (EV_ABS), code 57 (ABS_MT_TRACKING_ID), value -1 Event: time 97.879491, type 1 (EV_KEY), code 330 (BTN_TOUCH), value 0 Event: time 97.879491, -------------- SYN_REPORT ------------ Event: time 98.290574, type 3 (EV_ABS), code 57 (ABS_MT_TRACKING_ID), value 7 Event: time 98.290574, type 3 (EV_ABS), code 53 (ABS_MT_POSITION_X), value 744 Event: time 98.290574, type 3 (EV_ABS), code 54 (ABS_MT_POSITION_Y), value 6 Event: time 98.290574, type 3 (EV_ABS), code 48 (ABS_MT_TOUCH_MAJOR), value 28 Event: time 98.290574, type 3 (EV_ABS), code 50 (ABS_MT_WIDTH_MAJOR), value 28 Event: time 98.290574, type 1 (EV_KEY), code 330 (BTN_TOUCH), value 1 Event: time 98.290574, type 3 (EV_ABS), code 0 (ABS_X), value 744 Event: time 98.290574, type 3 (EV_ABS), code 1 (ABS_Y), value 6 Event: time 98.290574, -------------- SYN_REPORT ------------ Event: time 98.384787, type 3 (EV_ABS), code 57 (ABS_MT_TRACKING_ID), value -1 Event: time 98.384787, type 1 (EV_KEY), code 330 (BTN_TOUCH), value 0 Event: time 98.384787, -------------- SYN_REPORT ------------ Event: time 99.332530, type 3 (EV_ABS), code 57 (ABS_MT_TRACKING_ID), value 8 Event: time 99.332530, type 3 (EV_ABS), code 53 (ABS_MT_POSITION_X), value 750 Event: time 99.332530, type 3 (EV_ABS), code 54 (ABS_MT_POSITION_Y), value 451 Event: time 99.332530, type 3 (EV_ABS), code 48 (ABS_MT_TOUCH_MAJOR), value 43 Event: time 99.332530, type 3 (EV_ABS), code 50 (ABS_MT_WIDTH_MAJOR), value 43 Event: time 99.332530, type 1 (EV_KEY), code 330 (BTN_TOUCH), value 1 Event: time 99.332530, type 3 (EV_ABS), code 0 (ABS_X), value 750 Event: time 99.332530, type 3 (EV_ABS), code 1 (ABS_Y), value 451 Event: time 99.332530, -------------- SYN_REPORT ------------ Event: time 99.405632, type 3 (EV_ABS), code 57 (ABS_MT_TRACKING_ID), value -1 Event: time 99.405632, type 1 (EV_KEY), code 330 (BTN_TOUCH), value 0 Event: time 99.405632, -------------- SYN_REPORT ------------ Event: time 100.258616, type 3 (EV_ABS), code 57 (ABS_MT_TRACKING_ID), value 9 Event: time 100.258616, type 3 (EV_ABS), code 53 (ABS_MT_POSITION_X), value 6 Event: time 100.258616, type 3 (EV_ABS), code 54 (ABS_MT_POSITION_Y), value 474 Event: time 100.258616, type 3 (EV_ABS), code 48 (ABS_MT_TOUCH_MAJOR), value 8 Event: time 100.258616, type 3 (EV_ABS), code 50 (ABS_MT_WIDTH_MAJOR), value 8 Event: time 100.258616, type 1 (EV_KEY), code 330 (BTN_TOUCH), value 1 Event: time 100.258616, type 3 (EV_ABS), code 0 (ABS_X), value 6 Event: time 100.258616, type 3 (EV_ABS), code 1 (ABS_Y), value 474 Event: time 100.258616, -------------- SYN_REPORT ------------ Event: time 100.310865, type 3 (EV_ABS), code 57 (ABS_MT_TRACKING_ID), value -1 Event: time 100.310865, type 1 (EV_KEY), code 330 (BTN_TOUCH), value 0 Event: time 100.310865, -------------- SYN_REPORT ------------
中断正常:
# # cat /proc/interrupts CPU0 16: 4309 sun4i_irq 13 Edge timer@1c20c00 17: 0 sun4i_irq 18 Edge 1c02000.dma-controller 18: 3 sun4i_irq 10 Edge sun6i-spi 19: 316 sun4i_irq 29 Edge 1c0c000.lcd-controller 20: 0 sun4i_irq 34 Edge cedar_dev 21: 3970 sun4i_irq 23 Edge sunxi-mmc 22: 1 sun4i_irq 26 Edge musb-hdrc.1.auto 28: 839 sun4i_irq 2 Edge ttyS0 29: 2261 sun4i_irq 7 Edge mv64xxx_i2c 76: 93 sunxi_pio_edge 44 Edge gt911 Err: 0 #
-
回复: 芒果的tiny200s板子 gt911电容屏不能中断,一筹莫展中
刚刚有朋友提醒我,把中断腿设置为io模式,看能拉高拉低,
测试 PE12 输出高低电平:
echo $((4*32+12)) echo 140 > /sys/class/gpio/export echo out > /sys/class/gpio/gpio140/direction echo 0 > /sys/class/gpio/gpio140/value
然后果然不能拉高拉低,难道板子坏了吗?
-
回复: 芒果的tiny200s板子 gt911电容屏不能中断,一筹莫展中
我记得以前是正常的
三块新屏都是一样的问题,用万用表量了一下,触摸的时候屏的INT引脚确实不能下拉.
-
芒果的tiny200s板子 gt911电容屏不能中断,一筹莫展中
使用的是这个SDK: buildroot-tiny200 (F1C100/200s) 开发包近期更新内容 * 已支持DVP摄像头 *
i2c 检测 gt911 正常
[ 4.444256] Goodix-TS 0-0014: 0-0014 supply AVDD28 not found, using dummy regulator [ 4.452376] Goodix-TS 0-0014: 0-0014 supply VDDIO not found, using dummy regulator [ 4.460527] suniv-f1c100s-pinctrl 1c20800.pinctrl: 1c20800.pinctrl supply vcc-pe not found, using dummy regulator [ 4.739056] Goodix-TS 0-0014: ID 911, version: 1060 [ 4.803438] input: Goodix Capacitive TouchScreen as /devices/platform/soc/1c27000.i2c/i2c-0/0-0014/input/input0 [ 5.560878] urandom_read: 1 callbacks suppressed [ 5.560903] random: dd: uninitialized urandom read (512 bytes read) [ 5.838436] file system registered [ 5.984015] read descriptors [ 5.987311] read strings
evtest不听使唤:
# evtest /dev/input/event0 Input driver version is 1.0.1 Input device ID: bus 0x18 vendor 0x416 product 0x38f version 0x1060 Input device name: "Goodix Capacitive TouchScreen" Supported events: Event type 0 (EV_SYN) Event type 1 (EV_KEY) Event code 125 (KEY_LEFTMETA) Event code 330 (BTN_TOUCH) Event type 3 (EV_ABS) Event code 0 (ABS_X) Value 0 Min 0 Max 799 Event code 1 (ABS_Y) Value 0 Min 0 Max 479 Event code 47 (ABS_MT_SLOT) Value 0 Min 0 Max 4 Event code 48 (ABS_MT_TOUCH_MAJOR) Value 0 Min 0 Max 255 Event code 50 (ABS_MT_WIDTH_MAJOR) Value 0 Min 0 Max 255 Event code 53 (ABS_MT_POSITION_X) Value 0 Min 0 Max 799 Event code 54 (ABS_MT_POSITION_Y) Value 0 Min 0 Max 479 Event code 57 (ABS_MT_TRACKING_ID) Value 0 Min 0 Max 65535 Properties: Property type 1 (INPUT_PROP_DIRECT) Testing ... (interrupt to exit)
gt911 中断次数0:
# cat /proc/interrupts CPU0 16: 4309 sun4i_irq 13 Edge timer@1c20c00 17: 0 sun4i_irq 18 Edge 1c02000.dma-controller 18: 3 sun4i_irq 10 Edge sun6i-spi 19: 316 sun4i_irq 29 Edge 1c0c000.lcd-controller 20: 0 sun4i_irq 34 Edge cedar_dev 21: 3970 sun4i_irq 23 Edge sunxi-mmc 22: 1 sun4i_irq 26 Edge musb-hdrc.1.auto 28: 839 sun4i_irq 2 Edge ttyS0 29: 2261 sun4i_irq 7 Edge mv64xxx_i2c 76: 0 sunxi_pio_edge 44 Edge gt911 Err: 0
-
回复: f1c200s 触摸屏问题
没看出哪个地方有语法错误,会不会弄错dts文件了呢?
还是直接用这个SDK吧: buildroot-tiny200 (F1C100/200s) 开发包近期更新内容 * 已支持DVP摄像头 *
-
回复: 动手让LVGL8带的Music-Demo音乐响起来(代码已上传)
[lv_demos/src/lv_demo_music/lv_demo_music_main.c@797]:music id:1 [lv_demos/src/lv_demo_music/lv_demo_music_main.c@798]:music name:1.wav [lv_demos/src/lv_demo_music/lv_demo_music_main.c@338]:{ "command": ["loadfile", "./music/1.wav"] } [lv_demos/src/lv_demo_music/lv_demo_music_main.c@797]:music id:2 [lv_demos/src/lv_demo_music/lv_demo_music_main.c@798]:music name:2.wav [lv_demos/src/lv_demo_music/lv_demo_music_main.c@338]:{ "command": ["loadfile", "./music/2.wav"] } [lv_demos/src/lv_demo_music/lv_demo_music_main.c@797]:music id:3 [lv_demos/src/lv_demo_music/lv_demo_music_main.c@798]:music name:3.wav [lv_demos/src/lv_demo_music/lv_demo_music_main.c@338]:{ "command": ["loadfile", "./music/3.wav"] } [lv_demos/src/lv_demo_music/lv_demo_music_main.c@797]:music id:1 [lv_demos/src/lv_demo_music/lv_demo_music_main.c@798]:music name:1.wav [lv_demos/src/lv_demo_music/lv_demo_music_main.c@338]:{ "command": ["loadfile", "./music/1.wav"] } [lv_demos/src/lv_demo_music/lv_demo_music_main.c@797]:music id:2 [lv_demos/src/lv_demo_music/lv_demo_music_main.c@798]:music name:2.wav [lv_demos/src/lv_demo_music/lv_demo_music_main.c@338]:{ "command": ["loadfile", "./music/2.wav"] } [lv_demos/src/lv_demo_music/lv_demo_music_main.c@797]:music id:3 [lv_demos/src/lv_demo_music/lv_demo_music_main.c@798]:music name:3.wav [lv_demos/src/lv_demo_music/lv_demo_music_main.c@338]:{ "command": ["loadfile", "./music/3.wav"] } Segmentation fault (core dumped)
-
回复: 动手让LVGL8带的Music-Demo音乐响起来(代码已上传)
这是作者昨天深夜发我的代码,我试过了,按钮很好使了,但是偶尔还是会die,您试一试: music_player_base_mpv_20220618.7z
-
回复: 请教一下各位大佬,T113 如何进入FEL BOOT?
不插TF卡,并且下拉 SPI FLASH 的 CS/MISO/MOSI 引脚,插入USB OTG 即进入FEL。
-
回复: 动手让LVGL8带的Music-Demo音乐响起来(代码已上传)
捋了一下,楼主用进程通讯的,先启动后台进程:
mpv --quiet --no-terminal --no-video --idle=yes --term-status-msg= --input-ipc-server=/tmp/mpvsocket
然后前台使用命令通讯
装载文件:
echo '{ "command": ["loadfile", "/mnt/hgfs/D/music/3.wav"] }' | socat - /tmp/mpvsocket
暂停:
echo '{ "command": ["set_property", "pause", true] }' | socat - /tmp/mpvsocket
继续:
echo '{ "command": ["set_property", "pause", false] }' | socat - /tmp/mpvsocket
播放进度:
echo '{ "command": ["get_property", "playback-time"] }' | socat - /tmp/mpvsocket
获取当前播放文件名:
echo '{ "command": ["get_property", "filename"] }' | socat - /tmp/mpvsocket
获取总时长:
echo '{ "command": ["get_property", "duration"] }' | socat - /tmp/mpvsocket
剩余时长:
echo '{ "command": ["get_property", "time-remaining"] }' | socat - /tmp/mpvsocket
播放进度:
echo '{ "command": ["get_property", "time-pos"] }' | socat - /tmp/mpvsocket
文件信息:
echo '{ "command": ["get_property", "filtered-metadata"] }' | socat - /tmp/mpvsocket
设置音量:
echo '{ "command": ["set_property", "volume", 80] }' | socat - /tmp/mpvsocket
获取当前音量:
echo '{ "command": ["get_property", "volume"] }' | socat - /tmp/mpvsocket
绝对定位(180秒):
echo '{ "command": ["seek", 180, "absolute"] }' | socat - /tmp/mpvsocket
相对定位(往前180秒):
echo '{ "command": ["seek", 180, "relative"] }' | socat - /tmp/mpvsocket
添加到播放列表:
echo '{ "command": ["loadfile", "/mnt/hgfs/D/music/08 初恋女.wav", "append"] }' | socat - /tmp/mpvsocket
显示播放列表:
echo '{ "command": ["get_property", "playlist"] }' | socat - /tmp/mpvsocket
显示当前播放的音乐文件名:
echo '{ "command": ["get_property", "media-title"] }' | socat - /tmp/mpvsocket
显示播放列表音乐数量:
echo '{ "command": ["get_property", "playlist-count"] }' | socat - /tmp/mpvsocket
播放列表序号是2的歌曲:
echo '{ "command": ["set_property", "playlist-pos", 2] }' | socat - /tmp/mpvsocket
获取当前播放的歌曲在列表中的序号:
echo '{ "command": ["get_property", "playlist-pos"] }' | socat - /tmp/mpvsocket
获取工作目录:
echo '{ "command": ["get_property", "working-directory"] }' | socat - /tmp/mpvsocket
获取播放列表序号3的文件名:
echo '{ "command": ["get_property", "playlist/3/filename"] }' | socat - /tmp/mpvsocket
设置循环播放:
echo '{ "command": ["set_property", "loop", true] }' | socat - /tmp/mpvsocket
读取循环播放设置:
echo '{ "command": ["get_property", "loop"] }' | socat - /tmp/mpvsocket
更多使用方法,参考: https://man.archlinux.org/man/community/mpv/mpv.1.en
-
回复: 动手让LVGL8带的Music-Demo音乐响起来(代码已上传)
感谢楼主 @xfdr0805 ,已经拿到源码,GUI没有问题了,但是ubuntu16.04 mpv 创建 socket 文件失败,正在检查原因。
-
回复: 配置好config之后重新编译,lvgl还是没有显示,屏幕上一直是原来的哪吒图片
@jr_online
buildroot busybox 文件系统可以放/etc/init.d/ 或 /etc/profile.d/ -
回复: D1-H 使用内置FANOUT REFCLK 24M时钟扫到卡但是无法下载固件
@yuzukitsuru
示波器量下有没有24Mhz了,没有的话就找个有源晶振试一试。 -
回复: 【极简操作】使用builroot 2021一键编译生成D1 nezha 系统镜像!
rm output/target; find output/build/ -name .stamp_target_installed |xargs rm ; make
执行这个命令, 药到病除。
-
回复: 【极简操作】使用builroot 2021一键编译生成D1 nezha 系统镜像!
@ztcontrol
我问的是, 为什么 “可是大小没见缩小”?是不是禁用了一些软件包,却没有缩小?
-
回复: 【极简操作】使用builroot 2021一键编译生成D1 nezha 系统镜像!
*** Maybe you need to increase the filesystem size (BR2_TARGET_ROOTFS_EXT2_SIZE)
根文件系统超过了 BR2_TARGET_ROOTFS_EXT2_SIZE 尺寸
直接编辑 .config 文件, 修改上面那个变量.
-
回复: tina linux IP地址每次重启都改变
通过板上的其它唯一Id(flash,soc id)通过某些函数变换得到一个mac地址,然后通过这个命令设置:
ifconfig eth0 ether 00:01:02:03:04:05
-
回复: Windows/Linux 给 lvgl8 添加本地文件系统支持。
@xfdr0805
感谢指教, 我搜索了一下本地文件确实没有, 是比较旧的 v8.0.x看了一下主线, 真有了:
https://github.com/lvgl/lvgl/commits/master/src/extra/libs/fsdrv/lv_fs_posix.c
-
回复: LVGL8的窗口切换 (转)
#include "lvgl/lvgl.h" #define HIDDEN_WIN (0) static lv_obj_t *win1_contanier = NULL; static lv_obj_t *win2_contanier = NULL; static void win_btn_event_callback1(lv_event_t* event); static void win_btn_event_callback2(lv_event_t* event); static void show_button_win1() { static lv_style_t obj_style; lv_style_reset(&obj_style); lv_style_init(&obj_style); // 初始化按钮样式 lv_style_set_radius(&obj_style, 0); // 设置样式圆角弧度 lv_obj_t * btn = NULL; lv_obj_t * label1 = NULL; win1_contanier = lv_obj_create(lv_scr_act()); // 基于屏幕创建一个和屏幕大小一样的容器win1_contanier if (win1_contanier != NULL) { lv_obj_set_style_bg_color(win1_contanier, lv_palette_main(LV_PALETTE_RED), 0); lv_obj_set_size(win1_contanier, 800, 480); lv_obj_add_style(win1_contanier, &obj_style, 0); btn = lv_btn_create(win1_contanier); label1 = lv_label_create(win1_contanier); if (btn != NULL) { lv_obj_set_size(btn, 100, 50); //lv_obj_set_pos(btn, 100, 100); lv_obj_add_event_cb(btn, win_btn_event_callback1, LV_EVENT_ALL, NULL); // 给对象添加CLICK事件和事件处理回调函数 lv_obj_center(btn); lv_obj_align_to(label1, btn, LV_ALIGN_OUT_TOP_LEFT, 0, -10); lv_label_set_text(label1, "This is window1"); lv_obj_t *label = lv_label_create(btn); // 给按钮添加标签 if (label != NULL) { lv_label_set_text(label, "Button1"); // 设置标签文本 lv_obj_center(label); // 标签居中显示 } } } } static void show_button_win2() { static lv_style_t obj_style; lv_style_reset(&obj_style); lv_style_init(&obj_style); // 初始化按钮样式 lv_style_set_radius(&obj_style, 0); // 设置样式圆角弧度 lv_obj_t * btn =NULL; lv_obj_t * label2 = NULL; win2_contanier = lv_obj_create(lv_scr_act()); // 基于屏幕创建一个和屏幕大小一样的容器win2_contanier if (win2_contanier != NULL) { lv_obj_set_style_bg_color(win2_contanier, lv_palette_main(LV_PALETTE_BLUE), 0); lv_obj_set_size(win2_contanier, 800, 480); lv_obj_add_style(win2_contanier, &obj_style, 0); btn = lv_btn_create(win2_contanier); label2 = lv_label_create(win1_contanier); if (btn != NULL) { lv_obj_set_size(btn, 100, 50); lv_obj_add_event_cb(btn, win_btn_event_callback2, LV_EVENT_ALL, NULL); // 给对象添加CLICK事件和事件处理回调函数 lv_obj_center(btn); lv_obj_set_style_bg_color(btn, lv_palette_main(LV_PALETTE_RED), 0); lv_obj_t *label = lv_label_create(btn); // 给按钮添加标签 lv_obj_align_to(label2, btn, LV_ALIGN_OUT_TOP_LEFT, 0, -20); lv_label_set_text(label2, "This is window2"); if (label != NULL) { lv_label_set_text(label, "Button2"); // 设置标签文本 lv_obj_center(label); // 标签居中显示 } } } } static void win_btn_event_callback1(lv_event_t* event) { lv_event_code_t code = lv_event_get_code(event); if (code == LV_EVENT_CLICKED) { #if HIDDEN_WIN // 给窗口1的容器添加隐藏属性,清除窗口2的隐藏属性 lv_obj_add_flag(win1_contanier, LV_OBJ_FLAG_HIDDEN); lv_obj_clear_flag(win2_contanier, LV_OBJ_FLAG_HIDDEN); #else // 删除窗口1的win1_contanier容器,这样就可以把win1_contanier上的子对象全部删除,然后显示窗口2 lv_obj_del(win1_contanier); show_button_win2(); #endif } } static void win_btn_event_callback2(lv_event_t* event) { lv_event_code_t code = lv_event_get_code(event); if (code == LV_EVENT_CLICKED) { #if HIDDEN_WIN // 给窗口2的容器添加隐藏属性,清除窗口1的隐藏属性 lv_obj_add_flag(win2_contanier, LV_OBJ_FLAG_HIDDEN); lv_obj_clear_flag(win1_contanier, LV_OBJ_FLAG_HIDDEN); #else // 删除窗口2的win2_contanier容器,这样就可以把win2_contanier上的子对象全部删除,然后显示窗口1 lv_obj_del(win2_contanier); show_button_win1(); #endif } } void lv_win_switch_main() { show_button_win1(); #if HIDDEN_WIN show_button_win2(); // 给窗口2的容器添加隐藏属性 lv_obj_add_flag(win2_contanier, LV_OBJ_FLAG_HIDDEN); #endif }
添加 label 后的代码
-
回复: LVGL8的窗口切换 (转)
转载: LVGL8的窗口切换方式
LVGL8实现两个窗口的切换方式:
方法一:切换到窗口2时,删除窗口1的容器,这样可以删除窗口1下的所有子对象,这种方式适用于运存较小的设备方法二:显示窗口1之前给窗口2的容器设置LV_OBJ_FLAG_HIDDEN隐藏属性,显示窗口2之前给窗口1的容器设置LV_OBJ_FLAG_HIDDEN隐藏属性
还是通过codeblock来模拟代码的运行,代码如下:
#define HIDDEN_WIN (0) static lv_obj_t *win1_contanier = NULL; static lv_obj_t *win2_contanier = NULL; static void win_btn_event_callback1(lv_event_t* event); static void win_btn_event_callback2(lv_event_t* event); static void show_button_win1() { static lv_style_t obj_style; lv_style_reset(&obj_style); lv_style_init(&obj_style); // 初始化按钮样式 lv_style_set_radius(&obj_style, 0); // 设置样式圆角弧度 lv_obj_t * btn =NULL; win1_contanier = lv_obj_create(lv_scr_act()); // 基于屏幕创建一个和屏幕大小一样的容器win1_contanier if (win1_contanier != NULL) { lv_obj_set_style_bg_color(win1_contanier, lv_palette_main(LV_PALETTE_RED), 0); lv_obj_set_size(win1_contanier, 800, 480); lv_obj_add_style(win1_contanier, &obj_style, 0); btn = lv_btn_create(win1_contanier); if (btn != NULL) { lv_obj_set_size(btn, 100, 50); lv_obj_add_event_cb(btn, win_btn_event_callback1, LV_EVENT_ALL, NULL); // 给对象添加CLICK事件和事件处理回调函数 lv_obj_center(btn); lv_obj_t *label = lv_label_create(btn); // 给按钮添加标签 if (label != NULL) { lv_label_set_text(label, "Button1"); // 设置标签文本 lv_obj_center(label); // 标签居中显示 } } } } static void show_button_win2() { static lv_style_t obj_style; lv_style_reset(&obj_style); lv_style_init(&obj_style); // 初始化按钮样式 lv_style_set_radius(&obj_style, 0); // 设置样式圆角弧度 lv_obj_t * btn =NULL; win2_contanier = lv_obj_create(lv_scr_act()); // 基于屏幕创建一个和屏幕大小一样的容器win2_contanier if (win2_contanier != NULL) { lv_obj_set_style_bg_color(win2_contanier, lv_palette_main(LV_PALETTE_BLUE), 0); lv_obj_set_size(win2_contanier, 800, 480); lv_obj_add_style(win2_contanier, &obj_style, 0); btn = lv_btn_create(win2_contanier); if (btn != NULL) { lv_obj_set_size(btn, 100, 50); lv_obj_add_event_cb(btn, win_btn_event_callback2, LV_EVENT_ALL, NULL); // 给对象添加CLICK事件和事件处理回调函数 lv_obj_center(btn); lv_obj_set_style_bg_color(btn, lv_palette_main(LV_PALETTE_RED), 0); lv_obj_t *label = lv_label_create(btn); // 给按钮添加标签 if (label != NULL) { lv_label_set_text(label, "Button2"); // 设置标签文本 lv_obj_center(label); // 标签居中显示 } } } } static void win_btn_event_callback1(lv_event_t* event) { lv_event_code_t code = lv_event_get_code(event); if (code == LV_EVENT_CLICKED) { #if HIDDEN_WIN // 给窗口1的容器添加隐藏属性,清除窗口2的隐藏属性 lv_obj_add_flag(win1_contanier, LV_OBJ_FLAG_HIDDEN); lv_obj_clear_flag(win2_contanier, LV_OBJ_FLAG_HIDDEN); #else // 删除窗口1的win1_contanier容器,这样就可以把win1_contanier上的子对象全部删除,然后显示窗口2 lv_obj_del(win1_contanier); show_button_win2(); #endif } } static void win_btn_event_callback2(lv_event_t* event) { lv_event_code_t code = lv_event_get_code(event); if (code == LV_EVENT_CLICKED) { #if HIDDEN_WIN // 给窗口2的容器添加隐藏属性,清除窗口1的隐藏属性 lv_obj_add_flag(win2_contanier, LV_OBJ_FLAG_HIDDEN); lv_obj_clear_flag(win1_contanier, LV_OBJ_FLAG_HIDDEN); #else // 删除窗口2的win2_contanier容器,这样就可以把win2_contanier上的子对象全部删除,然后显示窗口1 lv_obj_del(win2_contanier); show_button_win1(); #endif } } void lv_win_switch_main() { show_button_win1(); #if HIDDEN_WIN show_button_win2(); // 给窗口2的容器添加隐藏属性 lv_obj_add_flag(win2_contanier, LV_OBJ_FLAG_HIDDEN); #endif }
-
回复: LVGL|lvgl教程之巧用图层(layer)编写模态对话框 (转载)
改进
上面的代码实现的效果是标准的模式对话框的效果,我们必须完成日历的设置才能退出对话框,如果是不小心点错了或者不想现在就设置,那么应该是点击空白处就可以退出当前对话框,实现效果是这样的:
实现源码
基于上面模式对话框来改进代码,非常简单,我们只要在 calendar_event_cb 和 birthday_event_cb 函数中稍作修改即可。重点就是我们在进入模式对话框的时候,因为设置日期的对话框是在 lv_layer_top 层上创建的,所以 lv_layer_top 层也就位于设置日期对话框之下了,所以我们只要让用户点击位于对话框之下的 lv_layer_top 层的任意地方时关闭对话框即可。看注释是阅读理解源码的好方法,下面给出的代码可直接在lvgl开发环境下运行。
static void birthday_event_cb(lv_event_t * e) { lv_event_code_t code = lv_event_get_code(e); lv_obj_t * ta = lv_event_get_target(e); if(code == LV_EVENT_FOCUSED) { if(lv_indev_get_type(lv_indev_get_act()) == LV_INDEV_TYPE_POINTER) { if(calendar == NULL) { lv_obj_add_flag(lv_layer_top(), LV_OBJ_FLAG_CLICKABLE); // 使能 lv_layer_top 点击 calendar = lv_calendar_create(lv_layer_top()); // 在 lv_layer_top 层上创建日历对象 lv_obj_set_style_bg_opa(lv_layer_top(), LV_OPA_50, 0); // 设置对象透明度 lv_obj_set_style_bg_color(lv_layer_top(), lv_palette_main(LV_PALETTE_GREY), 0); // 设置对象颜色 lv_obj_set_size(calendar, 300, 300); // 设置对象大小 lv_calendar_set_showed_date(calendar, 1990, 01); // 给日历的指定打开时显示的日期 lv_obj_align(calendar, LV_ALIGN_CENTER, 0, 30); // 设置对象对齐、偏移 lv_obj_add_event_cb(calendar, calendar_event_cb, LV_EVENT_VALUE_CHANGED, ta); // 给对象分配事件 lv_obj_add_event_cb(lv_layer_top(), calendar_event_cb, LV_EVENT_CLICKED, NULL); // 给对象分配事件(lv_layer_top层分配点击回调处理函数) calendar_header = lv_calendar_header_dropdown_create(lv_layer_top(), calendar); // 创建一个包含 2 个下拉列表的标题:一个用于年份,另一个用于月份。 } } } } static void calendar_event_cb(lv_event_t * e) { lv_event_code_t code = lv_event_get_code(e); // 获取事件代码 lv_obj_t * ta = lv_event_get_user_data(e); // 获取在对象上注册事件时传递的 user_data // 判断事件类型 if(code == LV_EVENT_VALUE_CHANGED) { char buf[32]; lv_calendar_date_t d; lv_calendar_get_pressed_date(e->target, &d); // 获取当前选中的日期 lv_snprintf(buf, sizeof(buf), "%02d.%02d.%d", d.day, d.month, d.year); lv_textarea_set_text(ta, buf); // 在文本区域展示日期信息 lv_obj_del(calendar); // 删除对象及其所有子对象 lv_obj_del(calendar_header); // 删除对象及其所有子对象 lv_obj_remove_event_cb(lv_layer_top(),calendar_event_cb); // 删除对象的事件处理函数(lv_layer_top层) calendar = NULL; calendar_header = NULL; lv_obj_clear_flag(lv_layer_top(), LV_OBJ_FLAG_CLICKABLE); // 清除标志(lv_layer_top层) lv_obj_set_style_bg_opa(lv_layer_top(), LV_OPA_TRANSP, 0); // 设置透明度(lv_layer_top层) } else if ((code == LV_EVENT_CLICKED)) { lv_obj_del(calendar); // 删除对象及其所有子对象 lv_obj_del(calendar_header); // 删除对象及其所有子对象 lv_obj_remove_event_cb(lv_layer_top(),calendar_event_cb); // 删除对象的事件处理函数(lv_layer_top层) calendar = NULL; calendar_header = NULL; lv_obj_clear_flag(lv_layer_top(), LV_OBJ_FLAG_CLICKABLE); // 清除标志(lv_layer_top层) lv_obj_set_style_bg_opa(lv_layer_top(), LV_OPA_TRANSP, 0); // 设置透明度(lv_layer_top层) } }
更近一步的改进
这里的改进是对于对话框之外的改进,不知道读者发现没有,我们布局编写的代码非常低级糟糕的,其实我们不用这么麻烦,lvgl 8.x 中我们可以使用两种布局:Flex(弹性布局)
Grid(网格布局)
通过这两种布局我们可以很方便的管理我们的ui布局。这部分的内容超出了本文的范围,感兴趣的读者可以关注阅读我的下一篇文章 -
回复: LVGL|lvgl教程之巧用图层(layer)编写模态对话框 (转载)
lvgl模式对话框代码
看注释是阅读理解源码的好方法,下面给出的代码可直接在lvgl开发环境下运行。
/** * @file lv_100ask_demo_layer.c * */ /********************* * INCLUDES *********************/ #include "lv_100ask_demo_layer.h" /********************* * DEFINES *********************/ /********************** * TYPEDEFS **********************/ /********************** * STATIC VARIABLES **********************/ static lv_obj_t * bottom_bg; static lv_obj_t * calendar; static lv_obj_t * calendar_header; static void ta_event_cb(lv_event_t * e); static void birthday_event_cb(lv_event_t * e); static void calendar_event_cb(lv_event_t * e); static void birthday_event_cb(lv_event_t * e) { lv_event_code_t code = lv_event_get_code(e); lv_obj_t * ta = lv_event_get_target(e); if(code == LV_EVENT_FOCUSED) { if(lv_indev_get_type(lv_indev_get_act()) == LV_INDEV_TYPE_POINTER) { if(calendar == NULL) { lv_obj_add_flag(lv_layer_top(), LV_OBJ_FLAG_CLICKABLE); // 使能 lv_layer_top 点击 calendar = lv_calendar_create(lv_layer_top()); // 在 lv_layer_top 层上创建日历对象 lv_obj_set_style_bg_opa(lv_layer_top(), LV_OPA_50, 0); // 设置对象透明度 lv_obj_set_style_bg_color(lv_layer_top(), lv_palette_main(LV_PALETTE_GREY), 0); // 设置对象颜色 lv_obj_set_size(calendar, 300, 300); // 设置对象大小 lv_calendar_set_showed_date(calendar, 1990, 01); // 给日历的指定打开时显示的日期 lv_obj_align(calendar, LV_ALIGN_CENTER, 0, 30); // 设置对象对齐、偏移 lv_obj_add_event_cb(calendar, calendar_event_cb, LV_EVENT_VALUE_CHANGED, ta); // 给对象分配事件 calendar_header = lv_calendar_header_dropdown_create(lv_layer_top(), calendar); // 创建一个包含 2 个下拉列表的标题:一个用于年份,另一个用于月份。 } } } } static void calendar_event_cb(lv_event_t * e) { lv_event_code_t code = lv_event_get_code(e); // 获取事件代码 lv_obj_t * ta = lv_event_get_user_data(e); // 获取在对象上注册事件时传递的 user_data // 判断事件类型 if(code == LV_EVENT_VALUE_CHANGED) { char buf[32]; lv_calendar_date_t d; lv_calendar_get_pressed_date(e->target, &d); // 获取当前选中的日期 lv_snprintf(buf, sizeof(buf), "%02d.%02d.%d", d.day, d.month, d.year); lv_textarea_set_text(ta, buf); // 在文本区域展示日期信息 lv_obj_del(calendar); // 删除对象及其所有子对象 lv_obj_del(calendar_header); // 删除对象及其所有子对象 calendar = NULL; calendar_header = NULL; lv_obj_clear_flag(lv_layer_top(), LV_OBJ_FLAG_CLICKABLE); // 清除标志 lv_obj_set_style_bg_opa(lv_layer_top(), LV_OPA_TRANSP, 0); // 设置透明度 } else if ((code == LV_EVENT_CLICKED)) { lv_obj_del(calendar); // 删除对象及其所有子对象 lv_obj_del(calendar_header); // 删除对象及其所有子对象 calendar = NULL; calendar_header = NULL; lv_obj_clear_flag(lv_layer_top(), LV_OBJ_FLAG_CLICKABLE); // 清除标志 lv_obj_set_style_bg_opa(lv_layer_top(), LV_OPA_TRANSP, 0); // 设置透明度 } } static void ta_event_cb(lv_event_t * e) { lv_event_code_t code = lv_event_get_code(e); // 获取事件代码 lv_obj_t * ta = lv_event_get_target(e); // 获取事件最初指向的对象 lv_obj_t * kb = lv_event_get_user_data(e); // 获取在对象上注册事件时传递的 user_data // 判断事件类型(当焦点在键盘上时) if(code == LV_EVENT_FOCUSED) { //获取输入设备的类型 if(lv_indev_get_type(lv_indev_get_act()) != LV_INDEV_TYPE_KEYPAD) { lv_keyboard_set_textarea(kb, ta); // 为键盘分配一个文本区域 lv_obj_set_style_max_height(kb, LV_HOR_RES * 2 / 3, 0); // 设置键盘的最高宽度为屏幕高度的一半 lv_obj_update_layout(bottom_bg); // 确保尺寸更新 lv_obj_set_height(bottom_bg, LV_VER_RES - lv_obj_get_height(kb)); // 设置对象的高度,当唤出键盘时应该偏移背景 lv_obj_clear_flag(kb, LV_OBJ_FLAG_HIDDEN); // 清除标志 lv_obj_scroll_to_view_recursive(ta, LV_ANIM_OFF); // 滚动到一个对象,直到它在其父对象上可见。对父母的父母做同样的事情,依此类推。即使对象具有嵌套的可滚动父对象,它也会滚动到视图中 } } // 判断事件类型(当焦点不在键盘上时) else if(code == LV_EVENT_DEFOCUSED) { lv_keyboard_set_textarea(kb, NULL); lv_obj_set_height(bottom_bg, LV_VER_RES); lv_obj_add_flag(kb, LV_OBJ_FLAG_HIDDEN); } // 判断事件类型(当键盘点击确定或取消键) else if(code == LV_EVENT_READY || code == LV_EVENT_CANCEL) { lv_obj_set_height(bottom_bg, LV_VER_RES); lv_obj_add_flag(kb, LV_OBJ_FLAG_HIDDEN); // 标志为隐藏对象(使对象隐藏,就像它根本不存在一样) lv_obj_clear_state(e->target, LV_STATE_FOCUSED); // 删除对象的一种或多种状态。其他状态位将保持不变。 lv_indev_reset(NULL, e->target); // 忘记最后一次点击的对象,使其再次成为可关注的对象 } } void lv_100ask_demo_layer(void) { static lv_style_t style_title; static lv_style_t style_text_muted; bottom_bg = lv_obj_create(lv_scr_act()); lv_obj_set_size(bottom_bg, LV_HOR_RES, LV_VER_RES); // 设置样式 lv_style_init(&style_title); lv_style_set_text_font(&style_title, &lv_font_montserrat_20); // 字体 lv_style_init(&style_text_muted); lv_style_set_text_opa(&style_text_muted, LV_OPA_50); // 文本透明度 // 创建键盘 lv_obj_t * kb = lv_keyboard_create(lv_scr_act()); lv_obj_add_flag(kb, LV_OBJ_FLAG_HIDDEN); // 标志为隐藏对象(使对象隐藏,就像它根本不存在一样) // 创建对象并初始化 lv_obj_t * title = lv_label_create(bottom_bg); lv_label_set_text(title, "Your profile"); // 为标签设置新文本 lv_obj_add_style(title, &style_title, 0); // 给对象添加样式 lv_obj_align(bottom_bg, LV_ALIGN_TOP_LEFT, 0, 0); // 更改对象的对齐方式并设置新坐标。 lv_obj_t * user_name_label = lv_label_create(bottom_bg); lv_label_set_text(user_name_label, "User name"); // 为标签设置新文本 lv_obj_add_style(user_name_label, &style_text_muted, 0); // 给对象添加样式 lv_obj_align(user_name_label, LV_ALIGN_TOP_LEFT, 0, 30); // 更改对象的对齐方式并设置新坐标 lv_obj_t * user_name = lv_textarea_create(bottom_bg); lv_textarea_set_one_line(user_name, true); // 单行模式 lv_textarea_set_placeholder_text(user_name, "Your name"); // 设置文本区域的占位符文本(输入框提示文本内容) lv_obj_add_event_cb(user_name, ta_event_cb, LV_EVENT_ALL, kb); // 为对象分配事件及其处理函数 lv_obj_align(user_name, LV_ALIGN_TOP_LEFT, 0, 50); // 更改对象的对齐方式并设置新坐标 lv_obj_t * password_label = lv_label_create(bottom_bg); lv_label_set_text(password_label, "Password"); // 为标签设置新文本 lv_obj_align(password_label, LV_ALIGN_TOP_MID, -95, 30); // 更改对象的对齐方式并设置新坐标。 lv_obj_add_style(password_label, &style_text_muted, 0); // 给对象添加样式 lv_obj_t * password = lv_textarea_create(bottom_bg); lv_textarea_set_one_line(password, true); // 单行模式 lv_textarea_set_password_mode(password, true); // 密码模式 lv_textarea_set_placeholder_text(password, "Min. 8 chars."); // 设置文本区域的占位符文本(输入框提示文本内容) lv_obj_align(password, LV_ALIGN_TOP_MID, 0, 50); // 更改对象的对齐方式并设置新坐标 lv_obj_add_event_cb(password, ta_event_cb, LV_EVENT_ALL, kb); // 为对象分配事件及其处理函数 lv_obj_t * gender_label = lv_label_create(bottom_bg); lv_label_set_text(gender_label, "Gender"); // 为标签设置新文本 lv_obj_add_style(gender_label, &style_text_muted, 0); // 给对象添加样式 lv_obj_align(gender_label, LV_ALIGN_TOP_LEFT, 0, 100); // 更改对象的对齐方式并设置新坐标 lv_obj_t * gender = lv_dropdown_create(bottom_bg); lv_dropdown_set_options_static(gender, "Male\nFemale\nOther"); // 设置下拉列表选项 lv_obj_align(gender, LV_ALIGN_TOP_LEFT, 0, 120); // 更改对象的对齐方式并设置新坐标 lv_obj_t * birthday_label = lv_label_create(bottom_bg); lv_label_set_text(birthday_label, "Birthday"); // 为标签设置新文本 lv_obj_align(birthday_label, LV_ALIGN_TOP_MID, -95, 100); // 更改对象的对齐方式并设置新坐标 lv_obj_add_style(birthday_label, &style_text_muted, 0); // 给对象添加样式 lv_obj_t * birthdate = lv_textarea_create(bottom_bg); lv_textarea_set_one_line(birthdate, true); // 单行模式 lv_obj_align(birthdate, LV_ALIGN_TOP_MID, 0, 120); // 更改对象的对齐方式并设置新坐标 lv_obj_add_event_cb(birthdate, birthday_event_cb, LV_EVENT_ALL, NULL); // 为对象分配事件及其处理函数 }
-
回复: LVGL|lvgl教程之巧用图层(layer)编写模态对话框 (转载)
lvgl无模式对话框示例代码
看注释是阅读理解源码的好方法,下面给出的代码可直接在lvgl开发环境下运行。
/** * @file lv_100ask_demo_layer.c * */ /********************* * INCLUDES *********************/ #include "lv_100ask_demo_layer.h" /********************* * DEFINES *********************/ /********************** * TYPEDEFS **********************/ /********************** * STATIC PROTOTYPES **********************/ /* 对象事件处理函数 */ static void ta_event_cb(lv_event_t * e); static void birthday_event_cb(lv_event_t * e); static void calendar_event_cb(lv_event_t * e); /********************** * STATIC VARIABLES **********************/ static lv_obj_t * bottom_bg; static lv_obj_t * calendar; static lv_obj_t * calendar_header; /********************** * STATIC FUNCTIONS **********************/ static void birthday_event_cb(lv_event_t * e) { lv_event_code_t code = lv_event_get_code(e); lv_obj_t * ta = lv_event_get_target(e); // 获取事件最初指向的对象 // 判断事件类型 if(code == LV_EVENT_FOCUSED) { //获取输入设备的类型 if(lv_indev_get_type(lv_indev_get_act()) == LV_INDEV_TYPE_POINTER) { if(calendar == NULL) { calendar = lv_calendar_create(lv_scr_act()); // 创建日历对象 lv_obj_set_style_bg_opa(lv_scr_act(), LV_OPA_50, 0); // 设置对象透明度 lv_obj_set_style_bg_color(lv_scr_act(), lv_palette_main(LV_PALETTE_GREY), 0); // 设置对象颜色 lv_obj_set_size(calendar, 300, 300); // 设置对象大小 lv_calendar_set_showed_date(calendar, 1990, 01); // 给日历的指定打开时显示的日期 lv_obj_align(calendar, LV_ALIGN_CENTER, 0, 30); // 设置对象对齐、偏移 lv_obj_add_event_cb(calendar, calendar_event_cb, LV_EVENT_VALUE_CHANGED, ta); // 为对象分配事件及其处理函数 calendar_header = lv_calendar_header_dropdown_create(lv_scr_act(), calendar); // 创建一个包含 2 个下拉列表的标题:一个用于年份,另一个用于月份。 } } } } static void calendar_event_cb(lv_event_t * e) { lv_event_code_t code = lv_event_get_code(e); // 获取事件代码 lv_obj_t * ta = lv_event_get_user_data(e); // 获取在对象上注册事件时传递的 user_data // 判断事件类型 if(code == LV_EVENT_VALUE_CHANGED) { lv_calendar_date_t d; lv_calendar_get_pressed_date(e->target, &d); // 获取当前选中的日期 char buf[32]; lv_snprintf(buf, sizeof(buf), "%02d.%02d.%d", d.day, d.month, d.year); lv_textarea_set_text(ta, buf); lv_obj_del(calendar); // 删除对象及其所有子对象 lv_obj_del(calendar_header); // 删除对象及其所有子对象 calendar = NULL; calendar_header = NULL; } else if ((code == LV_EVENT_CLICKED)) { lv_obj_del(calendar); // 删除对象及其所有子对象 lv_obj_del(calendar_header); // 删除对象及其所有子对象 calendar = NULL; calendar_header = NULL; } } static void ta_event_cb(lv_event_t * e) { lv_event_code_t code = lv_event_get_code(e); // 获取事件代码 lv_obj_t * ta = lv_event_get_target(e); // 获取事件最初指向的对象 lv_obj_t * kb = lv_event_get_user_data(e); // 获取在对象上注册事件时传递的 user_data // 判断事件类型(当焦点在键盘上时) if(code == LV_EVENT_FOCUSED) { //获取输入设备的类型 if(lv_indev_get_type(lv_indev_get_act()) != LV_INDEV_TYPE_KEYPAD) { lv_keyboard_set_textarea(kb, ta); // 为键盘分配一个文本区域 lv_obj_set_style_max_height(kb, LV_HOR_RES * 2 / 3, 0); // 设置键盘的最高宽度为屏幕高度的一半 lv_obj_update_layout(bottom_bg); // 确保尺寸更新 lv_obj_set_height(bottom_bg, LV_VER_RES - lv_obj_get_height(kb)); // 设置对象的高度,当唤出键盘时应该偏移背景 lv_obj_clear_flag(kb, LV_OBJ_FLAG_HIDDEN); // 清除标志 lv_obj_scroll_to_view_recursive(ta, LV_ANIM_OFF); // 滚动到一个对象,直到它在其父对象上可见。对父母的父母做同样的事情,依此类推。即使对象具有嵌套的可滚动父对象,它也会滚动到视图中 } } // 判断事件类型(当焦点不在键盘上时) else if(code == LV_EVENT_DEFOCUSED) { lv_keyboard_set_textarea(kb, NULL); lv_obj_set_height(bottom_bg, LV_VER_RES); lv_obj_add_flag(kb, LV_OBJ_FLAG_HIDDEN); } // 判断事件类型(当键盘点击确定或取消键) else if(code == LV_EVENT_READY || code == LV_EVENT_CANCEL) { lv_obj_set_height(bottom_bg, LV_VER_RES); lv_obj_add_flag(kb, LV_OBJ_FLAG_HIDDEN); // 标志为隐藏对象(使对象隐藏,就像它根本不存在一样) lv_obj_clear_state(e->target, LV_STATE_FOCUSED); // 删除对象的一种或多种状态。其他状态位将保持不变。 lv_indev_reset(NULL, e->target); // 忘记最后一次点击的对象,使其再次成为可关注的对象 } } /********************** * GLOBAL FUNCTIONS **********************/ void lv_100ask_demo_layer2(void) { static lv_style_t style_title; static lv_style_t style_text_muted; bottom_bg = lv_obj_create(lv_scr_act()); lv_obj_set_size(bottom_bg, LV_HOR_RES, LV_VER_RES); // 设置样式 lv_style_init(&style_title); lv_style_set_text_font(&style_title, &lv_font_montserrat_20); // 字体 lv_style_init(&style_text_muted); lv_style_set_text_opa(&style_text_muted, LV_OPA_50); // 文本透明度 // 创建键盘 lv_obj_t * kb = lv_keyboard_create(lv_scr_act()); lv_obj_add_flag(kb, LV_OBJ_FLAG_HIDDEN); // 标志为隐藏对象(使对象隐藏,就像它根本不存在一样) // 创建对象并初始化 lv_obj_t * title = lv_label_create(bottom_bg); lv_label_set_text(title, "Your profile"); // 为标签设置新文本 lv_obj_add_style(title, &style_title, 0); // 给对象添加样式 lv_obj_align(bottom_bg, LV_ALIGN_TOP_LEFT, 0, 0); // 更改对象的对齐方式并设置新坐标。 lv_obj_t * user_name_label = lv_label_create(bottom_bg); lv_label_set_text(user_name_label, "User name"); // 为标签设置新文本 lv_obj_add_style(user_name_label, &style_text_muted, 0); // 给对象添加样式 lv_obj_align(user_name_label, LV_ALIGN_TOP_LEFT, 0, 30); // 更改对象的对齐方式并设置新坐标 lv_obj_t * user_name = lv_textarea_create(bottom_bg); lv_textarea_set_one_line(user_name, true); // 单行模式 lv_textarea_set_placeholder_text(user_name, "Your name"); // 设置文本区域的占位符文本(输入框提示文本内容) lv_obj_add_event_cb(user_name, ta_event_cb, LV_EVENT_ALL, kb); // 为对象分配事件及其处理函数 lv_obj_align(user_name, LV_ALIGN_TOP_LEFT, 0, 50); // 更改对象的对齐方式并设置新坐标 lv_obj_t * password_label = lv_label_create(bottom_bg); lv_label_set_text(password_label, "Password"); // 为标签设置新文本 lv_obj_align(password_label, LV_ALIGN_TOP_MID, -95, 30); // 更改对象的对齐方式并设置新坐标。 lv_obj_add_style(password_label, &style_text_muted, 0); // 给对象添加样式 lv_obj_t * password = lv_textarea_create(bottom_bg); lv_textarea_set_one_line(password, true); // 单行模式 lv_textarea_set_password_mode(password, true); // 密码模式 lv_textarea_set_placeholder_text(password, "Min. 8 chars."); // 设置文本区域的占位符文本(输入框提示文本内容) lv_obj_align(password, LV_ALIGN_TOP_MID, 0, 50); // 更改对象的对齐方式并设置新坐标 lv_obj_add_event_cb(password, ta_event_cb, LV_EVENT_ALL, kb); // 为对象分配事件及其处理函数 lv_obj_t * gender_label = lv_label_create(bottom_bg); lv_label_set_text(gender_label, "Gender"); // 为标签设置新文本 lv_obj_add_style(gender_label, &style_text_muted, 0); // 给对象添加样式 lv_obj_align(gender_label, LV_ALIGN_TOP_LEFT, 0, 100); // 更改对象的对齐方式并设置新坐标 lv_obj_t * gender = lv_dropdown_create(bottom_bg); lv_dropdown_set_options_static(gender, "Male\nFemale\nOther"); // 设置下拉列表选项 lv_obj_align(gender, LV_ALIGN_TOP_LEFT, 0, 120); // 更改对象的对齐方式并设置新坐标 lv_obj_t * birthday_label = lv_label_create(bottom_bg); lv_label_set_text(birthday_label, "Birthday"); // 为标签设置新文本 lv_obj_align(birthday_label, LV_ALIGN_TOP_MID, -95, 100); // 更改对象的对齐方式并设置新坐标 lv_obj_add_style(birthday_label, &style_text_muted, 0); // 给对象添加样式 lv_obj_t * birthdate = lv_textarea_create(bottom_bg); lv_textarea_set_one_line(birthdate, true); // 单行模式 lv_obj_align(birthdate, LV_ALIGN_TOP_MID, 0, 120); // 更改对象的对齐方式并设置新坐标 lv_obj_add_event_cb(birthdate, birthday_event_cb, LV_EVENT_ALL, NULL); // 为对象分配事件及其处理函数 }
-
回复: LVGL|lvgl教程之巧用图层(layer)编写模态对话框 (转载)
实现原理
lvgl的具有图层(layer)的概念,默认规则是最后创建的在最上层,一般我们都是使用在 lv_scr_act 层上面创建各种控件(widgets),每个控件其实就相当于一个个小小的图层展示在屏幕上。
在 lv_scr_act 之上还有另外两个层 layer_top 和 layer_sys,这是两个特殊的层。两者在显示器的所有屏幕上都是可见的和通用的。但是,它们不会在多个物理显示器之间共享。 layer_top 始终位于默认屏幕 (lv_scr_act()) 的顶部,而 layer_sys 位于 layer_top 的顶部。
用户可以使用 layer_top 来创建一些随处可见的内容。例如,一个菜单栏,一个弹出窗口等。如果启用了click属性,那么layer_top将吸收所有用户点击并充当模态。
layer_sys 在 LVGL 中也用于类似的目的。例如,它将鼠标光标放在所有图层上方以确保它始终可见。
layer_sys > layer_top > lv_scr_act
使用lvgl实现模式对话框的关键点就是利用 layer_sys 和 layer_top 的特点。也就是说创建对话框的时候在 layer_sys 和 layer_top 之上创建即可。
示例中使用到了 layer_top 实现模式对话框效果。下面是示例源码。