Fyne ( go跨平台GUI )中文文档-Fyne总览(二)

本文档注意参考官网(developer.fyne.io/) 编写, 只保留基本用法

go代码展示为Go 1.16 及更高版本, idegoland2021.2​​​​​​​

 这是一个系列文章:

Fyne ( go跨平台GUI )中文文档-入门(一)-CSDN博客

Fyne ( go跨平台GUI )中文文档-Fyne总览(二)-CSDN博客

Fyne ( go跨平台GUI )中文文档-绘图和动画(三)-CSDN博客

Fyne ( go跨平台GUI )中文文档-容器和布局 (四)-CSDN博客

Fyne ( go跨平台GUI )中文文档-小部件 (五)-CSDN博客

Fyne ( go跨平台GUI )中文文档- 数据绑定 (六)-CSDN博客

Fyne ( go跨平台GUI )中文文档- 扩展Fyne (七)-CSDN博客

Fyne ( go跨平台GUI )中文文档- 架构 (八)完结-CSDN博客

2.Fyne总览

2.1 Canvas(画布) and CanvasObject

在 Fyne 中Canvas是在其中绘制应用程序的区域。每个窗口都有一个您可以通过Window.Canvas()访问的Canvas,但通常您会在上面找到Window避免访问画布的功能。
可以在 Fyne中绘制的所有内容都是CanvasObject. 这里的示例打开一个新窗口,然后通过设置窗口画布的内容来显示不同类型的原始图形元素。如文本和圆形示例所示,可以通过多种方式自定义每种类型的对象。
除了更改显示Canvas.SetContent()的内容外,还可以更改当前可见的内容。例如,如果您更改FillColour矩形的 ,则可以使用 请求刷新此现有组件rect.Refresh()

package main

import (
    "image/color"
    "time"

    "fyne.io/fyne/v2"
    "fyne.io/fyne/v2/app"
    "fyne.io/fyne/v2/canvas"
)

func main() {
    myApp := app.New()
    myWindow := myApp.NewWindow("Canvas")
    myCanvas := myWindow.Canvas()

    blue := color.NRGBA{R: 0, G: 0, B: 180, A: 255}
    rect := canvas.NewRectangle(blue)
    myCanvas.SetContent(rect)

    go func() {
        time.Sleep(time.Second)
        green := color.NRGBA{R: 0, G: 180, B: 0, A: 255}
        rect.FillColor = green
        rect.Refresh()
    }()

    myWindow.Resize(fyne.NewSize(100, 100))
    myWindow.ShowAndRun()
}

我们可以用同样的方式绘制很多不同的绘图元素,比如圆形和文字。

func setContentToText(c fyne.Canvas) {
    green := color.NRGBA{R: 0, G: 180, B: 0, A: 255}
    text := canvas.NewText("Text", green)
    text.TextStyle.Bold = true
    c.SetContent(text)
}

func setContentToCircle(c fyne.Canvas) {
    red := color.NRGBA{R: 0xff, G: 0x33, B: 0x33, A: 0xff}
    circle := canvas.NewCircle(color.White)
    circle.StrokeWidth = 4
    circle.StrokeColor = red
    c.SetContent(circle)
}

小部件(Widget)

fyne.Widget是一种特殊类型的画布对象,它具有与之关联的交互元素。在小部件中,逻辑与其外观(也称为 WidgetRenderer)是分开的。
小部件也是CanvasObject一种类型,因此我们可以将窗口的内容设置为单个小部件。在这个例子中看看我们如何创建一个新的 widget.Entry并将其设置为窗口的内容。

package main

import (
    "fyne.io/fyne/v2/app"
    "fyne.io/fyne/v2/widget"
)

func main() {
    myApp := app.New()
    myWindow := myApp.NewWindow("Widget")

    myWindow.SetContent(widget.NewEntry())
    myWindow.ShowAndRun()
}

2.2 Container and Layouts(容器和布局)

在前面的示例中,我们看到了如何将 CanvasObject 设置为Canvas的内容,但只显示一个视觉元素并不是很有用。为了显示多个项目,我们使用Container类型。
由于fyne.Container也是 fyne.CanvasObject,我们可以将其设置为fyne.Canvas 的内容。在本例中,我们创建了 3 个文本对象,然后使用container.NewWithoutLayout()函数将它们放入容器中。由于没有布局集,我们可以用text2.Move()移动元素。

