Flutter跨平台开发技术

仅分享文字,见谅

Flutter

  • Flutter 介绍
    • 功能
    • 跨平台性
    • 架构
    • 流行度
    • Flutter vs React Native
  • 配置 Windows Flutter App 环境
  • 配置 Tizen Flutter App 环境
  • 用 Dart 语言开发 Flutter App
  • Flutter-Tizen 的限制

Flutter 介绍

Flutter 是由 Google 推出的开源移动应用开发框架,可用于快速构建高性能、美观的移动应用程序。它采用 Dart 语言进行开发,具有热重载功能,可以快速查看代码更改后的效果,极大地提高了开发效率

Flutter 的 UI 框架采用了现代化的响应式编程风格,可以轻松地创建漂亮且高度定制化的用户界面。它还提供了丰富的组件库,开发者可以根据自己的需求选择合适的组件来构建应用程序

Flutter 还支持跨平台开发,开发者可以使用同一套代码 base 开发 iOS 和 Android 应用,大大减少了开发成本和时间。同时,Flutter 还提供了丰富的工具和插件,帮助开发者更好地调试和优化应用程序

Flutter 的跨平台性

Flutter 支持移动端 (iOS, Android), Web 端,桌面端 (Windows, macOS, Linux) 和嵌入式 App 的开发,所有平台共用一套代码库,大大降低开发和维护成本

