低代码平台开发胎压监测APP
项目介绍
该项目是一个利用Flutter框架和蓝牙技术实现轮胎压力实时监测的应用。
主要功能如下:
- 用于接收蓝牙模块传输的胎压数据,并实时显示胎压值。
- APP对接收到的胎压数据进行处理,如单位转换、数据滤波等,然后将处理后的胎压值显示在界面上。
总之,该项目可以帮助用户实时监测轮胎压力,并提供丰富的功能以满足不同需求。该项目可以应用于汽车、自行车、摩托车等轮胎压力监测场景。
平台支持
-
Android
-
iOS
AiFlutter市场链接:胎压监测App
蓝牙调试助手APP源码链接:源码下载
平台实现步骤
一、注册登录
打开 低代码平台登录网页 ,使用微信快捷登录或者扫描二维码登录。
二、创建项目
-
点击【新增项目】>【手动添加】,在平台内部创建项目
-
在跳出的弹窗中输入项目名称、项目描述,建议结合项目功能描述命名,便于检索
-
输入完成后点击确定
三、创建页面
(1)点击已经创建好的项目进入到操作界面,默认会存在一个HomePage
页面,操作界面相关详情可查看教程 操作界面
(2)创建三个页面 AddBleDevice
、SetBleName
、DeviceNetWork
-
点击【添加页面】> 【创建页面】
-
在跳出的弹窗中输入 页面名称、页面描述
-
最后点击确定即可
(4)删除HomePage
页面,在【页面管理】中右击要删除的页面,并点击【删除】
(5)设置AddBleDevice
为主页面,在【页面管理】中单击要删除的页面,并在右侧的属性编辑器中设置页面路由为
/
四、页面设计
AddBleDevice页面设计
效果图
实现流程
1. 在【页面管理】中单击
AddBleDevice
页面,在右侧的属性编辑器中配置页面描述和功能详情,内容如下
名称 | 内容 |
页面描述 | 整个页面的布局可以是垂直分区的,上半部分是设备扫描区,下半部分是设备列表区。 |
功能详情 | 1. 在页面初始化时,会依次执行以下操作 (1)监听蓝牙扫描状态,接收到状态变化后重新构建页面 (2)蓝牙扫描结果监听,接收到扫描结果后进行存储并重新构建页面 (3)开始蓝牙扫描,扫描时长8秒 2. 连接设备,在设备列表中选择设备进行连接,连接成功后跳转到数据收发页面 3. 重新扫描,蓝牙扫描结束后,点击【重新扫描】开始扫描,此时会断开已连接的蓝牙设备 |
2. 在【页面管理】中单击
AddBleDevice
页面,在右侧的属性编辑器中添加页面变量
需要定义的变量如下
变量名称 | 变量类型 | 是否为数组 | 默认值 | 变量描述 |
---|---|---|---|---|
devices | Map | 是 | 设备原始数据列表,用来去重 | |
scaning | Bool | 否 | false | 蓝牙扫描状态 true 正在扫描 false 未扫描 |
deviceList | Map | 是 | 页面显示的设备列表 |
操作成功如下
3. 添加页面初始化动作,在右侧的属性编辑器中点击【动作】> 【打开】
在操作流程编辑器中,页面初始化
事件下点击+
号添加事件,再点击+
号添加动作,信息如下
-
动作类型 --【自定义代码块】,添加customCode1自定义代码块并选择
customCode1内容如下
void function() {// 控制雷达扫描的动画 waterRippleController = AnimationController(vsync: this,duration: const Duration(seconds: 2),);radarViewController = AnimationController(vsync: this,duration: const Duration(seconds: 5),);// 蓝牙扫描结果处理 ble.onScanResults(callbackLast: (event) {String name = event.advertisementData.advName;// 设备名称过滤 String DEVICE_NAME = StorageUtil().read('DEVICE_NAME') ?? '';if ((DEVICE_NAME.isNotEmpty &&(name == '' || !name.contains(DEVICE_NAME))) ||devices.contains(event)) {return;}// 去重操作,防止重复设备添加 devices.add(event);if (mounted) {setState(() {// 添加至设备列表 deviceList.add({"name": event.device.platformName,"rssi": event.rssi,"mac": "mac","raw": event});});}});// 扫描状态处理 ble.isScaning((event) {if (mounted) {setState(() {scaning = event;});if (event) {waterRippleController?.repeat();radarViewController?.repeat();} else {waterRippleController?.stop();radarViewController?.stop();}}});// 开始扫描 ble.status(timeout: const Duration(seconds: 8));}
操作成功如下
4. 开启顶部导航栏,点击页面编辑窗口右上角的【顶部导航栏】并开启,配置顶部导航栏背景色为
#FF006FFF
(1)从【小部件面板】> 【常用元素】中选择【
文本小部件
】拖入到顶部导航栏中间位置中,然后在右侧的属性编辑器中配置属性,属性信息如下:
属性名称 | 属性内容 |
---|---|
文本内容 | 蓝牙连接 |
文本颜色 | #FFFFFFFF |
文本大小 | 18 |
(2)从【小部件面板】> 【常用元素】中选择【
按钮小部件
】拖入到顶部导航栏右侧位置中,然后在右侧的属性编辑器中配置属性,属性信息如下:
属性名称 | 属性内容 |
---|---|
宽 | 40 |
高 | 40 |
背景颜色 | #00C8C8C8 |
阴影大小 | 0 |
(3)按钮打开动作流程编辑器,单击
事件下点击+
号添加事件,再点击+
号添加动作,信息如下
-
动作类型 --【导航】,设置导航到
SetBleName
页面
(4)从【小部件面板】> 【基本元素】中选择【
图标小部件
】拖入到【按钮小部件
】中,然后在右侧的属性编辑器中配置属性,属性信息如下:
属性名称 | 属性内容 |
---|---|
图标 | setting |
大小 | 24 |
颜色 | #FFFFFFFF |
5. 页面内容设计
(1)从【小部件面板】> 【常用元素】中选择【
容器小部件
】拖入到页面编辑窗口内的上下布局中,然后在右侧的属性编辑器中配置属性,属性信息如下:
属性名称 | 属性内容 |
---|---|
宽 | 80 |
高 | 20 |
颜色 | #00C8C8C8 |
(2)从【小部件面板】> 【基本元素】中选择【
雷达小部件
】拖入到页面编辑窗口内的上下布局中,然后在右侧的属性编辑器中配置属性,属性信息如下:
属性名称 | 属性内容 |
---|---|
变量绑定 | deviceList |
宽 | 320 |
高 | 320 |
雷达指针 | true |
指针颜色 | #FF00478D |
背景渐变 | true |
渐变类型 | 放射性渐变 |
过渡点 |
|
渐变中心 | 0,0 |
渐变半径 | 0.5 |
水波纹个数 | 3 |
水波纹颜色 | #1CE6ECEC |
水波纹是否填充 | true |
点的大小 | 15 |
点的颜色 | #FF3B35B7 |
操作成功如下
(3)再次从【小部件面板】> 【常用元素】中选择【
容器小部件
】拖入到页面编辑窗口内的上下布局中,然后在右侧的属性编辑器中配置属性,属性信息如下:
属性名称 | 属性内容 |
---|---|
宽 | 无限大 |
高 | 40 |
颜色 | #00C8C8C8 |
(4)从【小部件面板】> 【基本元素】中选择 【
条件生成器小部件
】拖入到容器小部件中,然后在右侧的属性编辑器中选择变量scaning
(5)条件 scaning = false
,勾选展示此界面
,从【小部件面板】> 【常用元素】中选择【
按钮小部件
】拖入到【条件生成器小部件
】中,然后在右侧的属性编辑器中配置属性,属性信息如下:
属性名称 | 属性内容 |
---|---|
宽 | 120 |
高 | 40 |
颜色 | #00C8C8C8 |
阴影大小 | 0 |
(6)按钮动作面板中打开动作流程编辑器,单击
事件下点击+
号添加事件,再点击+
号添加动作,信息如下
-
动作类型 --【自定义代码块】,添加customCode2自定义代码块并选择
customCode2内容如下
void function() async {EasyLoading.dismiss();if (mounted) {// 断开蓝牙 await ble.disconnect();setState(() {// 清空设备列表devices.clear();});// 重新扫描设备 ble.status(timeout: const Duration(seconds: 8));}
}
(7)从【小部件面板】> 【常用元素】中选择【
文本小部件
】拖入到【按钮小部件
】中,然后在右侧的属性编辑器中配置属性,属性信息如下:
属性名称 | 属性内容 |
---|---|
文本内容 | 重新扫描 |
字体颜色 | #FF006FFF |
字体大小 | 18 |
字体粗细 | 500 |
(8)条件 scaning = true
,勾选展示此界面
,从【小部件面板】> 【常用元素】中选择【
文本小部件
】拖入到【条件生成器小部件
】中,然后在右侧的属性编辑器中配置属性,属性信息如下:
属性名称 | 属性内容 |
---|---|
文本内容 | 正在扫描 |
字体大小 | 18 |
字体粗细 | 500 |
操作成功如下
(9)从【小部件面板】> 【基本元素】中选择【
滚动条小部件
】拖入到页面编辑窗口内的上下布局中
(10)从【小部件面板】> 【布局元素】中选择【
列表布局小部件
】拖入到【滚动条小部件
】中
属性名称 | 属性内容 |
---|---|
绑定变量 | deviceList |
宽 | 340 |
高 | 350 |
操作成功如下
(11)从【小部件面板】> 【常用元素】中选择【
容器小部件
】拖入到【列表布局小部件
】中,然后在右侧的属性编辑器中配置属性,属性信息如下:
属性名称 | 属性内容 |
---|---|
宽 | 无限大 |
高 | 80 |
背景颜色 | #FFFFFFFF |
圆角 | 10 |
内边距 | 10 |
外边距 | 上:10 下:10 |
(12)从【小部件面板】> 【常用元素】中选择【
左右布局小部件
】拖入到【容器小部件
】中
(13)从【小部件面板】> 【常用元素】中选择【
上下布局小部件
】拖入到【左右布局小部件
】中
从【小部件面板】> 【常用元素】中选择【
容器小部件
】拖入到【上下布局小部件
】中,然后在右侧的属性编辑器中配置属性,属性信息如下:
属性名称 | 属性内容 |
---|---|
宽 | 120 |
高 | 20 |
背景颜色 | #00C8C8C8 |
从【小部件面板】> 【常用元素】中选择【
文本小部件
】拖入到【容器小部件
】中,然后在右侧的属性编辑器中配置属性,属性信息如下:
属性名称 | 属性内容 |
---|---|
文本内容 | ${deviceList[index]["name"] == '' ? '未知' : deviceList[index["name"]} |
字体大小 | 16 |
字体粗细 | 700 |
从【小部件面板】> 【常用元素】中选择【
容器小部件
】拖入到【上下布局小部件
】中,然后在右侧的属性编辑器中配置属性,属性信息如下:
属性名称 | 属性内容 |
---|---|
宽 | 260 |
高 | 20 |
背景颜色 | #00C8C8C8 |
从【小部件面板】>【常用元素】中选择【
文本小部件
】拖入到【容器小部件
】中,然后在右侧的属性编辑器中配置属性,属性信息如下:
属性名称 | 属性内容 |
---|---|
文本内容 | Mac: ${deviceList[index]['mac']} RSSI: ${deviceList[index]["rssi"]} |
字体颜色 | #FF999999 |
字体大小 | 14 |
字体粗细 | 500 |
(14)从【小部件面板】>【常用元素】中选择【
按钮小部件
】拖入到【左右布局小部件
】中,然后在右侧的属性编辑器中配置属性,属性信息如下:
属性名称 | 属性内容 |
---|---|
宽 | 60 |
高 | 40 |
背景颜色 | #00C8C8C8 |
阴影大小 | 0 |
(15)按钮动作面板中打开动作流程编辑器,单击
事件下点击+
号添加事件,再点击+
号添加动作,信息如下
动作类型 --【自定义代码块】,添加自定义代码块customCode3并选择
customCode3内容如下
void function(index) {if (scaning) {ble.stopScan();}EasyLoading.show();// 连接蓝牙 ble.connect(deviceList[index]['raw'].device,serviceUUID: StorageUtil().read("serviceUUID") ?? '',readCharacteristicUUID:StorageUtil().read("readCharacteristicUUID") ?? '',writeCharacteristicUUID:StorageUtil().read("writeCharacteristicUUID") ?? '',notifyCallBcak: () async {Map<String, dynamic> json = {"name": deviceList[index]['name'],"id": deviceList[index]['mac']};
await Get.toNamed('/DeviceNetWork', arguments: json);
EasyLoading.dismiss();});}
(16)从【小部件面板】> 【常用元素】中选择【
文本小部件
】拖入到【按钮小部件
】中,然后在右侧的属性编辑器中配置属性,属性信息如下:
属性名称 | 属性内容 |
---|---|
文本内容 | 连接 |
字体颜色 | #FF006FFF |
字体大小 | 14 |
字体粗细 | 500 |
操作成功如下
SetBleName页面设计
效果图
实现流程
1. 在【页面管理】中单击SetBleName页面,在右侧的属性编辑器中配置页面描述和功能详情,内容如下
名称 | 内容 |
页面描述 | 整个页面的布局可以是垂直分区的,从上到下依次为数据输入区(输入框),输入确认区(按钮) |
功能详情 | 1. 蓝牙名称过滤,设置BLE名称后蓝牙只搜索该名称的设备 2. 读写UUID,如果不设置蓝牙的读写UUID,则默认向所有的读写UUID发送数据和接收数据 |
2. 在【页面管理】中单击
SetBleName
页面,在右侧的属性编辑器中添加页面变量
需要定义的变量如下
变量名称 | 变量类型 | 是否为数组 | 默认值 | 变量描述 |
---|---|---|---|---|
DEVICE_NAME | String | 否 | ${StorageUtil().read("DEVICE_NAME") ?? ''} | 设备名称 |
serviceUUID | String | 否 | 服务UUID | |
readCharacteristicUUID | String | 否 | 读特征UUID | |
writeCharacteristicUUID | String | 否 | 写特征UUID |
操作成功如下
2. 开启顶部导航栏
(1)点击页面编辑窗口右上角的【顶部导航栏】并开启,配置顶部导航栏背景色为
#FF006FFF
(2)从【小部件面板】> 【常用元素】中选择【
文本小部件
】拖入到顶部导航栏中间位置中,然后在右侧的属性编辑器中配置属性,属性信息如下:
属性名称 | 属性内容 |
---|---|
文本内容 | 设置 |
文本颜色 | #FFFFFFFF |
文本大小 | 18 |
3. 页面内容设计
(1)从【小部件面板】> 【常用元素】中选择【
容器小部件
】拖入到页面编辑窗口内的上下布局中,然后在右侧的属性编辑器中配置属性,属性信息如下:
属性名称 | 属性内容 |
---|---|
宽 | 无限大 |
高 | 600 |
背景颜色 | #00C8C8C8 |
内边距 | 10 |
(2)从【小部件面板】> 【常用元素】中选择【
上下布局小部件
】拖入到【容器小部件
】中
(3)从【小部件面板】> 【常用元素】中选择【
上下布局小部件
】拖入到【上下布局小部件
】中
(4)从【小部件面板】> 【常用元素】中选择【
文本小部件
】拖入到【上下布局小部件
】中,然后在右侧的属性编辑器中配置属性,属性信息如下:
属性名称 | 属性内容 |
---|---|
文本内容 | BLE名称 |
(5)从【小部件面板】> 【常用元素】中选择【
容器小部件
】拖入到【上下布局小部件
】中,然后在右侧的属性编辑器中配置属性,属性信息如下:
属性名称 | 属性内容 |
---|---|
宽 | 无限大 |
高 | 50 |
背景颜色 | #00C8C8C8 |
边框 | 位置 下 宽度 颜色 样式 |
(6)从【小部件面板】> 【表单元素】中选择【
文本输入框小部件
】拖入到【容器小部件
】中,然后在右侧的属性编辑器中配置属性,属性信息如下:
属性名称 | 属性内容 |
---|---|
绑定变量 | DEVICE_NAME |
光标颜色 | #FF006FFF |
操作成功如下
(7)复制上述上下布局小部件及其子小部件的内容,并粘贴,修改内容如下
-
文本内容
服务UUID
、读特征UUID
、写特征UUID
-
绑定变量
serviceUUID
、readCharacteristicUUID
、writeCharacteristicUUID
操作成功如下
(8)从【小部件面板】> 【常用元素】中选择【
按钮小部件
】拖入到【上下布局小部件
】中,然后在右侧的属性编辑器中配置属性,属性信息如下:
属性名称 | 属性内容 |
---|---|
宽 | 无限大 |
高 | 40 |
背景颜色 | #FF006FFF |
阴影大小 | 4 |
圆角大小 | 10 |
(9)按钮动作面板中打开动作流程编辑器,单击
事件下点击+
号添加事件,再点击+
号添加动作,信息如下
-
动作类型 --【自定义代码块】,添加customCode1自定义代码块并选择
customCode1内容如下
void function(){StorageUtil().write("DEVICE_NAME", DEVICE_NAME);
StorageUtil().write("serviceUUID", serviceUUID);StorageUtil().write("readCharacteristicUUID", readCharacteristicUUID);StorageUtil().write("writeCharacteristicUUID", writeCharacteristicUUID); EasyLoading.showSuccess("设置成功");Get.back();
}
(10)从【小部件面板】> 【常用元素】中选择【
文本小部件
】拖入到【按钮小部件
】中,然后在右侧的属性编辑器中配置属性,属性信息如下:
属性名称 | 属性内容 |
---|---|
文本内容 | 确认 |
字体颜色 | #FFFFFFFF |
字体大小 | 14 |
字体粗细 | 500 |
DeviceNetWork页面设计
效果图
实现流程
1. 在【页面管理】中单击
DeviceNetWork
页面,在右侧的属性编辑器中配置页面描述和功能详情,内容如下
名称 | 内容 |
页面描述 | 整个页面的布局可以是垂直分区的,上半部分是电动车图像,下半部分是数据指标(胎压、温度、电量)。 |
功能详情 | 1. 在页面初始化时,会依次执行以下操作 (1)蓝牙接收数据监听,接收到数据后进行存储并重新构建页面 (2)蓝牙连接状态监听,如果蓝牙断开连接,则在400ms后回到上一个页面 2. 数据指标计算,将接收到的蓝牙数据通过协议解析成数据并进行回显 |
2. 在【页面管理】中单击
DeviceNetWork
页面,在右侧的属性编辑器中添加页面变量
需要定义的变量如下
变量名称 | 变量类型 | 是否是列表 | 默认值 | 变量描述 |
---|---|---|---|---|
password | Map | 是 | 接收的数据内容 | |
isConnected | Bool | 否 | false | 连接状态 |
wifiname | String | 否 | 发送数据内容 | |
_getData | Var | 否 | 数据接收流 | |
_connectionSubscription | Var | 否 | 连接状态流 | |
disconnectTimer | Var | 否 | 断开连接定时器 | |
tirePressure | Int | 否 | 0 | 前轮的胎压值 |
tirePressure1 | Int | 否 | 0 | 后轮的胎压值 |
temperature | Double | 否 | 0 | 温度 |
voltage | Double | 否 | 0 | 电压 |
3. 添加页面初始化动作,在右侧的属性编辑器中点击【动作】> 【打开】
在操作流程编辑器中,页面初始化
事件下点击+
号添加事件,再点击+
号添加动作,信息如下
-
动作类型 --【自定义代码块】,添加customCode1自定义代码块并选择
-
动作类型 --【硬件动作】,硬件类型 --【蓝牙】,操作类型 --【接收数据】,协议配置 -- 添加协议并选择,通信协议参考:蓝牙通讯协议模板
协议配置如下
命令 | 帧头 | 帧长 | 控制命令 | 数据 | 校验 | 帧尾 |
---|---|---|---|---|---|---|
字节长度 | 1 | 1 | 1 | 9 | 1 | 1 |
案例 | 0xAA | 0xXX | 0xXX | 0xXX | 0xXX | 0x55 |
描述 | 定值 | 数据位长度+3 | 变值 | 变值 | 从0到n-1位累加校验 | 定值 |
协议解析
控制字 | 变量名称 | 表达式 | 备注 |
---|---|---|---|
01 | taiya | _protocolArr_10[3]<<8 | _protocolArr_10[4] | 前轮的胎压值 |
taiya1 | _protocolArr_10[5]<<8 | _protocolArr_10[6] | 后轮的胎压值 | |
wendufuhao | _protocolArr_10[7] | 温度符号 | |
wendu | _protocolArr_10[8]<<8 | _protocolArr_10[9] | 温度 | |
dianya | _protocolArr_10[10]<<8 | _protocolArr_10[11] | 电压 |
变量赋值
控制字 | 页面变量 | 变量名称 | 备注 |
---|---|---|---|
01 | tirePressure | taiya | 前轮的胎压值 |
tirePressure1 | taiya1 | 后轮的胎压值 | |
temperature | wendu | 温度 | |
voltage | dianya | 电压 |
customCode1内容如下
void function(){_connectionSubscription?.cancel();_connectionSubscription = ble.connectController.stream.listen((event) {if (event is BluetoothConnectionState) {if (mounted) {setState(() {switch (event) {case BluetoothConnectionState.connected:isConnected = true;break;case BluetoothConnectionState.disconnected:disconnectTimer?.cancel();disconnectTimer = Timer(const Duration(milliseconds: 400), () {if (connectStatus == BluetoothConnectionState.disconnected) {//400毫秒后还是未连接才代表断开了连接,回到以前的界面print("400毫秒后还是未连接才代表断开了连接,回到以前的界面");EasyLoading.showError("设备断开了连接");Get.offNamed('/'); }});
break;
default:}});}}});}
操作成功如下
4. 页面内容设计
(1)从【小部件面板】> 【常用元素】中选择【
容器小部件
】拖入到页面编辑窗口内的上下布局中,然后在右侧的属性编辑器中配置属性,属性信息如下:
属性名称 | 属性内容 |
---|---|
宽 | 无限大 |
高 | 820 |
背景渐变 | true |
渐变类型 | 线性渐变 |
过渡点 | 过渡点 0 颜色 #FF8CBCFA 过渡点 0.3 颜色 #FF93CEFC 过渡点 1 颜色 #FFE5E5E5 |
渐变起点 | 0,1 |
渐变终点 | 0,-1 |
(2)从【小部件面板】> 【常用元素】中选择【
上下布局小部件
】拖入到【容器小部件
】中
(3)从【小部件面板】> 【常用元素】中选择【
左右布局小部件
】拖入到【上下布局小部件
】中
(4)从【小部件面板】> 【布局元素】中选择【
按钮小部件
】拖入到【左右布局小部件
】中,然后在右侧的属性编辑器中配置属性,属性信息如下:
属性名称 | 属性内容 |
---|---|
宽 | 40 |
高 | 40 |
背景颜色 | #00FCFCFC |
阴影大小 | 0 |
圆角 | 40 |
(5)从【小部件面板】> 【常用元素】中选择【
图标小部件
】拖入到【按钮小部件
】中,然后在右侧的属性编辑器中配置属性,属性信息如下:
属性名称 | 属性内容 |
---|---|
图标 | left |
图标大小 | 24 |
图标颜色 | #FF000000 |
(6) 从【小部件面板】> 【常用元素】中选择【
容器小部件
】拖入到【上下布局小部件
】中,然后在右侧的属性编辑器中配置属性,属性信息如下:
属性名称 | 属性内容 |
---|---|
宽 | 80 |
高 | 100 |
背景颜色 | #00C8C8C8 |
(7)从【小部件面板】> 【常用元素】中选择【
图片小部件
】拖入到【上下布局小部件
】中,然后在右侧的属性编辑器中配置属性,属性信息如下:
属性名称 | 属性内容 |
---|---|
宽 | 无限大 |
高 | 200 |
Box Fit | 适应高度 |
图片来源 | 我的文件 点击 上传文件图标进行上传,图片素材链接:图片下载 |
(8)从【小部件面板】> 【表单元素】中选择【
左右布局小部件
】拖入到【上下布局小部件
】中,然后在右侧的属性编辑器中配置属性,属性信息如下:
属性名称 | 属性内容 |
---|---|
主轴对齐 | 从左往右第 5 个选项 |
(9)从【小部件面板】> 【常用元素】中选择【
文本小部件
】拖入到【左右布局小部件
】中,然后在右侧的属性编辑器中配置属性,属性信息如下:
属性名称 | 属性内容 |
---|---|
文本内容 | ${tirePressure} kPa |
(10) 从【小部件面板】> 【常用元素】中选择【
文本小部件
】拖入到【左右布局小部件
】中,然后在右侧的属性编辑器中配置属性,属性信息如下:
属性名称 | 属性内容 |
---|---|
文本内容 | ${tirePressure1} kPa |
(11) 从【小部件面板】> 【常用元素】中选择【
容器小部件
】拖入到【上下布局小部件
】中,然后在右侧的属性编辑器中配置属性,属性信息如下:
属性名称 | 属性内容 |
---|---|
宽 | 80 |
高 | 80 |
背景颜色 | #00C8C8C8 |
(12)从【小部件面板】> 【常用元素】中选择【
左右布局小部件
】拖入到【上下布局小部件
】中,然后在右侧的属性编辑器中配置属性,属性信息如下:
属性名称 | 属性内容 |
---|---|
主轴对齐 | 从左往右第 4 个选项 |
(13)从【小部件面板】> 【常用元素】中选择【
容器小部件
】拖入到【左右布局小部件
】中,然后在右侧的属性编辑器中配置属性,属性信息如下:
属性名称 | 属性内容 |
---|---|
宽 | 170 |
高 | 90 |
(14)从【小部件面板】> 【常用元素】中选择【
左右布局小部件
】拖入到【容器小部件
】中
从【小部件面板】> 【常用元素】中选择【
图片小部件
】拖入到【左右布局小部件
】中 ,然后在右侧的属性编辑器中配置属性,属性信息如下:
属性名称 | 属性内容 |
---|---|
宽 | 40 |
高 | 40 |
Box Fit | 按比例缩小 |
图片来源 | 我的文件 点击 上传文件图标进行上传,图片素材链接:图片下载 |
从【小部件面板】> 【常用元素】中选择【
文本小部件
】拖入到【左右布局小部件
】中 ,然后在右侧的属性编辑器中配置属性,属性信息如下:
属性名称 | 属性内容 |
---|---|
文本内容 | ${temperature} ℃ |
(15)从【小部件面板】> 【常用元素】中选择【
容器小部件
】拖入到【左右布局小部件
】中,然后在右侧的属性编辑器中配置属性,属性信息如下:
属性名称 | 属性内容 |
---|---|
宽 | 170 |
高 | 90 |
(16)从【小部件面板】> 【常用元素】中选择【
左右布局小部件
】拖入到【容器小部件
】中
从【小部件面板】> 【常用元素】中选择【
图片小部件
】拖入到【左右布局小部件
】中 ,然后在右侧的属性编辑器中配置属性,属性信息如下:
属性名称 | 属性内容 |
---|---|
宽 | 40 |
高 | 40 |
Box Fit | 按比例缩小 |
图片来源 | 我的文件 点击 上传文件图标进行上传,图片素材链接:图片下载 |
从【小部件面板】> 【常用元素】中选择【
文本小部件
】拖入到【左右布局小部件
】中 ,然后在右侧的属性编辑器中配置属性,属性信息如下:
属性名称 | 属性内容 |
---|---|
文本内容 | ${voltage} V |
相关文章:
低代码平台开发胎压监测APP
项目介绍 该项目是一个利用Flutter框架和蓝牙技术实现轮胎压力实时监测的应用。 主要功能如下: 用于接收蓝牙模块传输的胎压数据,并实时显示胎压值。APP对接收到的胎压数据进行处理,如单位转换、数据滤波等,然后将处理后的胎压值…...
GNOME扩展入门:日期时间
Getting Started | GNOME JavaScript 1.扩展路径 ~/.local/share/gnome-shell/extensions/ 2.新建文件夹 datetimesonichy 3.metadata.json {"uuid": "datetimesonichy","name": "datetime","description": "Dis…...
NLP高频面试题(五十二)——深度学习优化器详解
在深度学习的训练过程中,各种基于梯度的优化器肩负着寻找损失函数最优解的重任。最基础的梯度下降法通过沿着损失函数负梯度方向迭代更新参数,实现对模型参数的优化;而随机梯度下降(SGD)则以更高的计算效率和内存利用率在大规模数据集上大放异彩,但也因更新噪声大、易陷入…...
SLAM常用地图对比示例
序号地图类型概述1格栅地图将现实环境栅格化,每一个栅格用 0 和 1 分别表示空闲和占据状态,初始化为未知状态 0.52特征地图以点、线、面等几何特征来描绘周围环境,将采集的信息进行筛选和提取得到关键几何特征3拓扑地图将重要部分抽象为地图&…...
Web常见攻击方式及防御措施
一、常见Web攻击方式 1. 跨站脚本攻击(XSS) 攻击原理:攻击者向网页注入恶意脚本,在用户浏览器执行 存储型XSS:恶意脚本存储在服务器(如评论区) 反射型XSS:恶意脚本通过URL参数反射给用户 DOM型XSS&…...
java.lang.IllegalArgumentException: URI is not hierarchical报错
java.lang.IllegalArgumentException: URI is not hierarchical Thread.currentThread().getContextClassLoader("类的全路径").getClass().newInstance()一个类的静态块初始化异常了,后面调用这个类创建对象会报错吗? 是的,如果一…...
118. 杨辉三角
目录 一、问题描述 二、解题思路 三、代码 四、复杂度分析 一、问题描述 给定一个非负整数 numRows,生成「杨辉三角」的前 numRows 行。 在「杨辉三角」中,每个数是它左上方和右上方的数的和。 二、解题思路 每一行的第一个和最后一个元素是 1&…...
Anything V4/V5 模型汇总
二次元风格生成扩散模型-anything-v4.0Stable Diffusion anything-v5-PrtRE模型介绍及使用深度探索 Anything V5:安装与使用全攻略anything-v5x0.25少儿插画_v1xyn-ai/anything-v4.0...
网络原理 - 7(TCP - 4)
目录 6. 拥塞控制 7. 延时应答 8. 捎带应答 9. 面向字节流 10. 异常情况 总结: 6. 拥塞控制 虽然 TCP 有了滑动窗口这个大杀器,就能够高效可靠的发送大量的数据,但是如果在刚开始阶段就发送大量的数据,仍然可能引起大量的…...
探秘 FFmpeg 版本发展时间简史
前言 FFmpeg 是一套开源的计算机程序,主要用于记录、转换数字音频、视频,并能将其转化为流。它提供了录制、转换以及流化音视频的完整解决方案,在多媒体处理领域应用广泛。很多小伙伴们想系统的学习FFmpeg,还是有必要了解下FFmpeg的版本发展历史,感受它每次的版本迭代是如…...
5.3.1 MvvmLight以及CommunityToolkit.Mvvm介绍
MvvmLight、CommunityToolkit.Mvvm是开源包,他们为实现 MVVM(Model-View-ViewModel)模式提供了一系列实用的特性和工具,能帮助开发者更高效地构建 WPF、UWP、MAUI 等应用程序。 本文介绍如下: 一、使用(旧)的MvvmLight库 其特点如下,要继承的基类是ViewModelBase;且使用…...
PCB常见封装类型
1. 电阻、电容、电感封装 2. 二极管、三极管封 3. 排阻类器件(8脚、16脚)封装 4. SO类器件(间距有1.27、2.54mm等)封装 5. QFP类器件封装(四方扁平封装) 结构:引脚分布在封装的四个侧面&#…...
一键多环境构建——用 Hvigor 玩转 HarmonyOS Next
引言 在 HarmonyOS Next 的应用开发中,常常需要针对不同环境(测试、预发、线上)或不同签名(调试、正式)输出多个 APP/HAP 包。虽然 HarmonyOS 提供了多目标构建(Multi-Target Build)能力&#…...
SQLPandas刷题(LeetCode3451.查找无效的IP地址)
描述:LeetCode3451.查找无效的IP地址 表:logs ---------------------- | Column Name | Type | ---------------------- | log_id | int | | ip | varchar | | status_code | int | ---------------------- log_id 是这张表的唯…...
【leetcode100】组合总和Ⅳ
1、题目描述 给你一个由 不同 整数组成的数组 nums ,和一个目标整数 target 。请你从 nums 中找出并返回总和为 target 的元素组合的个数。 题目数据保证答案符合 32 位整数范围。 示例 1: 输入:nums [1,2,3], target 4 输出࿱…...
2020-06-23 暑期学习日更计划(机器学习入门之路(资源汇总)+概率论)
机器学习入门 前言 说实话,机器学习想学好真心不易,很多时候都感觉自己学得云里雾里。以前一段时间自己为了完成毕业设计,在机器学习的理论部分并没有深究,仅仅通过TensorFlow框架力求快速实现模型。现在来看,很多时候…...
Linux操作系统--基础I/O(上)
目录 1.回顾C文件接口 stdin、stdout、stderr 2.系统文件I/O 3.接口介绍 4.open函数返回值 5.文件描述符fd 5.1 0&1&2 1.回顾C文件接口 hello.c写文件 #include<stdio.h> #include<string.h>int main() {FILE *fp fopen("myfile","…...
Spring boot 中的IOC容器对Bean的管理
Spring Boot 中 IOC 容器对 Bean 的管理,涵盖从容器启动到 Bean 的生命周期管理的全流程。 步骤 1:理解 Spring Boot 的容器启动 Spring Boot 的 IOC 容器基于 ApplicationContext,在应用启动时自动初始化。 入口类:通过 SpringB…...
ARINC818协议一些说明综述
关键术语 航空总线技术 光纤通道层次架构 光纤通道拓扑结构 FC-AV协议,架构,容器系统 ARINC818协议,容器 ADVB帧映射,帧格式 机载视频处理系统对视频数据进行实时处理和记录。 分辨率:1080p,4k,8k视频技术 FC-AV技术是…...
Turso:一个基于 libSQL的分布式数据库
Turso 是一个完全托管的数据库平台,支持在一个组织中创建高达数十万个数据库,并且可以复制到任何地点,包括你自己的服务器,以实现微秒级的访问延迟。你可以通过Turso CLI(命令行界面)管理群组、数据库和API…...
2025.5.4机器学习笔记:PINN文献阅读
2025.5.4周报 文献阅读题目信息摘要创新点网络架构实验结论不足以及展望 文献阅读 题目信息 题目: Physics-Informed Neural Network Approach for Solving the One-Dimensional Unsteady Shallow-Water Equations in Riverine Systems期刊: Journal o…...
一行命令打开iOS模拟器
要在 Mac 命令行打开 iPhone 15 Pro 模拟器,需满足已安装 Xcode 这一前提条件,以下是具体操作步骤: 步骤一:列出所有可用模拟器设备 打开终端(Terminal),输入并执行以下命令,用于列…...
java面向对象编程【基础篇】之基础语法
目录 🚀前言🌟构造器💯案例 🤔this关键字💯使用this调用本类中的属性💯使用this调用构造器💯this表示当前对象 🦜封装💯合理隐藏💯合理暴露 🐧实体…...
跑MPS产生委外采购申请(成品)
问题:跑MPS产生委外采购申请(成品),更改BOM和跑MRP,但物料需求清单中无新增物料复合膜的需求。截图如下: 解决方法:更改委外采购申请的批准日期为BOM的生效日和重新展开bom。 重新展开后&#x…...
[flutter]切换国内源(window)
如题,切换到国内源避免总是连不上google导致卡住的问题。 临时切换到国内: cmd set PUB_HOSTED_URLhttps://pub.flutter-io.cn set FLUTTER_STORAGE_BASE_URLhttps://storage.flutter-io.cnpower shell $env:PUB_HOSTED_URL "https://pub.flut…...
学习海康VisionMaster之顶点检测
一:进一步学习了 今天学习下VisionMaster中的顶点检测:可检测图像指定区域内的顶点,并输出顶点坐标等信息。该模块常用于检测目标物体的顶点 二:开始学习 1:什么是顶点检测? 一个不是很规则的物体需要检测…...
Vue2中常用的核心函数(选项和生命周期钩子)的完整示例及总结
以下是Vue2中常用的核心函数(选项和生命周期钩子)的完整示例及总结: 1. 实例选项函数 data 初始化组件数据 new Vue({el: #app,data() {return {message: Hello Vue!};} });methods 定义组件方法 new Vue({el: #app,data() {return { c…...
数据集-目标检测系列- F35 战斗机 检测数据集 F35 plane >> DataBall
数据集-目标检测系列- F35 战斗机 检测数据集 F35 plane >> DataBall DataBall 助力快速掌握数据集的信息和使用方式。 贵在坚持! * 相关项目 1)数据集可视化项目:gitcode: https://gitcode.com/DataBall/DataBall-detections-100s…...
2025年3月AGI技术月评|技术突破重构数字世界底层逻辑
〔更多精彩AI内容,尽在 「魔方AI空间」 ,引领AIGC科技时代〕 本文作者:猫先生 ——当「无限照片」遇上「可控试穿」,我们正在见证怎样的智能革命? 被低估的进化:开源力量改写游戏规则 当巨头们在AGI赛道…...
【k8s】k8s是怎么实现自动扩缩的
Kubernetes 提供了多种自动扩缩容机制,主要包括 Pod 水平自动扩缩(HPA)、垂直 Pod 自动扩缩(VPA) 和 集群自动扩缩(Cluster Autoscaler)。以下是它们的实现原理和配置方法: 1. Pod …...
协作开发攻略:Git全面使用指南 — 引言
协作开发攻略:Git全面使用指南 — 引言 Git 是一种分布式版本控制系统,用于跟踪文件和目录的变更。它能帮助开发者有效管理代码版本,支持多人协作开发,方便代码合并与冲突解决,广泛应用于软件开发领域。 文中内容仅限技…...
【AI提示词】私人教练
提示说明 以专业且细致的方式帮助客户实现健康与健身目标,提升整体生活质量。 提示词 # Role: 私人教练## Profile - language: 中文 - description: 以专业且细致的方式帮助客户实现健康与健身目标,提升整体生活质量 - background: 具备丰富的健身经…...
【星海出品】Calico研究汇总
Calico项目由Tigera公司发起并主导开发 源码 https://github.com/projectcalico/calico?tabreadme-ov-file#-join-the-calico-community 简介 Tigera是一家专注于云原生安全的公司,于2016年成立,其核心产品包括开源的Calico项目以及商业版的Calico Ent…...
观成科技:摩诃草组织Spyder下载器流量特征分析
一、概述 自2023年以来,摩诃草组织频繁使用Spyder下载器下载远控木马,例如Remcos。观成安全研究团队对近几年的Spyder样本进行了深入研究,发现不同版本的样本在数据加密、流量模式等方面存在差异。基于此,我们对多个版本样本的通…...
中心极限定理(CLT)习题集 · 题目篇
中心极限定理(CLT)习题集 题目篇 共 18 题,覆盖经典 CLT、Lyapunov/Lindeberg 条件、Berry–Esseen 评估、 以及工程/数据科学应用与编程仿真。推荐先独立完成,再看《答案与解析篇》。 之前已经出过相关的知识点文章,…...
ITL和TTL线程间值的传递
InheritableThreadLocal InheritableThreadLocal 继承自 ThreadLocal,增加了父线程到子线程的值传递功能。当一个新线程被创建时,InheritableThreadLocal 会将父线程中 ThreadLocal 变量的值拷贝到子线程(浅拷贝),子线…...
Android学习总结之Room篇
一、Room 框架基础 1. 实体类(Entity) 实体类用于描述数据库表的结构。通过使用 Entity 注解,可以将一个 Java 类映射到数据库中的一张表。例如,以下是一个简单的 User 实体类: import androidx.room.Entity; impor…...
java IO流
一:概述 (1)IO (2)流 二:分类 (1)流向 (2)数据单位 (3)IO流角色 三:API (1)InputStream ÿ…...
STM32 串口USART
目录 常见的通信方式 串行通信和并行通信 全双工,半双工和单工通信 同步通信和异步通信 通信速率 常见的通信协议 串口基础知识 电平特性 串口传输协议 STM32F103的USART资源 端口引脚 数据寄存器单元 发送接收控制单元 实现串口发送 printf…...
数字IC后端项目典型问题之后端实战项目问题记录(2025.04.24)
今天给大家分享下近两天小编帮助学员解决的几个经典后端项目问题。希望能够对大家的学习和工作有所帮助。 Q1:在做a7top顶层物理验证Calibre LVS检查时提示NOT COMPARED,请问是什么原因? 我们在用calibre检查LVS后,其结果基本上就是以下三种…...
关于边缘计算盒子的外部接口保护
边缘计算盒子是一种基于边缘计算和人工智能技术的智能设备,它内置了灵活可配的多样化AI算法库,所以也被称为AI算法盒子或智能边缘分析一体机,可以将数据处理和分析的能力推至离数据源最近的边缘位置,提供高效的数据处理和实时响应…...
OCP考试需要注意什么?
一、OCP考试需要准备的资料 身份证件:携带有效的身份证件(如身份证、护照等),以便在考试当天进行身份验证。确保身份证件在考试当天仍然有效,并且与报名时使用的证件一致。 准考证:打印并携带准考证&…...
git Http改用户下载
用原先别人账号,无权下更新 http方式设置自己账号 例如 git fetch --all 提示没有权限从 http://192.168.1.2/gitlab/项目路径.git下载 git remote set-url origin http://your-username192.168.1.2/gitlab/项目路径.git your-username修改成自己的git账号 需要输入一个Tok…...
postgres 导出导入(基于数据库,模式,表)
在 PostgreSQL 中,导出和导入数据库、模式(schema)或表的数据可以使用多种工具和方法。以下是常用的命令和步骤,分别介绍如何导出和导入整个数据库、特定的模式以及单个表的数据。 一、导出数据 1. 使用 pg_dump 导出整个数据库…...
把dll模块注入到游戏进程的方法_挂起进程注入
一. 概述 挂起进程注入是指在创建进程的时候把运行状态设置为挂起,然后创建一个远程线程,来注入。挂起进程注入作为远线程注入的一个补充,可以在进程创建的时候就注入,从而注入时间较早,不宜被拦截。易知挂起进程注入的局限性也就是如果进程已经启动,那么这种注入方式就…...
TypeScript 开发实战:如何安全替换字符串中的关键字
在 TypeScript 开发中,我们经常需要处理字符串替换的场景。最近我在开发一个表达式解析功能时,遇到了一个有趣的挑战:如何将用户输入的简化数学表达式(如"sin")替换为标准形式(如"Math.sin&…...
ES6 模块化 与 CommonJS 的核心概念解析
以下是关于 ES6 模块化 与 CommonJS 的核心概念解析、知识点总结及使用场景说明: 1. ES6 模块化与 CommonJS 是什么? ES6 模块化(ECMAScript Modules, ESM) 定义:ES6 标准引入的模块系统,使用 import 和 …...
【踩坑记录】stm32 jlink程序烧录不进去
最近通过Jlink给STM32烧写程序时一直报错,但是换一个其他工程就可以烧录,对比了一下jink配置,发现是速率选太高了“SW Device”,将烧录速率调整到10MHz以下就可以了...
CS144 Lab 6 实战记录:构建 IP 路由器
1 实验背景与目标 在 CS144 的 Lab 6 中,我们需要在之前实现的 NetworkInterface(Lab 5)基础上构建一个完整的 IP 路由器。路由器的主要任务是根据路由表将接收到的 IP 数据报转发到正确的网络接口,并发送给正确的下一跳…...
AI与智能能源管理:如何通过AI优化能源分配和消耗?
引言:能源管理面临的新挑战 在“双碳”目标持续推进的背景下,能源管理已经不再是简单的节电节水问题,而是关乎可持续发展和企业长期竞争力的核心议题。无论是工业园区、写字楼,还是家庭用户,能源的使用正在变得越来越复…...