fyne.Layout实现了一种在容器内组织项目的方法。通过取消注释container.New()此示例中的行,您可以更改容器以使用具有 2 列的网格布局。运行此代码并尝试调整窗口大小以查看布局如何自动配置窗口的内容。另请注意,text2布局代码忽略了手动位置。
要查看更多信息,您可以查看Layout list.

2.3 小部件(Widget)列表
2.3.1 标准小部件(widget包)

手风琴(Accordion )

Accordion 显示 AccordionItems 列表。每个项目都由一个按钮表示,点击该按钮会显示详细视图。

按钮(Button)

按钮小部件具有文本标签和图标,两者都是可选的。

卡片(Card)

卡片小部件使用标题和子标题对元素进行分组,所有这些都是可选的。

复选框(Check )

检查小部件有一个文本标签和一个选中(或未选中)的图标。

输入框(Entry)

输入框小部件允许在获得焦点时输入简单的文本。

PasswordEntry 小部件隐藏文本输入并添加一个按钮来显示文本。

文件图标(FileIcon)

FileIcon 为各种类型的文件提供有用的标准图标。它将文件类型显示为指示器图标并显示文件类型的扩展名。

表单(Form)

表单小部件是两列网格,其中每一行都有一个标签和一个小部件(通常是一个输入)。最后一行将包含适当的表单控制按钮。

超链接(Hyperlink)

超链接小部件是具有适当填充和布局的文本组件。单击后,URL 将在您的默认 Web 浏览器中打开。

图标(Icon)

图标小部件是一个基本的图像组件,它加载其资源以匹配主题。

标签(Label )

标签小部件是具有适当填充和布局的标签组件。

进度条(ProgressBar)

ProgressBar 小部件创建一个指示进度的水平面板。

ProgressBarInfinite 小部件创建一个水平面板,指示无限进度条 0% -> 100% 重复循环,直到调用 Stop()。

单选框组(RadioGroup)

RadioGroup 小部件有一个文本标签列表和每个旁边的单选检查图标。

下拉选择框(Select)

选择小部件有一个选项列表,显示当前选项,并在单击时触发事件函数。

下拉选择框可输入选择(SelectEntry)

小部件将可编辑组件添加到下拉选择框小部件。用户可以选择一个选项或输入自己的值。

分割线(Separator)

分隔小部件显示其他元素之间的分界线。

滑块(Slider)

Slider小部件可以在两个固定值之间滑动切换。

文本网格(TextGrid )

TextGrid 是一个等宽的字符网格。这旨在供文本编辑器、代码预览或终端仿真器使用。

工具栏(Toolbar)

工具栏小部件创建工具按钮的水平列表。

2.3.2 集成小部件(widget包)

集成小部件提供高级缓存功能,以提供海量数据的高性能呈现。这确实导致了一个更复杂的构造函数,但是对于它实现的结果来说是一个很好的平衡。这些小部件中的每一个都使用一系列回调,最小集合由它们的构造函数定义,其中包括数据大小、可重复使用的模板的创建、数据应用于小部件的函数。

列表(List)

List 提供了许多子项的高性能垂直滚动。

表格(Table)

表格提供了许多子项的高性能滚动二维显示。

树(Tree)

树提供了一个高性能的垂直滚动项目,可以展开以显示子元素。

2.3.3 容器小部件(container包)

容器小部件类似于常规容器,但它们提供了一些额外的功能。

应用选项卡(AppTabs)

AppTabs 小部件允许从 TabItems 列表切换可见内容。每个项目都由小部件顶部的按钮表示。

滚动容器 (ScrollContainer)

ScrollContainer 定义了一个小于 Content 的容器。

分裂容器(SplitContainer)

SplitContainer 定义了一个容器,其大小在两个子项之间拆分。

2.4 布局(layout)列表

水平框(HBox)

水平框将项目排列在水平行中。每个元素都将具有相同的高度(容器中最高项目的高度),并且对象将在其最小宽度处左对齐。

垂直框 (VBox)

垂直框将项目排列在垂直列中。每个元素将具有相同的宽度(容器中最宽项的宽度),并且对象将在其最小高度处顶部对齐。

居中(Center )

居中布局将所有容器元素放置在容器的中心。每个对象都将设置为其最小尺寸。

表单布局(Form)

