開源 Arkts 鴻蒙應用 開發(十六)自定義繪圖控件--波形圖

?文章的目的為了記錄使用Arkts?進行Harmony?app?開發學習的經歷。本職為嵌入式軟件開發,公司安排開發app,臨時學習,完成app的開發。開發流程和要點有些記憶模糊,趕緊記錄,防止忘記。

?相關鏈接:

開源 Arkts 鴻蒙應用 開發(一)工程文件分析-CSDN博客

開源 Arkts 鴻蒙應用 開發(二)封裝庫.har制作和應用-CSDN博客

開源 Arkts 鴻蒙應用 開發(三)Arkts的介紹-CSDN博客

開源 Arkts 鴻蒙應用 開發(四)布局和常用控件-CSDN博客

開源 Arkts 鴻蒙應用 開發(五)控件組成和復雜控件-CSDN博客

開源 Arkts 鴻蒙應用 開發(六)數據持久--文件和首選項存儲-CSDN博客

開源 Arkts 鴻蒙應用 開發(七)數據持久--sqlite關系數據庫-CSDN博客

開源 Arkts 鴻蒙應用 開發(八)多媒體--相冊和相機-CSDN博客

開源 Arkts 鴻蒙應用 開發(九)通訊--tcp客戶端-CSDN博客

開源 Arkts 鴻蒙應用 開發(十)通訊--Http-CSDN博客

開源 Arkts 鴻蒙應用 開發(十一)證書和包名修改-CSDN博客

開源 Arkts 鴻蒙應用 開發(十二)傳感器的使用-CSDN博客

開源 Arkts 鴻蒙應用 開發(十三)音頻--MP3播放_arkts avplayer播放音頻 mp3-CSDN博客

開源 Arkts 鴻蒙應用 開發(十四)線程--任務池(taskpool)-CSDN博客

開源 Arkts 鴻蒙應用 開發(十五)自定義繪圖控件--儀表盤-CSDN博客

開源 Arkts 鴻蒙應用 開發(十六)自定義繪圖控件--波形圖-CSDN博客

開源 Arkts 鴻蒙應用 開發(十七)通訊--http多文件下載-CSDN博客

開源 Arkts 鴻蒙應用 開發(十八)通訊--Ble低功耗藍牙服務器-CSDN博客

?推薦鏈接:

開源 java android app 開發(一)開發環境的搭建-CSDN博客

開源 java android app 開發(二)工程文件結構-CSDN博客

開源 java android app 開發(三)GUI界面布局和常用組件-CSDN博客

開源 java android app 開發(四)GUI界面重要組件-CSDN博客

開源 java android app 開發(五)文件和數據庫存儲-CSDN博客

開源 java android app 開發(六)多媒體使用-CSDN博客

開源 java android app 開發(七)通訊之Tcp和Http-CSDN博客

開源 java android app 開發(八)通訊之Mqtt和Ble-CSDN博客

開源 java android app 開發(九)后臺之線程和服務-CSDN博客

開源 java android app 開發(十)廣播機制-CSDN博客

開源 java android app 開發(十一)調試、發布-CSDN博客

開源 java android app 開發(十二)封庫.aar-CSDN博客

推薦鏈接:

開源C# .net mvc 開發(一)WEB搭建_c#部署web程序-CSDN博客

開源 C# .net mvc 開發(二)網站快速搭建_c#網站開發-CSDN博客

開源 C# .net mvc 開發(三)WEB內外網訪問(VS發布、IIS配置網站、花生殼外網穿刺訪問)_c# mvc 域名下不可訪問內網,內網下可以訪問域名-CSDN博客

開源 C# .net mvc 開發(四)工程結構、頁面提交以及顯示_c#工程結構-CSDN博客

開源 C# .net mvc 開發(五)常用代碼快速開發_c# mvc開發-CSDN博客

本章內容主要演示了如何使自定義控件,通過畫布實現一個心率監測應用,主要包含三個文件:Index.ets、HeartRate.ets和HeartRateGraph.ets。

1.工程結構

2.源碼解析

3.演示效果

4.工程下載網址

一、工程結構,主要有標紅部分4個文件

二、源碼解析

2.1? Index.ets
這是應用的入口文件,主要功能:

創建一個簡單的界面展示心率數據和心率圖表

使用AppStorage存儲心率數據

通過定時器模擬心率數據變化