通过 Flutter-Tizen 工具 (https://github.com/flutter-tizen/flutter-tizen),也可在 Tizen 设备上运行 Flutter App

Flutter 架构

Flutter 的架构主要分为三层:框架层、引擎层和平台层

  • 框架层(Framework Layer):框架层是 Flutter 的核心,包括了大量的 UI 组件、渲染、布局和手势等功能。开发者可以通过使用框架提供的组件和 API 来构建用户界面。框架层采用了现代化的响应式编程风格,可以快速地响应用户输入和数据变化

  • 引擎层(Engine Layer):引擎层是 Flutter 的底层渲染引擎,负责处理 UI 渲染、输入事件处理、动画和布局等底层操作。引擎层使用 C++编写,包括 Skia 图形库、Dart 运行时和平台相关的代码

  • 平台层(Platform Layer):平台层是 Flutter 与操作系统交互的部分,包括了与 Android 和 iOS 平台的通信、访问硬件功能和系统服务等。平台层负责将 Flutter 应用程序与底层系统进行交互,使应用程序能够在不同平台上运行

使用 Flutter 开发的应用

Flutter 作为一种跨平台移动应用开发框架,受到越来越多公司的青睐。较为知名的应用有:阿里巴巴的闲鱼,淘宝特价版,盒马,UC 浏览器,字节跳动的今日头条,西瓜视频,抖音火山版等

Flutter vs React Native

作为两款流行的跨平台应用开发框架,Flutter 和 React Native 的理念有许多相似之处,Flutter 的很多设计灵感来自 React:

  1. 组件化开发
    1. Flutter 的 Widget,React Native 的 Component,都支持组件化开发
  2. UI = f(State)
    1. Flutter 和 React Native 都采用了响应式 UI 的设计思想,由数据变化(State)驱动页面渲染更新
  3. Diff 算法
    1. 二者都使用 Diff 算法,逐层比对 Element 树的节点,标记更新
  4. 生命周期
    1. 二者的生命周期函数都是围绕着组件的创建,更新,销毁

Flutter 和 React Native 的不同:

  1. 语言
    1. Flutter 使用 Dart 语言,React Native 使用 JavaScript
  2. 性能
    1. Flutter 使用 Skia 图形引擎来渲染用户界面,而 React Native 使用原生控件来渲染用户界面,因此在 Flutter 性能方面表现更好
  3. 生态系统
    1. React Native 已经存在更长时间,因此有更大的生态系统和更多的第三方库和插件可供开发人员使用。Flutter 相对较新,但也在迅速发展,拥有一个活跃的社区和不断增长的生态系统

从流行程度上看,Flutter 略胜一筹

Github:

Google Trends(蓝线是 Flutter、红线是 React Native):

配置 Windows Flutter App 环境

  • 配置代理和镜像源
  • 安装 Flutter SDK
  • 使用 VSCode 作为开发工具进行调试
  • 常用 Flutter 命令

配置代理和镜像源

配置以下环境变量

变量解释
FLUTTER_STORAGE_BASE_URLhttps://storage.flutter-io.cn下载包的地址
PUB_HOSTED_URLhttps://pub.flutter-io.cn发布包的地址
HTTP_PROXYhttp://109.123.97.11:8080/
HTTPS_PROXYhttp://109.123.97.11:8080/
NO_PROXYlocalhost,127.0.0.1,::1用于本地调试

安装 Flutter SDK

  1. 下载 Flutter SDK 包
    https://storage.googleapis.com/flutter_infra_release/releases/stable/windows/flutter_windows_3.19.1-stable.zip

  2. 将 SDK 解压到准备放置 SDK 的路径下,如 D:\FlutterSDK

  3. 将 Flutter SDK 的 bin 文件夹添加到 Path

使用 VSCode 作为开发工具进行调试

安装以下两个扩展:

  1. Flutter

    Flutter 扩展用于创建、编辑、debug、运行 Flutter app

  2. Dart

    Dart 扩展为 Dart 编程语言提供支持

  1. Ctrl + Shift + P,选择 Flutter: New Project

  2. 选择模板为 Flutter Application

  3. 在文件资源管理器中选择一个空文件夹作为新项目的路径

  4. 设置 Project Name

  1. 按下 Enter,等待片刻后,将创建新的 Flutter App

    • 其中,最需要关注的是 lib\main.dart,这是 Flutter App 的入口文件

    • 入口函数:

    void main() {
       runApp(const MyApp());
    }
    
  2. 安装依赖包

    flutter pub get
    
  1. 按下 F5,等待 build 出 .exe 文件并开始 debug

常用 Flutter 命令

  • 检查已安装的工具并列出所有连接的设备
    • flutter doctor -v
    • flutter devices
  • 创建新的 Flutter 项目
    • flutter create 项目名称
  • 构建项目并在目标设备上运行
    • Debug 模式:flutter run
    • Release 模式:flutter run --release
  • Build Release 版本的包
    • flutter build windows,生成的包在 \build\windows\x64\runner\Release,只有单独的 .exe 文件无法运行,需要同级目录下的 .dll 文件和 data 文件夹
    • 其他平台可将 windows 替换为 apkios

配置 Tizen Flutter App 环境

  • 安装 Tizen SDK
  • 安装 Flutter-Tizen 工具
  • 调试 Flutter-Tizen 项目

安装 Tizen SDK

  1. 打开 https://developer.tizen.org/development/tizen-studio/download ,下载 Tizen Studio 5.5 with CLI(command line interface) installer

  2. 将 Tizen SDK 解压到准备放置 SDK 的路径下,如 D:\tizen-studio-cli

  3. 将 Tizen SDK 的 tools 文件夹添加到 Path

安装 Flutter-Tizen 工具

  1. 在希望安装 Flutter-Tizen 工具的位置执行:
    git clone https://github.com/flutter-tizen/flutter-tizen.git
  1. 将 flutter-tizen 的 bin 文件夹添加到 path

  2. 运行 flutter-tizen doctor -v,自动化检查、安装、配置环境

在 Tizen 上调试 Flutter 项目

  1. 创建 Tizen Flutter 项目

    flutter-tizen create ./my_first_app
    
  2. 通过 VS Code 打开项目文件夹

  3. 下载依赖包

    flutter pub get
    
  1. 通过 SDB 连接 TV

    sdb connect TV的IP
    

    Note:如果出现类似 failed to connect to remote target 'TV 的 IP' 等报错,需要重新配置 Tizen 开发选项:

    buxton2ctl set-int32 system db/sdk/develop/mode 1
    buxton2ctl set-string system db/sdk/develop/ip PC的IP
    sync
    systemctl start sdbd
    systemctl daemon-reload
    
  1. 在 VS Code 中,按下 Ctrl 和 ` 键调出控制台,输入以下命令,编出 Debug 包,传输到目标电视并 Launch 起来

    flutter-tizen run
    

  1. 稍等片刻,App 将在目标电视将以 debug 模式启动

  2. 待 App 启动后,在 VS Code 的侧栏中选择运行与调试 Tab,点击 flutter-tizen: Attach

    Note:如果找不到 flutter-tizen:Attach,可能是 App 没有成功启动,或者在 VS Code 中打开的文件夹不是项目文件夹。

  1. 在 VS Code 中进行调试

常用 Flutter-Tizen 命令

  • 检查已安装的工具并列出所有连接的设备
    • flutter-tizen doctor -v
    • flutter-tizen devices
  • 创建新的 Flutter-Tizen 项目,或者为已存在的项目添加 Tizen 文件
    • flutter-tizen create 项目名称
  • 构建项目并在 Tizen 设备上运行
    • Debug 模式:flutter-tizen run
    • Release 模式:flutter-tizen run --release
  • Build Release 版本的 tpk 包
    • flutter-tizen build tpk -ptv,生成的包在 \build\tizen\tpk 文件夹下

用 Dart 语言开发 Flutter App

  • Dart 语言介绍
  • 用 Dart 语言编写组件
  • 定义组件样式
  • 动画
  • 网络通信
  • 播放媒体
  • 使用 Flutter Inspector 工具进行调试

Dart 语言介绍

Flutter App 使用 Dart 语言进行开发。Dart 语言具有以下特点:

  • Object-oriented programming:Dart 支持 OOP 的概念,包括类、继承、多态、封装等
  • Functional programming:Dart 支持函数式编程的概念,包括高阶函数、闭包、柯里化等
  • Asynchronous programming:Dart 提供了异步编程的支持,使用 async 和 await 关键字可以轻松实现异步编程

用 Dart 语言编写组件

Flutter 有两种类型的 Widget,StatelessWidget 和 StatefulWidget

StatelessWidget(无状态组件)指不含 State,创建后不再更新的 Widget,通常用于展示静态内容,例如文本、图像或图标等

class MyStatelessWidget extends StatelessWidget {
  // build() 类似于 React 中的 render(),构建页面,描述页面的结构
  @override
  Widget build(BuildContext context) {
    return const Text('I am StatelessWidget');
  }
}

使用时,可在前面加入 const,提示 Flutter 框架此组件及其子组件无需刷新

Widget build(BuildContext context) {
  return const MyStatelessWidget();
}

StatefulWidget(有状态组件)则包含 State,是一种可变的 Widget,其状态可以随用户交互或其他因素而改变

一个 StatefulWidget 一般需要两个类,一个继承自 StatefulWidget,负责创建 State 对象;一个继承 State,负责管理 Widget 的状态。以 Flutter 项目默认 App 为例:

class MyHomePage extends StatefulWidget {
  // title 由父组件传递,类似于 React 中的 Prop
  // 标记为 final,也是和 React Prop Immutable 的性质同理
  final String title;

// 构造函数,required 代表父组件必须传递 title 这个参数
const MyHomePage({super.key, required this.title});

// 创建 State 对象,重载 createState 为 () => _MyHomePageState();
@override
State<MyHomePage> createState() => _MyHomePageState();
}

State 类。注意 build() 在 State 类中,而非 StatefulWidget 类中:

class _MyHomePageState extends State<MyHomePage> {
  // _counter 类似于 React 中的 state
  // 下划线代表 counter 为私有属性
  int _counter = 0;

// 更新 State 的函数
void _incrementCounter() {
// 调用 setState() 会告诉 Flutter 框架该状态发生了变化,从而重新运行下面的 build(),显
// 示更新后的值。如果直接更新 _counter 而没有调用 setState(),则不会重新构建
setState(() { _counter++; });
}

@override
Widget build(BuildContext context) {
return
}
}

@override
Widget build(BuildContext context) {
  return Scaffold(                             // 页面结构脚手架
    appBar: AppBar(                            // 标题栏
      backgroundColor: Theme.of(context).colorScheme.inversePrimary,
      title: Text(widget.title),
    ),
    body: Center(                              // 主要内容
      child: Column(
        children: <Widget>[
          const Text('You have pushed the button this many times:'),
          Text('$_counter'),
        ],
      ),
    ),
    floatingActionButton: FloatingActionButton( // 悬浮在页面右下角的按钮
      onPressed: _incrementCounter,
      tooltip: 'Increment',
      child: const Icon(Icons.add),
    ),
  );
}

定义组件样式

组件的样式通过传入的参数进行设定,以 Container 为例

child: Container(
  width: 300,
  height: 300,
  decoration: BoxDecoration(            // 装饰器
    gradient: const LinearGradient(     // 渐变色
      begin: Alignment.bottomLeft,
      end: Alignment.topRight,
      colors: [Colors.purple, Colors.blue],
      stops: [0.5, 0.7],
    ),
    // 阴影
    boxShadow: const [BoxShadow(spreadRadius: 25, blurRadius: 25)],
    // 圆角
    borderRadius: BorderRadius.circular(20),
  ),
),

动画

简单的动画可以使用 Flutter 封装的 AnimatedXXX 类来实现。如希望 Container 做出动画效果,对应使用 AnimatedContainer 类

child: AnimatedContainer(
  duration: const Duration(milliseconds: 1000), // 单次动画的时间
  width: 300,
  height: _height,
  color: Colors.blue,
),

通过修改 _height 的值,触发动画。如将某按钮绑定 setState(() {_height = _height + 100;}) 事件,则每点击一次按钮,Container 的高度将用一秒钟的时间缓慢增加 100

若涉及到循环重播、随时中断、多方协调等较复杂的动画,需使用 AnimatedBuilder 等进行手动控制,这里不作展开

网络通信

Flutter 中进行网络通信通常使用 http、https 等网络请求库来实现,以 http 为例:

  1. 在项目的 pubspec.yaml 文件中加入 http 依赖:
dependencies:
  flutter:
    sdk: flutter
  http: ^1.2.0
  1. 在需要进行网络通信的 Dart 文件中引入 http 库和 convert 库。其中 convert 库是 Flutter 的一个标准库,用于在不同数据类型之间进行转换:
import 'package:http/http.dart' as http;
import 'dart:convert';
  1. 编写代码来发起 GET 请求并处理响应的数据:
  fetchData() async {
    // 发起请求
    final response = await http.get(Uri.parse(
        'https://homescreenmiscstg.samsungqbe.cn/homescreen/service/v1/weather'
        '?position=江苏-南京-南京&countrycode=CN&modelid=22_PONTUSM_QTV&vdlangc'
        'ode=zh_CN&duid=OU4ZNAX3AKJZX'));
<span class="hljs-keyword">if</span> (response.statusCode == <span class="hljs-number">200</span>) { <span class="hljs-comment">// 请求成功</span>
  <span class="hljs-comment">// 对响应结果进行解码</span>
  <span class="hljs-built_in">Map</span>&lt;<span class="hljs-built_in">String</span>, <span class="hljs-built_in">dynamic</span>&gt; data = json.decode(utf8.decode(response.bodyBytes));

  setState(() {
    text = data.toString();
  });
} <span class="hljs-keyword">else</span> {                          <span class="hljs-comment">// 请求失败</span>
  setState(() {
    text = <span class="hljs-string">&#x27;Failed to fetch data&#x27;</span>;
  });
}

}

播放媒体

图片

使用 Image 组件显示图片

child: Image.network(
  imageUrl,
  width: 1500,
  height: 800,
),

视频

Flutter 框架默认不提供视频播放功能,因此需要引入 video_player 插件

然而,官方开发的视频播放器插件 video_player 不支持 Windows Desktop,为了在 Windows 平台上播放视频,还需引入 video_player 插件的衍生版本 video_player_win

  1. 在项目的 pubspec.yaml 文件中加入 video_player 和 video_player_win:
dependencies:
  flutter:
    sdk: flutter
  video_player: ^2.5.1
  video_player_win: ^2.0.0 # 二者需同时引入
  1. 创建 VideoPlayer 的控制器,并在组件初始化时对此 controller 进行初始化,加载网络媒体资源
final VideoPlayerController _controller = VideoPlayerController.network(videoUrl);
void initState() {
  super.initState();

// video player 初始化完成后,开始播放
controller.initialize().then(() {
setState(() {
_controller.play();
});
});
}

  1. 构建 VideoPlayer 的 UI

    • 在视频数据加载完毕之前,显示圆形进度指示器
    • 在加载完毕后显示纵横比为视频比例的视频播放器
@override
Widget build(BuildContext context) {
  return _controller.value.isInitialized
      ? AspectRatio(                       // 限制比例
          aspectRatio: _controller.value.aspectRatio, // 将视频比例作为纵横比
          child: VideoPlayer(_controller),
        )
      : const CircularProgressIndicator(); // 圆形进度指示器
}

开发 Tizen App 时,则需引入 video_player 和 video_player_tizen 依赖:

dependencies:
  flutter:
    sdk: flutter
  video_player: ^2.4.2
  video_player_tizen: ^2.4.9

并在 tizen-manifest.xml 中加入以下三个 privilege,分别用于访问内部存储、外部存储和网络上的视频资源:

<privileges>
  <privilege>http://tizen.org/privilege/mediastorage</privilege>
  <privilege>http://tizen.org/privilege/externalstorage</privilege>
  <privilege>http://tizen.org/privilege/internet</privilege>
</privileges>

使用 Flutter Inspector 工具进行调试

Flutter Inspector 是一个用于调试和检查 Flutter 应用程序的强大工具。它提供了一种可视化方式来查看 Flutter widget 树、布局、颜色、边距和其他属性,帮助开发人员更好地理解应用程序的结构和外观

  1. 使用 VS Code 开始调试后,页面顶端显示以下几个图标:

    从左到右分别代表暂停,Step Over,Step Into,Step Return,Hot Reload,Restart,断开连接,打开 Inspector

  1. 点击最后一个,弹出 Widget Inspector 窗口

Flutter Widget Inspector 由三个部分组成,Widget 树,测量面板和属性面板

  • Widget 树 (Widget Tree): Widget 树以树形结构展示当前应用程序中的所有 Widget
  • 属性面板 (Widget Details Tree): 属性面板显示了选定的 Widget 的所有属性,包括大小、位置、颜色、字体等
  • 测量面板 (Layout Explorer): 测量面板显示了选定的 Widget 的实际布局情况,如大小、位置、边距等

  1. 点击左上角的 Toggle Select Widget Mode 图标 ,在选中某个 Widget 时,在 App 中高亮显示

  1. 更新代码

    child: const Icon(Icons.add),
    // 改为
    child: const Icon(Icons.search),
    
  2. 点击热重载按钮

    Flutter 的热重载是一项非常强大的功能,它允许开发者在不需要重新启动应用程序的情况下,立即查看所做的更改。热重载还会保留应用程序的当前状态,包括当前页面和用户输入,使开发者能够快速验证他们所做的更改是否正确

  3. 页面样式发生改变

Flutter-Tizen 的限制

  1. 多数 flutter 库没有对 tizen 做适配,目前确认可以使用的 plugin 如下:https://github.com/flutter-tizen/plugins?tab=readme-ov-file
  2. 已做适配的 plugin 也可能存在一些功能上难以完全覆盖需求的部分,如 video_player_tizen 不支持 VideoPlayerController.network 的 httpHeaders
  3. Tizen 开发时,使用模拟器有很多限制,如 video_player_tizen 就无法在模拟器上正常工作
  4. Flutter-Tizen 没有主流开发工具的社区氛围,只依赖于 Samsung Research 维护和解答,当遇到问题时,解决途径比较狭窄

性能比较

分别用 Flutter 和 C# 实现计数器 App(包含一个按钮和一行文本,文本记录已按按钮的次数,每点按一次按钮数字加一),性能数据如下:

维度FlutterC#解释
tpk 包的大小7902kB19kBFlutter 除了应用程序本身外,还需包含 Flutter 框架,导致 Flutter 应用程序的包比传统 Tizen App 大
CPU 占用率(按按钮时)5.6%1.6%Flutter 框架需要更多的计算资源来渲染复杂的 UI 和处理用户交互,虽然使用了 Diff 算法等尽量优化掉不必要的重绘,但优化本身仍要占用一定的计算资源
内存占用35,66818,261Flutter 框架会占用一定的内存空间

总结

Flutter 是谷歌开发的一款开源 UI 软件开发工具包,使用 Dart 进行开发,用于从单一代码库中构建 Mobile、Web 和 DeskTop 应用程序,提供热重载、基于 Widget 的用户界面、跨平台支持。通过 Flutter 框架,可以轻松实现绘制 UI,定义组件样式,动画效果,网络通信,播放媒体等功能。使用 Flutter-Tizen 开发 Tizen App 时,要注意额外的磁盘、内存和 CPU 消耗,以及各 plugin 支持受限的部分

Thank You

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

“闭门造车”之多模态思路浅谈:自回归学习与生成

©PaperWeekly 原创 作者 | 苏剑林 单位 | 科学空间 研究方向 | NLP、神经网络 这篇文章我们继续来闭门造车&#xff0c;分享一下笔者最近对多模态学习的一些新理解。 在前文《“闭门造车”之多模态思路浅谈&#xff1a;无损》中&#xff0c;我们强调了无损输入对于理想的…

Qt中实现让静态图片动起来,创建动画效果

在现代应用程序开发中&#xff0c;动画效果是提升用户体验的重要元素之一。Qt作为一个强大的跨平台应用程序框架&#xff0c;提供了丰富的工具和库来创建各种动画效果。本文将介绍如何在Qt中使用静态图片创建动画效果。 实现方法一 使用QTimer和QPixmap 1.准备图片资源&#…

Diffusion model笔记

![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/f5ec0915d48e4e17bf158b70296cc8d8.png stable diffusion

谷粒商城实战笔记-27-分布式组件-SpringCloud-Gateway-创建测试API网关

本节的主要内容是创建网关模块&#xff0c;将网关注册到Nacos&#xff0c;并配置路由进行测试。 一&#xff0c;创建网关模块 右键工程New->Module&#xff0c;创建新模块&#xff0c;模块名称 gulimall-gateway。 填充各种信息。 选中Gateway依赖。 点击Create创建模块。…

普中51单片机:定时器与计数器详解及应用(七)

文章目录 引言定时器工作原理TMOD定时器/计数器工作模式寄存器定时器工作模式模式0(13位定时器/计数器)模式1(16位定时器/计数器)模式2(8位自动重装模式)模式3(两个8位计数器) 定时器配置流程代码演示——LED1间隔1秒闪烁代码演示——按键1控制LED流水灯状态代码演示——LCD160…

企业数据治理做完了,如何让业务部门用起来

引言&#xff1a;企业数据治理完成后&#xff0c;确保业务部门能够充分利用这些数据并融入日常运营中&#xff0c;是实现数据价值最大化的关键步骤。以下是一些策略和建议&#xff0c;帮助推动业务部门使用数据治理成果&#xff1a; 一、管理层面推广 高层应用示范&#xff1…

【漏洞复现】方正全媒体采编系统——binary.do——SQL注入

声明&#xff1a;本文档或演示材料仅供教育和教学目的使用&#xff0c;任何个人或组织使用本文档中的信息进行非法活动&#xff0c;均与本文档的作者或发布者无关。 文章目录 漏洞描述漏洞复现测试工具 漏洞描述 方正全媒体采编系统&#xff08;FZMediaEditor&#xff09;是一…

网络安全第一次作业

需求 前置工作 给设备配好ip地址&#xff0c;并且在总公司处配置vlan 1&#xff0c; 先建立多个安全区域 接着新建两个策略 :办公区访问dmz区域策略&#xff0c;生产区访问dmz区域策略 2 &#xff0c; 不做配置即可&#xff0c;生产区本不允许访问互联网 3&#xff0c; 新…

学习大数据DAY14 PLSQL基础语法3

目录 二重循环 三种循环随便嵌套 exit continue return 作业 数据提取 游标 隐式游标 显示游标 动态游标 游标使用流程 游标属性 游标配合循环使用示例 作业2 参数游标 current of 语句 作业3 PLSQL基础语法&#xff08;三&#xff09; 二重循环 三种循环随便嵌…

LangChain框架详解

LangChain框架详解 LangChain是一个基于语言模型开发应用程序的强大框架&#xff0c;旨在帮助开发人员简化与大模型交互、数据检索以及将不同功能模块串联起来以完成复杂任务的过程。它提供了一套丰富的工具、组件和接口&#xff0c;使开发人员能够轻松构建上下文感知和具备逻…

Qt:19.浮动窗口/子窗口(子窗口介绍、代码方式创建子窗口、设置子窗口标题、为子窗口添加控件、设置子窗口停靠位置)

目录 1.子窗口介绍&#xff1a; 2.代码方式创建子窗口&#xff1a; 3.设置子窗口标题&#xff1a; 4.为子窗口添加控件&#xff1a; 5.设置子窗口停靠位置。 1.子窗口介绍&#xff1a; 在 Qt 中&#xff0c;可以创建和管理子窗口&#xff08;子窗口体&#xff09;以实现多窗…

线程安全(二)synchronized 的底层实现原理、锁升级

目录 一、基础使用1.1 不加锁的代码实现1.2 加锁的代码实现二、实现原理2.1 synchronized 简介2.2 对象监控器(Monitor)2.3 加锁过程第一步:判断 Owner 指向第二步:进入 EntryList 阻塞第三步:主动进入 WaitSet 等待三、锁升级3.1 对象的内存结构3.2 Mark Word 对象头3.3 …

python的简单爬取

需要的第三方模块 requests winr打开命令行输入cmd 简单爬取的基本格式&#xff08;爬取百度logo为例&#xff09; import requests url"http://www.baidu.com/img/PCtm_d9c8750bed0b3c7d089fa7d55720d6cf.png" resprequests.get(url)#回应 #保存到本地 with open(&…

地址翻译过程(TLB-->页表-->Cache-->主存-->外存)

目录 1.地址结构 2.查找快表或页表&#xff1a;从虚拟地址--->物理地址 3.通过物理地址访问数据 设某系统满足以下条件&#xff1a; •有一个TLB与一个data Cache •存储器以字节为编址单位 •虚拟地址 14位 •物理地址 12位 •页面大小为 64B •TLB 为四路组相联&#x…

嵌入式工程师从0开始,到底该学什么,怎么学?

作为嵌入式工程师&#xff0c;从零开始学习需要掌握以下几个关键方面。我收集归类了一份嵌入式学习包&#xff0c;对于新手而言简直不要太棒&#xff0c;里面包括了新手各个时期的学习方向编程教学、问题视频讲解、毕设800套和语言类教学&#xff0c;敲个22就可以免费获得。 基…

【高中数学/指数函数、对数函数、正弦函数】求 y=2^x+x,y=log2_x+x,y=2*sinX+x 的零点位置大小关系

【问题】 已知函数f(x)2^xx,g(x)log2_xx,h(x)2*sinXx 的零点分别是a,b,c,则a、b、c的大小顺序是&#xff1f; 【解答】 粗览三个函数&#xff0c;h(x)2*sinXx的零点是最好解决的&#xff0c;明显x0时h(x)0&#xff0c;因此c在原点的位置&#xff1b; 对于f(x)2^xx&#xff…

【C++BFS】690. 员工的重要性

本文涉及知识点 CBFS算法 LeetCode690. 员工的重要性 你有一个保存员工信息的数据结构&#xff0c;它包含了员工唯一的 id &#xff0c;重要度和直系下属的 id 。 给定一个员工数组 employees&#xff0c;其中&#xff1a; employees[i].id 是第 i 个员工的 ID。 employees[…

怎样在 C 语言中实现堆排序?

&#x1f345;关注博主&#x1f397;️ 带你畅游技术世界&#xff0c;不错过每一次成长机会&#xff01; &#x1f4d9;C 语言百万年薪修炼课程 【https://dwz.mosong.cc/cyyjc】通俗易懂&#xff0c;深入浅出&#xff0c;匠心打磨&#xff0c;死磕细节&#xff0c;6年迭代&…

人类大脑的计算与机器的类脑计算

人类大脑的计算基本原理涉及到神经元的基本工作方式、神经网络的结构和连接模式、信息传递的方式、学习和记忆的机制等多个层面的复杂互动&#xff0c;这些原理的深入理解不仅有助于神经科学的发展&#xff0c;还为人工智能领域的发展提供了重要的启示和指导。人类大脑计算基本…

按下快门前的算法——对焦

对焦算法可以分为测距式&#xff0c;相位式&#xff0c;反差式。 其中测距式是通过激光&#xff0c;&#xff08;TOF&#xff0c;Time of Flight&#xff09;等主动式地得知物距&#xff0c;然后对焦。更常用的是后两者。 反差式CDAF&#xff08;Contrast Detection Auto Foc…