表单布局将项目成对排列,其中第一列的宽度最小。这对于在表单中标记元素通常很有用,其中标签位于第一列,而它描述的项目位于第二列。您应该始终向表单布局添加偶数个元素。

网格(Grid)

网格布局在可用空间中平均排列项目。指定了列数,对象水平放置,直到达到列数,此时新行开始。所有对象具有相同的大小,即宽度除以总列,高度将是总高度除以所需的行数。减去填充。

网格环绕(GridWrap)

GridWrap 布局将所有项目排列成一行,如果空间不足,则换行到新行。所有对象都将设置为相同的大小,即传递给布局的大小。此布局可能不尊重项目 MinSize 来管理此统一布局。通常用于文件管理器或图像缩略图列表。

边框(Border)

边框布局支持将项目定位在可用空间之外。边框被传递给(上、左、下、右)对象的指针。容器中未定位在边框上的所有项目将填充剩余空间。

最大(max)

最大布局定位所有容器元素以填充可用空间。这些对象都将是全尺寸的,并按照它们添加到容器中的顺序绘制(最后一个在顶部)。

填充(Padded)

填充布局定位所有容器元素以填充可用空间,但在外部有一个小填充。填充的大小是特定于主题的。所有对象都将按照它们添加到容器中的顺序绘制(最后一个在顶部)。

组合布局

可以嵌套多个容器,每个容器都有自己的布局,以仅使用上面列出的标准布局创建完整的用户界面排列。例如标题的水平框,左侧文件面板的垂直框和内容区域中的网格环绕布局 - 使用边框布局的所有容器内都可以构建如下所示的结果。

2.5 对话框(Dialog)列表

颜色

允许用户从标准集(或高级模式下的任何颜色)中选择一种颜色。

确认

询问动作的构象

文件打开

展示此内容以要求用户选择要在应用内使用的文件。实际显示的对话框取决于当前的操作系统。

表单

在对话框中获取各种输入元素,并进行验证。

信息

一种向应用程序用户呈现一些信息的简单方法。

通用

在对话框容器中呈现任何内容。

2.6 快捷方式

快捷方式是可以通过键盘组合或上下文菜单触发的常见任务。快捷方式,很像键盘事件,可以附加到焦点元素或注册Window.Canvas
画布注册
定义了许多标准快捷键(例如fyne.ShortcutCopy),它们连接到标准键盘快捷键和右键菜单。第一步添加Shortcut是定义快捷方式。对于大多数用途,这将是一个键盘触发的快捷方式,它是一个桌面扩展。为此,我们使用desktop.CustomShortcut,例如使用 Tab 键和Control 修饰符,您可以执行以下操作:

    ctrlTab := desktop.CustomShortcut{KeyName: fyne.KeyTab, Modifier: desktop.ControlModifier}

请注意,此快捷方式可以重复使用,因此您也可以将其附加到菜单或其他项目。对于此示例,我们希望它始终可用,因此我们将其注册到我们的窗口Canvas中,如下所示:

    ctrlTab := desktop.CustomShortcut{KeyName: fyne.KeyTab, Modifier: desktop.ControlModifier}
    w.Canvas().AddShortcut(&ctrlTab, func(shortcut fyne.Shortcut) {
        log.Println("We tapped Ctrl+Tab")
    })

如您所见,以这种方式注册快捷方式有两个部分 - 传递快捷方式定义和回调函数。如果用户键入键盘快捷键,则将调用该函数并打印输出。
输入框(Entry)添加快捷方式
仅在当前项目获得焦点时应用快捷方式也很有帮助。这种方法可用于任何可聚焦的小部件,并通过扩展该小部件并添加TypedShortcut处理程序来管理。这很像添加键处理程序,除了传入的值将是fyne.Shortcut.

type myEntry struct {
    widget.Entry
}

func (m *myEntry) TypedShortcut(s fyne.Shortcut) {
    if _, ok := s.(*desktop.CustomShortcut); !ok {
        m.Entry.TypedShortcut(s)
        return
    }

    log.Println("Shortcut typed:", s)
}

您可以看到如何实现TypedShortcut处理程序。在此函数中,您应该检查快捷方式是否属于之前使用的自定义类型。如果快捷方式是标准快捷方式,最好调用原始快捷方式处理程序(如果小部件有一个)。完成这些检查后,您可以将快捷方式与您正在处理的各种类型(如果有多个)进行比较。

2.7 使用[Preferences] API