代碼如下:
?

import HeartRateGraph from '../uicomponents/HeartRateGraph';@Entry
@Component
struct Index {@State heartRate: number = 0;aboutToAppear() {// 初始化 AppStorage 中的 heartRateAppStorage.setOrCreate('heartRate', this.heartRate);// 定時更新setInterval(() => {this.heartRate = Math.floor(Math.random() * 60) + 60;AppStorage.setOrCreate('heartRate', this.heartRate);}, 1000);}build() {Column() {// 不需要傳遞 heartRate 參數HeartRateGraph({viewWidth: 360,viewHeight: 300}).width('100%').height(300)Text(`當前心率: ${this.heartRate} bpm`).fontSize(18)}}
}

2.2? HeartRate.ets
這是主要的心率展示頁面:展示心率數據(最大值、最小值、平均值、當前值)

使用@StorageLink從AppStorage同步心率數據和窗口大小數據

通過@Watch裝飾器監聽數據變化

以下為代碼:

/** Copyright (c) 2024 Huawei Device Co., Ltd.* Licensed under the Apache License, Version 2.0 (the "License");* you may not use this file except in compliance with the License.* You may obtain a copy of the License at**     http://www.apache.org/licenses/LICENSE-2.0** Unless required by applicable law or agreed to in writing, software* distributed under the License is distributed on an "AS IS" BASIS,* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.* See the License for the specific language governing permissions and* limitations under the License.*/import { display, promptAction, window } from '@kit.ArkUI';
import { common } from '@kit.AbilityKit';
import { BusinessError } from '@kit.BasicServicesKit';import HeartRateGraph from '../uicomponents/HeartRateGraph';
const uiContext: UIContext | undefined = AppStorage.get('uiContext');
const HEIGHT_NAVIGATION_BAR = 64;
const HEIGHT_TOP_ROW = 40;
const MARGIN_HORIZONTAL = 60;
const HEART_RATE_TOO_LOW = 50;
const HEART_RATE_TOO_HIGH = 100;
const context: Context =uiContext!.getHostContext()!;@Component
export struct HeartRate {@StorageLink('heartRate') @Watch('onHeartRate') heartRate: number = 0;@StorageLink('windowSize') @Watch('onWindowSizeChange') windowSize: window.Size = {width: display.getDefaultDisplaySync().width,height: display.getDefaultDisplaySync().height};@State isFoldAble: boolean = false;@State foldStatus: number = 2;@State heartRateTop: number = 0;@State heartRateBottom: number = 0;@State heartRateAverage: number = 0;@State graphWidth: number = this.windowSize.width - this.getUIContext().vp2px(MARGIN_HORIZONTAL) * 2;@State graphHeight: number = this.windowSize.height - this.getUIContext().vp2px(HEIGHT_NAVIGATION_BAR) - this.getUIContext().vp2px(HEIGHT_TOP_ROW * 3);@State isConnect: boolean = false;private windowClass = (context as common.UIAbilityContext).windowStage.getMainWindowSync();onHeartRate(): void {this.heartRateTop = this.heartRateTop < this.heartRate ? this.heartRate : this.heartRateTop;this.heartRateBottom = (this.heartRateBottom === 0) ? this.heartRate :(this.heartRateBottom > this.heartRate) ? this.heartRate : this.heartRateBottom;this.heartRateAverage = (this.heartRateAverage + this.heartRate) / 2;}onWindowSizeChange(): void {this.graphWidth = this.windowSize.width - this.getUIContext().vp2px(MARGIN_HORIZONTAL) * 2;this.graphHeight = this.windowSize.height - this.getUIContext().vp2px(HEIGHT_NAVIGATION_BAR) - this.getUIContext().vp2px(HEIGHT_TOP_ROW * 3);}showWarningReminder(): boolean {return this.tooHigh() || this.tooLow();}tooHigh(): boolean {return this.heartRate > HEART_RATE_TOO_HIGH;}tooLow(): boolean {return this.heartRate < HEART_RATE_TOO_LOW;}setOrientation(orientation: number) {this.windowClass.setPreferredOrientation(orientation).then(() => {//Logger.info('setWindowOrientation Succeeded');}).catch((err: BusinessError) => {//Logger.error(`setWindowOrientation Failed. Cause:${JSON.stringify(err)}`);})this.windowClass.setWindowSystemBarEnable([]);}aboutToAppear() {this.setOrientation(window.Orientation.LANDSCAPE);let mWindow: window.Window | undefined;let windowStage: window.WindowStage | undefined;mWindow = windowStage?.getMainWindowSync();mWindow?.on('windowSizeChange', (size: window.Size) => {AppStorage.setOrCreate('windowSize', size);})this.isFoldAble = display.isFoldable();let foldStatus: display.FoldStatus = display.getFoldStatus();if (this.isFoldAble) {this.foldStatus = foldStatus;let callback: Callback<number> = () => {let data: display.FoldStatus = display.getFoldStatus();this.foldStatus = data;}display.on('change', callback);}}aboutToDisappear(): void {this.setOrientation(window.Orientation.PORTRAIT);}build() {NavDestination() {Row() {Row() {Image($r('app.media.heart_fill')).width(36).aspectRatio(1).margin({ left: 8 })Column() {Row() {Text(`${this.heartRateTop}`).fontColor(Color.Black).opacity(0.9).fontSize(26).fontWeight(FontWeight.Bold)Text($r('app.string.times_per_minute')).fontColor(Color.Black).opacity(0.6)}.width(90)Text($r('app.string.maximum_heart_rate')).fontColor(Color.Black).opacity(0.6).width(90)}.margin({ left: 30, right: 50 })Column() {Row() {Text(`${this.heartRateBottom}`).fontColor(Color.Black).opacity(0.9).fontSize(26).fontWeight(FontWeight.Bold)Text($r('app.string.times_per_minute')).fontColor(Color.Black).opacity(0.6)}.width(90)Text($r('app.string.minimum_heart_rate')).fontColor(Color.Black).opacity(0.6).width(90)}}.alignItems(VerticalAlign.Center).width(this.isFoldAble && this.foldStatus === 2 ? 345 : 360).height(90).backgroundColor(Color.White).borderRadius(12).margin({ right: 24 })Row() {Image($r('app.media.waveform_path_ecg_heart_fill')).width(36).aspectRatio(1).margin({ left: 8 })Column() {Row() {Text(`${Math.floor(this.heartRateAverage)}`).fontColor(Color.Black).opacity(0.9).fontSize(26).fontWeight(FontWeight.Bold)Text($r('app.string.times_per_minute')).fontColor(Color.Black).opacity(0.6)}.width(90)Text($r('app.string.mean_heart_rate')).fontColor(Color.Black).opacity(0.6).width(90)}.margin({ left: 30, right: 50 })Column() {Row() {Text(`${this.heartRate}`).fontColor(Color.Black).opacity(0.9).fontSize(26).fontWeight(FontWeight.Bold)Text($r('app.string.times_per_minute')).fontColor(Color.Black).opacity(0.6)}.width(90)Text($r('app.string.current_heart')).fontColor(Color.Black).opacity(0.6).width(90)}}.alignItems(VerticalAlign.Center).width(this.isFoldAble && this.foldStatus === 2 ? 345 : 360).height(90).backgroundColor(Color.White).borderRadius(12)}.width('100%').height(90).padding({ left: 60, right: 60 }).justifyContent(FlexAlign.SpaceBetween).margin({ bottom: 36 })HeartRateGraph({viewWidth: 756,viewHeight: 180})}.hideTitleBar(true).backgroundColor('#F5F5F5')}
}

2.3? HeartRateGraph.ets
這是心率圖表組件,主要功能:繪制心率變化曲線圖,顯示坐標軸和時間軸,響應視圖大小變化

使用CanvasRenderingContext2D進行繪圖,繪制坐標軸、網格線和心率曲線

以下為代碼:

import DateUtils from '../utils/DateUtils';
const uiContext: UIContext | undefined = AppStorage.get('uiContext');
const SIZE: number = 12;
const COORDINATE_SIZE: number = 5;
const LINE_WIDTH: number = uiContext!.px2vp(6);
const COLOR_LINE: string = '#FF0A59F7';
const MAX_HEART_RATE: number = 200;
const WIDTH_CHANGE_POINT: number = uiContext!.px2vp(900);const X_COORDINATE_TEXT_HEIGHT: number = uiContext!.px2vp(30);
const START_X: number = uiContext!.px2vp(40);
const PADDING_VERTICAL: number = uiContext!.px2vp(40);
const PADDING_HORIZONTAL: number = uiContext!.px2vp(40);// 在常量定義部分增加字體大小相關常量
const COORDINATE_FONT_SIZE: number = uiContext!.px2vp(18); // 坐標軸字體大小
const DATA_LABEL_FONT_SIZE: number = uiContext!.px2vp(16); // 數據標簽字體大小
const TITLE_FONT_SIZE: number = uiContext!.px2vp(15);     // 標題字體大小@Component
export default struct HeartRateGraph {@StorageProp('heartRate') @Watch('onHeartRate') heartRate: number = 0;@Prop @Watch('onViewSizeChange') viewWidth: number;@Prop @Watch('onViewSizeChange') viewHeight: number;@State heartRateArr: Array<number> = [];@State timeArr: Array<string> = [];private settings: RenderingContextSettings = new RenderingContextSettings(true);private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings);private mCoordinateLineEndX: number = 0;private mOffset: number = 0;private mHeightRatio: number = 0;private mHeartRateCoordinateArr: Array<number> = [];aboutToAppear(): void {this.calculateLayoutConfig();for (let i = 0; i < SIZE; i++) {this.heartRateArr[i] = 0;}for (let i = 0; i < SIZE; i++) {this.timeArr[i] = `--:--:--`;}}onHeartRate() {this.heartRateArr.push(this.heartRate);if (this.heartRateArr.length > SIZE) {this.heartRateArr.shift();}this.timeArr.push(DateUtils.format(new Date(), 'HH:mm:ss'));if (this.timeArr.length > SIZE) {this.timeArr.shift();}this.draw();}onViewSizeChange() {this.calculateLayoutConfig();}calculateLayoutConfig() {this.mCoordinateLineEndX = this.viewWidth - PADDING_HORIZONTAL;this.mOffset = (this.viewWidth - START_X - PADDING_HORIZONTAL * 2) / (SIZE - 1);this.mHeightRatio = (this.viewHeight - PADDING_VERTICAL * 2 - X_COORDINATE_TEXT_HEIGHT * 2) / MAX_HEART_RATE;let heartRateCoordinate: number = MAX_HEART_RATE / (COORDINATE_SIZE - 1);this.mHeartRateCoordinateArr =[0, heartRateCoordinate, heartRateCoordinate * 2, heartRateCoordinate * 3, heartRateCoordinate * 4];}draw() {this.context.clearRect(0, 0, this.viewWidth, this.viewHeight);this.drawCoordinate();this.drawHeartRateLine();}drawCoordinate() {// 修改坐標軸文字大小和樣式this.context.font = `${COORDINATE_FONT_SIZE}px sans-serif`;this.context.fillStyle = '#333333'; // 使用更深的顏色提高可讀性// 修改數據標簽文字大小this.context.font = `${DATA_LABEL_FONT_SIZE}px sans-serif`;this.context.fillStyle = '#000000'; // 黑色提高對比度this.context.lineWidth = LINE_WIDTH / 3;this.context.font = '16px sans-serif';let path: Path2D = new Path2D();this.context.fillStyle = '#999999';for (let i = 0; i < COORDINATE_SIZE; i++) {let text = `${this.mHeartRateCoordinateArr[i]}bpm`;let offsetY = (this.viewHeight - PADDING_VERTICAL * 2 - X_COORDINATE_TEXT_HEIGHT * 2) / (COORDINATE_SIZE - 1);let x = 0;let y = this.viewHeight - PADDING_VERTICAL - X_COORDINATE_TEXT_HEIGHT * 2 - offsetY * i +this.context.measureText(text)?.height / 4;path.moveTo(x, y);this.context.fillText(text, x, y);this.context.stroke(path);}this.context.strokeStyle = '#1A000000';for (let i = 0; i < COORDINATE_SIZE; i++) {let offsetY = (this.viewHeight - PADDING_VERTICAL * 2 - X_COORDINATE_TEXT_HEIGHT * 2) / (COORDINATE_SIZE - 1);let x = START_X + PADDING_HORIZONTAL;let y = this.viewHeight - PADDING_VERTICAL - X_COORDINATE_TEXT_HEIGHT * 2 - offsetY * i;let path1: Path2D = new Path2D();path1.moveTo(x, y);path1.lineTo(this.mCoordinateLineEndX, y);this.context.stroke(path1);}this.context.fillStyle = '#999999';let path2: Path2D = new Path2D();for (let i = 0; i < SIZE; i++) {if (this.viewWidth <= WIDTH_CHANGE_POINT && i % 2 === 0) {continue;}let text = this.timeArr[i];let x = START_X + this.mOffset * i + PADDING_HORIZONTAL - this.context.measureText(text)?.width / 2;let y = this.viewHeight - PADDING_VERTICAL - X_COORDINATE_TEXT_HEIGHT;path2.moveTo(x, y);this.context.fillText(text, x, y);this.context.stroke(path2);}this.context.fillStyle = '#333333';let path3: Path2D = new Path2D();for (let i = 0; i < SIZE; i++) {if (this.viewWidth <= WIDTH_CHANGE_POINT && i % 2 === 0) {continue;}let text = `${this.heartRateArr[i]}bpm`;let x = START_X + this.mOffset * i + PADDING_HORIZONTAL - this.context.measureText(text)?.width / 2;let y = this.viewHeight - PADDING_VERTICAL;path2.moveTo(x, y);this.context.fillText(text, x, y);this.context.stroke(path3);}}drawHeartRateLine() {this.context.lineWidth = LINE_WIDTH;this.context.strokeStyle = COLOR_LINE;let path: Path2D = new Path2D();for (let i = 0; i < SIZE; i++) {let x = START_X + this.mOffset * i + PADDING_HORIZONTAL;let y =this.viewHeight - PADDING_VERTICAL - X_COORDINATE_TEXT_HEIGHT * 2 - this.heartRateArr[i] * this.mHeightRatio;if (i === 0) {path.moveTo(x, this.viewHeight - PADDING_VERTICAL - X_COORDINATE_TEXT_HEIGHT * 2);path.lineTo(x, y);} else {path.lineTo(x, y);}if (i === SIZE - 1) {path.lineTo(x, this.viewHeight - PADDING_VERTICAL - X_COORDINATE_TEXT_HEIGHT * 2);}}let gradient = this.context.createLinearGradient(0, PADDING_VERTICAL, 0,this.viewHeight - PADDING_VERTICAL - X_COORDINATE_TEXT_HEIGHT * 2);gradient.addColorStop(0.0, '#660A59F7');gradient.addColorStop(1.0, '#660A59F7');this.context.fillStyle = gradient;this.context.fill(path);this.context.stroke(path);this.context.clearRect(START_X + PADDING_HORIZONTAL - LINE_WIDTH / 2, 0, LINE_WIDTH,this.viewHeight - PADDING_VERTICAL - X_COORDINATE_TEXT_HEIGHT * 2 + LINE_WIDTH / 2);this.context.clearRect(this.viewWidth - PADDING_HORIZONTAL - LINE_WIDTH / 2, 0, LINE_WIDTH,this.viewHeight - PADDING_VERTICAL - X_COORDINATE_TEXT_HEIGHT * 2 + LINE_WIDTH / 2);}build() {Column() {// 添加圖表標題Text('心率變化圖').fontSize(TITLE_FONT_SIZE).fontWeight(FontWeight.Bold).fontColor('#333333').margin({ bottom: 10 });Canvas(this.context).width(this.viewWidth).height(this.viewHeight).onReady(() => {this.draw();})}}
}

2.4??DateUtils.ets時間格式化文件

以下為代碼:


const MAX_LENGTH: number = 2;export default class DateUtils {public static format(date: Date, format: string = 'yyyy-MM-dd HH:mm:ss'): string {let year = date.getFullYear().toString();let month = (date.getMonth() + 1).toString().padStart(MAX_LENGTH, '0');let day = (date.getDate() + 1).toString().padStart(MAX_LENGTH, '0');let hour = (date.getHours() + 1).toString().padStart(MAX_LENGTH, '0');let minute = (date.getMinutes() + 1).toString().padStart(MAX_LENGTH, '0');let second = (date.getSeconds() + 1).toString().padStart(MAX_LENGTH, '0');let result = format.replace('yyyy', year);result = result.replace('MM', month);result = result.replace('dd', day);result = result.replace('HH', hour);result = result.replace('mm', minute);result = result.replace('ss', second);return result}
}

三、演示效果

四、項目源碼下載網址:https://download.csdn.net/download/ajassi2000/91681323

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/93255.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/93255.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/93255.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【linux】自定義shell——bash命令行解釋器小程序

小編個人主頁詳情<—請點擊 小編個人gitee代碼倉庫<—請點擊 linux系列專欄<—請點擊 倘若命中無此運&#xff0c;孤身亦可登昆侖&#xff0c;送給屏幕面前的讀者朋友們和小編自己! 目錄前言一、交互問題&#xff0c;獲取命令行二、字串的分隔問題&#xff0c;解析命…

【Python】Python爬蟲學習路線

文章目錄Python爬蟲學習路線&#xff1a;從入門到實戰的全景指南一、地基&#xff1a;Python核心基礎1. 基礎語法與數據結構2. 面向對象編程&#xff08;OOP&#xff09;3. 正則表達式&#xff08;Regex&#xff09;4. 模塊與包管理二、工具鏈&#xff1a;Python爬蟲核心庫1. 網…

VUE+SPRINGBOOT從0-1打造前后端-前后臺系統-用戶管理

在現代Web應用開發中&#xff0c;前后端分離架構已經成為主流模式。本文將通過一個完整的用戶管理系統案例&#xff0c;詳細介紹如何使用Vue.js Element UI構建前端界面&#xff0c;結合Spring Boot實現后端服務&#xff0c;實現前后端分離開發。該系統包含用戶信息的增刪改查…

基于uni-app+vue3實現的微信小程序地圖范圍限制與單點標記功能實現指南

一、功能概述本文將分步驟講解如何使用uni-app框架在微信小程序中實現以下功能&#xff1a;顯示基礎地圖繪制特定區域范圍&#xff08;以鄭州市為例&#xff09;實現點擊地圖添加標記點限制標記點只能在指定區域內添加顯示選中位置的坐標信息二、分步驟實現步驟1&#xff1a;搭…

C# 反射和特性(關于應用特性的更多內容)

關于應用特性的更多內容 至此&#xff0c;我們演示了特性的簡單使用&#xff0c;都是為方法應用單個特性。本節將講述特性的其他使 用方式。 多個特性 可以為單個結構應用多個特性。 多個特性可以使用下面任何一種格式列出。 獨立的特性片段一個接一個。通常&#xff0c;它們彼…

【iOS】KVC原理及自定義

目錄 前言 KVC定義及API KVC的使用 基本類型 集合類型 訪問非對象類型——結構體 集合操作符 層層嵌套 KVC底層原理 設值過程 取值過程 自定義KVC setter方法 getter方法 KVC異常小技巧 自動轉換類型 設置空值 未定義的key 前言 在平時的開發中我們經常用到K…

完整設計 之 智能合約系統:主題約定、代理協議和智能合約 (臨時命名)----PromptPilot (助手)答問之2

摘要&#xff08;CSDN的AI助手生成的&#xff09;智能合約系統架構設計摘要本設計構建了一個多層次智能合約系統&#xff0c;包含150字以內的核心架構&#xff1a;三級架構體系&#xff1a;元級&#xff08;序分&#xff09;&#xff1a;MetaModel合約定義系統核心原則模型級&a…

Java基礎 8.16

1.final關鍵字基本介紹final中文意思&#xff1a;最后的&#xff0c;最終的final可以修飾類、屬性、方法和局部變量在某些情況下&#xff0c;程序員可能有以下需求&#xff0c;就會使用到final當不希望類被繼承時,可以用final修飾當不希望父類的某個方法被子類覆蓋/重寫(overri…

YOLOv8目標檢測網絡結構理論

目錄 YOLOv8的網絡結構圖&#xff1a; Backbone 卷積塊&#xff08;Conv Block&#xff09; Conv2d層 BatchNorm2d層 SiLU激活函數 瓶頸塊(Bottleneck Block) C2f 模塊結構 Neck SPPF(空間金字塔池化快速) PAN - FPN Head 結構1.卷積層和激活函數: 2.預測層(Predi…

docker部署hadoop集群

Docker部署hadoop集群下載資源構建鏡像啟動容器搭建集群配置ssh免密節點職責安排修改配置文件啟動集群測試上傳下載執行wordcount程序補充配置歷史服務器日志聚集單節點啟動Java客戶端使用HDFSMapReduce下載資源 java華為鏡像下載地址&#xff1a;Index of java-local/jdk (hu…

常用的T-SQL命令

文章目錄1. 數據庫操作2. 表操作3. 數據插入、更新、刪除4. 數據查詢5. 存儲過程6. 事務處理7、如何使用T-SQL在表中設置主鍵和外鍵&#xff1f;1. 設置主鍵&#xff08;PRIMARY KEY&#xff09;方法1&#xff1a;創建表時定義主鍵方法2&#xff1a;通過ALTER TABLE添加主鍵2. …

C++面試題及詳細答案100道( 31-40 )

《前后端面試題》專欄集合了前后端各個知識模塊的面試題&#xff0c;包括html&#xff0c;javascript&#xff0c;css&#xff0c;vue&#xff0c;react&#xff0c;java&#xff0c;Openlayers&#xff0c;leaflet&#xff0c;cesium&#xff0c;mapboxGL&#xff0c;threejs&…

給純小白的 Python 操作 Excel 筆記

&#x1f9f0; 1. 先裝工具電腦鍵盤按 Win R&#xff0c;輸入 cmd&#xff0c;回車&#xff0c;把下面一行粘進去回車&#xff0c;等它跑完。 bashpip install openpyxl——————————————————&#x1f6e0;? 2. 打開一個空白的 Excel 打開 Jupyter Notebook…

HTML 常用屬性介紹

目錄 HTML 屬性 HTML 屬性速查表 一、通用屬性&#xff08;所有元素適用&#xff09; 二、鏈接與引用相關屬性 三、表單與輸入控件屬性 四、媒體與多媒體屬性 五、事件屬性&#xff08;常用 JavaScript 事件&#xff09; 六、其他常用屬性 核心通用屬性 id 屬性 cla…

HTML5練習代碼集:學習與實踐核心特性

本文還有配套的精品資源&#xff0c;點擊獲取 簡介&#xff1a;HTML5作為新一代網頁標準&#xff0c;對Web開發提供了更豐富的功能和工具。本練習代碼集專門針對HTML5的核心特性&#xff0c;包括語義化標簽、離線存儲、多媒體支持、圖形繪制等&#xff0c;以及CSS3的3D效果和…

【RH134知識點問答題】第 10 章:控制啟動過程

目錄 1. 請簡要說明 RHEL9 的啟動過程。 2. 系統重啟和關機的命令分別是什么? 3. Systemd target 是什么&#xff1f; 4. 重置丟失的 root 密碼需要哪些步驟&#xff1f; 5. 如何讓系統日志在重啟后持久保留 1. 請簡要說明 RHEL9 的啟動過程。 答&#xff1a;①開機自檢…

Apollo10.0學習之固態雷達與IMU的外參標定

固態雷達&#xff08;如Livox、禾賽等非旋轉式激光雷達&#xff09;與IMU&#xff08;慣性測量單元&#xff09;的外參標定&#xff08;Extrinsic Calibration&#xff09;是自動駕駛、機器人定位&#xff08;如LIO-SAM、FAST-LIO&#xff09;的關鍵步驟。1. 標定原理 外參標定…

HTML5實現古典音樂網站源碼模板1

文章目錄 1.設計來源1.1 網站首頁1.2 古典音樂界面1.3 著名人物界面1.4 古典樂器界面1.5 歷史起源界面 2.效果和源碼2.1 動態效果2.2 源代碼 源碼下載萬套模板&#xff0c;程序開發&#xff0c;在線開發&#xff0c;在線溝通 作者&#xff1a;xcLeigh 文章地址&#xff1a;http…

40 C++ STL模板庫9-容器2-vector

C STL模板庫9-容器2-vector 文章目錄C STL模板庫9-容器2-vector一、基礎概念1. 類型成員&#xff08;Type Members&#xff09;2. 模板參數二、構造函數1. 語法2. 示例三、元素訪問1. 函數說明2. 示例代碼四、容量操作1. 函數說明2. 關鍵點說明3. 關鍵操作解析4. 操作示例五、修…

GPT-5系列文章2——新功能、測試與性能基準全解析

引言 2025年8月&#xff0c;OpenAI正式發布了其新一代旗艦模型GPT-5。與業界此前期待的AGI(人工通用智能)突破不同&#xff0c;GPT-5更像是OpenAI對現有技術的一次深度整合與用戶體驗優化。本文將全面解析GPT-5的新特性、實際測試表現以及官方發布的基準數據&#xff0c;幫助開…