存储用户配置和值是应用程序开发人员的一项常见任务,但跨多个平台实现它可能是乏味且耗时的。为了使它更容易,Fyne 有一个 API 用于在文件系统上以一种清晰易懂的方式存储值,同时为您处理复杂的部分。
让我们从 API 的设置开始。它是Preferences接口的一部分,其中存在 Bool、Float、Int 和 String 值的存储和加载函数。它们每个都包含三个不同的功能,一个用于加载,一个用于加载备用值,最后一个用于存储值。下面是 String 类型的三个函数及其行为的示例:

// String looks up a string value for the key
String(key string) string
// StringWithFallback looks up a string value and returns the given fallback if not found
StringWithFallback(key, fallback string) string
// SetString saves a string value for the given key
SetString(key string, value string)

这些函数可以通过创建的应用程序变量和调用Preferences()方法来访问。请注意,必须创建具有唯一 ID 的应用程序(通常像反向 url)。这意味着需要使用创建应用程序app.NewWithID()来拥有自己的位置来存储值。它大致可以像下面的例子一样使用:

a := app.NewWithID("com.example.tutorial.preferences")
[...]
a.Preferences().SetBool("Boolean", true)
number := a.Preferences().IntWithFallback("ApplicationLuckyNumber", 21)
expression := a.Preferences().String("RegularExpression")
[...]

为了展示这一点,我们将构建一个简单的小应用程序,它总是在设定的时间后关闭。此超时应该是用户可更改的,并在应用程序的下一次启动时应用。
让我们首先创建一个名为的变量,该变量timeout将用于以 的形式存储时间time.Duration

var timeout time.Duration

然后我们可以创建一个选择小部件,让用户从几个预定义的字符串中选择超时,然后将超时乘以字符串相关的秒数。最后,该"AppTimeout"键用于将字符串值设置为选定的值。

timeoutSelector := widget.NewSelect([]string{"10 seconds", "30 seconds", "1 minute"}, func(selected string) {
    switch selected {
    case "10 seconds":
        timeout = 10 * time.Second
    case "30 seconds":
        timeout = 30 * time.Second
    case "1 minute":
        timeout = time.Minute
    }

    a.Preferences().SetString("AppTimeout", selected)
})

现在我们想要获取设置的值,如果不存在,我们想要一个后备,将超时设置为尽可能短的时间,以节省用户等待时的时间。这可以通过将 的选定值设置timeoutSelector为加载的值或在这种情况下的回退来完成。通过这样做,选择小部件内的代码将为该特定值运行。

timeoutSelector.SetSelected(a.Preferences().StringWithFallback("AppTimeout", "10 seconds"))

最后一部分将只是拥有一个在单独的 goroutine 中启动的函数,并告诉应用程序在选定的超时后退出。

go func() {
    time.Sleep(timeout)
    a.Quit()
}()

最后,生成的代码应如下所示:

package main

import (
    "time"

    "fyne.io/fyne/v2/app"
    "fyne.io/fyne/v2/widget"
)

func main() {
    a := app.NewWithID("com.example.tutorial.preferences")
    w := a.NewWindow("Timeout")

    var timeout time.Duration

    timeoutSelector := widget.NewSelect([]string{"10 seconds", "30 seconds", "1 minute"}, func(selected string) {
        switch selected {
        case "10 seconds":
            timeout = 10 * time.Second
        case "30 seconds":
            timeout = 30 * time.Second
        case "1 minute":
            timeout = time.Minute
        }

        a.Preferences().SetString("AppTimeout", selected)
    })

    timeoutSelector.SetSelected(a.Preferences().StringWithFallback("AppTimeout", "10 seconds"))

    go func() {
        time.Sleep(timeout)
        a.Quit()
    }()

    w.SetContent(timeoutSelector)
    w.ShowAndRun()
}

2.8 数据绑定

Fyne v2.0.0中引入了数据绑定,使将许多小部件连接到将随时间更新的数据源变得更加容易。该data/binding包有许多有用的绑定,可以管理将在应用程序中使用的大多数标准类型。可以使用绑定 API(例如NewString)来管理数据绑定,也可以将其连接到外部数据项,例如 (BindInt(*int))。
支持绑定的小部件通常有一个…WithData构造函数来在创建小部件时设置绑定。您还可以调用Bind()Unbind()管理现有小部件的数据。以下示例显示了如何管理String绑定到简单Label小部件的数据项。

package main

import (
    "time"

    "fyne.io/fyne/v2/app"
    "fyne.io/fyne/v2/data/binding"
    "fyne.io/fyne/v2/widget"
)

func main() {
    a := app.New()
    w := a.NewWindow("Hello")

    str := binding.NewString()
    go func() {
        dots := "....."
        for i := 5; i >= 0; i-- {
            str.Set("Count down" + dots[:i])
            time.Sleep(time.Second)
        }
        str.Set("Blast off!")
    }()

    w.SetContent(widget.NewLabelWithData(str))
    w.ShowAndRun()
}

2.9 编译选项

Fyne 通常会通过选择驱动程序和配置来为目标平台适当地配置您的应用程序。支持以下构建标签,它们可以帮助您的开发。例如,如果您希望在台式计算机上运行时模拟移动应用程序,您可以使用以下命令:

go run -tags mobile main.go
标签描述
gles强制使用嵌入式 OpenGL (GLES) 而不是完整的 OpenGL。这通常由目标设备控制,通常不需要。
hints显示改进或优化的开发人员提示。当您的应用程序不遵循材料设计或其他建议时,运行hints将记录下来。
mobile此标签在模拟的移动窗口中运行应用程序。当您想在移动平台上预览您的应用程序而不编译和安装到设备时很有用。
no_native_menus此标志专门用于 macOS,表示应用程序不应使用 macOS 原生菜单。相反,菜单将显示在应用程序窗口内。对于在 macOS 上测试应用程序以模拟 Windows 或 Linux 上的行为最有用。

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

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

相关文章

本地生活商城开发搭建 同城O2O线上线下推广

同城本地化商城目前如火如荼,不少朋友咨询本地生活同城平台怎么开发,今天商淘云与大家分享同城O2O线上商城的设计和开发。 本地生活商城一般会涉及到区域以及频道类,一般下单需要支持用户定位、商家定位,这样利于用户可以快速找到…

Leetcode 反转链表

使用递归 /*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode() {}* ListNode(int val) { this.val val; }* ListNode(int val, ListNode next) { this.val val; this.next next; }* }*/ class S…

音频3A——初步了解音频3A

文章目录 前言一、3A使用的场景和原理1.AEC2.AGC3.ANS/ANR4.硬件3A和软件3A的区别1)层级不同2)处理顺序不同3)优缺点 5.处理过程 二、3A带来的问题三、开源3A算法总结 前言 在日常的音视频通话过程中,说话的双端往往会面对比较复…

Davinci 大数据可视化分析

Davinci 大数据可视化分析 一、Davinci 架构设计1.1 Davinci定义1.2 Davinci 应用场景 二、Davinci 安装部署2.1 部署规划2.2 前置环境准备2.3 Davinci部署2.3.1 物料准备2.3.2 安装配置 2.4 环境变量配置2.5 初始化数据库2.5.1 创建数据库及用户 2.5.2 建表2.6 初始化配置 三、…

Java反射机制入门:解锁运行时类信息的秘密

反射技术: 其实就是对类进行解剖的技术 类中有什么?构造方法 成员方法成员变量 结论:反射技术就是把一个类进行了解剖,然后获取到 构造方法、成员变量、成员方法 反射技术的应用案例: idea框架技术:Spr…

网络安全-ssrf

目录 一、环境 二、漏洞讲解 三、靶场讲解 四、可利用协议 4.1 dict协议 4.2 file协议 4.3 gopher协议 五、看一道ctf题吧(长亭的比赛) 5.1环境 5.2开始测试 ​编辑 一、环境 pikachu,这里我直接docker拉取的,我只写原…

基于vue框架的传统文化传播网站设计与实现f7r43(程序+源码+数据库+调试部署+开发环境)系统界面在最后面。

系统程序文件列表 项目功能:用户,文化类型,传统文化 开题报告内容 基于Vue框架的传统文化传播网站设计与实现开题报告 一、研究背景 在全球化加速的今天,各国文化相互交融,但也面临着传统文化被边缘化的风险。中国拥有五千年文明史&#…

【通俗易懂介绍OAuth2.0协议以及4种授权模式】

文章目录 一.OAuth2.0协议介绍二.设计来源于生活三.关于令牌与密码的区别四.应用场景五.接下来分别简单介绍下四种授权模式吧1.客户端模式1.1 介绍1.2 适用场景1.3 时序图 2.密码模式2.1 介绍2.2 适用场景2.3时序图 3.授权码模式3.1 介绍3.2 适用场景3.3 时序图 4.简化模式4.1 …

数据的表示和存储 第3讲 C语言中的整数

深耕AI ​互联网行业 算法研发工程师 概括 本讲主要介绍了C语言中的整数表示。 无符号整数能够表示的最大值比带符号整数要大。带符号整数使用补码来表示,补码的运算系统是一种模运算系统,能够实现加减运算的统一。在C语言中,如果一个表达式…

利用F.interpolate()函数进行插值操作

函数简介 功能: 利用插值方法,对输入的张量数组进行上\下采样操作,换句话说就是科学合理地改变数组的尺寸大小,尽量保持数据完整。 torch.nn.functional.interpolate(input, sizeNone, scale_factorNone, modenearest, align_c…

【赵渝强老师】K8s的DaemonSets控制器

DaemonSet控制器相当于在节点上启动了一个守护进程。通过使用DaemonSet可以确保一个Pod的副本运行在 Node节点上。如果有新的Node节点加入集群,DaemonSet也会自动给新加入的节点增加一个Pod的副本;反之,当有Node节点从集群中移除时&#xff0…

EdgeRoute_镜像烧录

1. EdgeRouter 概述 EdgeRouter Lite 是由 Ubiquiti Networks 公司生产的一款高性能网络路由器,适用于家庭和小型办公环境。它的尺寸为200 x 90 x 30 mm,重量为345克,配备了双核500 MHz的MIPS64处理器,并带有硬件加速功能&#x…

MySQL_数据类型简介

课 程 推 荐我 的 个 人 主 页:👉👉 失心疯的个人主页 👈👈入 门 教 程 推 荐 :👉👉 Python零基础入门教程合集 👈👈虚 拟 环 境 搭 建 :&#x1…

Vue使用Vue Router路由:开发单页应用

1、路由基础 在单页 Web 应用中,整个项目只有一个 HTML 文件,不同视图(组件的模块)的内容都是在同一个页面中渲染的。当用户切换页面时,页面之前的跳转都是在浏览器端完成的,这时就需要使用前端路由。 路…

APP自动化中 ADB Monkey用法

一、monkey是干什么的? 我们可以使用monkey做手机端性能的压力测试,稳定性测试 二、monkey在使用的时候,他的运行特性 monkey默认配置下执行,会在手机中随机的点击或者轻触我们的手机中应用,不过这个时候&#xff0…

Cortex-M7核心寄存器

参考内容:Cortex-M7编程手册 文章目录 软件执行的处理器模式和权限级别处理器模式软件执行的权限级别 栈Stacks核心寄存器Core registers通用寄存器General-purpose registers链接寄存器Link register程序计数器 Program counter程序状态寄存器Program status regis…

PMP--二模--解题--91-100

文章目录 14.敏捷91、 [单选] 在敏捷团队完成三次迭代之后,项目经理确定团队在这三次迭代中的平均速度是30个故事点。还有292个故事点来完成项目的剩余部分。团队需要多少次额外的迭代才能完成项目? 9.资源管理92、 [单选] 项目经理前往另一个国家执行最…

python yield用法

1 yield关键字 yield在函数中的功能类似于return,不同的是yield每次返回结果之后函数并没有退出,而是 每次遇到yield关键字后返回相应结果,并保留函数当前的运行状态,等待下一次的调用。如果 一个函数需要多次循环执行一个动作&am…

【自动驾驶】控制算法(九)深度解析车辆纵向控制 | 从算法基础到 Carsim 仿真实践

写在前面: 🌟 欢迎光临 清流君 的博客小天地,这里是我分享技术与心得的温馨角落。📝 个人主页:清流君_CSDN博客,期待与您一同探索 移动机器人 领域的无限可能。 🔍 本文系 清流君 原创之作&…

『功能项目』QFrameWorkBug关联Slot(插槽)【67】

我们打开上一篇66QFrameWorkBug拖拽功能的项目, 本章要做的事情是关联插槽Slot 修改脚本:UISlot.cs 修改脚本:UGUICanvas.cs 此时关联Slot已经完成 接下来的文章内容: 1.QFrameWork扔到地上UGUI 2.位置存储功能 3.点击名称寻…