【Godot 4.2】Tree控件与TreeItem完全解析

news2024/11/17 23:24:41

概述

本篇是控件完全解析系列之一,主要总结一下Tree控件与TreeItem的使用。

Tree控件是一个非常强大的控件,尤其是在编写一些相关的程序或编辑器插件时,非常适合展示树形组织的节点型数据。

本篇将从简单的添加根节点,根节点子节点,设置文本和图标等等基础开始学习,尽量涵盖和串联TreeTreeItem所提供的API。

为Tree添加节点

这里的“节点”只是对TreeItem的一个通俗(但有歧义的)称呼,Tree控件的TreeItem并不算是一个真正意义上的Godot节点,行为方法也很节点不一样。因为它是直接继承自Object类型的,而不是Control,所以无法直接在场景面板中查看到,也无法直接用检视器面板添加和编辑。删除的时候也要使用free()方法。

为了尽量减少歧义,又符合通俗描述,我会在本文中尽量少的地方用“节点”的称呼,而是直接改用TreeItem

创建根节点

  • 我们可以使用Tree控件的create_item()方法创TreeItem
  • create_item()有一个参数,用于传入作为父节点的TreeItem,如果为null,则创建的TreeItem作为Tree根节点被添加。
  • create_item()返回对新建的TreeItem的引用,我们可以用一个变量接收,并通过这个变量继续设定TreeItem的属性或调用其方法。
# 创建根节点
var root:TreeItem = tree.create_item()
root.set_text(0,"root")   # 设定根节点文本
  • 这里我们使用TreeItemset_text()方法设定根节点root的文本
  • Tree控件可以显示多列信息,显示列数由其columns属性设定,默认为1,也就是只显示一列。
  • set_text()第一个参数是所在列的索引,默认为0

上面代码的效果:

image.png

创建根节点的子节点

  • 在添加根节点后,可以继续使用Tree控件的create_item()方法创建根节点的子节点,只是需要将根节点引用root作为父节点传入。
# 创建根节点
var root:TreeItem = tree.create_item()
root.set_text(0,"root")             # 设定根节点文本

# 创建根节点的子节点
var itm:TreeItem = tree.create_item(root)
itm.set_text(0,"子节点1")

上面代码的效果:

image.png

  • 除了直接用Tree控件的create_item()方法外,也可以直接利用已经创建的TreeItem(比如根节点)的create_child()方法来创建子节点。
# 创建根节点
var root:TreeItem = tree.create_item()
root.set_text(0,"root")             # 设定根节点文本

# 创建根节点的子节点
var itm:TreeItem = root.create_child()
itm.set_text(0,"子节点1")

两种方式得到的效果是一致的。

设定图标

使用TreeItemset_icon()方法,可以设定图标。同样第一个参数指定所在列。

var icon = preload("res://icon.svg")
# 创建根节点
var root:TreeItem = tree.create_item()
root.set_text(0,"root")   # 设定根节点文本
root.set_icon(0,icon)     # 设定根节点图标

上面代码效果:

image.png

设定图标最大宽度

  • 可以看到,单纯用set_icon()方法,只能在TreeItem上显示图标
  • 但是很多情况下我们会遇到图标尺寸不合适的情况,这时就需要用set_icon_max_width方法设定图标最大宽度了。
var icon = preload("res://icon.svg")
# 创建根节点
var root:TreeItem = tree.create_item()
root.set_text(0,"root")             # 设定根节点文本
root.set_icon(0,icon)               # 设定根节点图标
root.set_icon_max_width(0,30)       # 设定根节点图标宽度
  • Godot项目默认图标icon.svg尺寸为128×128像素,通过设定最大宽度为30,则图标将以30×30像素进行显示。
    image.png

使用SpriteSheet或打包纹理作为图标来源

  • SpriteSheet打包纹理都是一种常见的2D游戏或UI美术素材存储形式。SpriteSheet采用尺寸一致的行列划分,每一帧大小尺寸一致。而打包纹理,则是更自由的压缩存储多个大小不一的小图片。

  • 这里我使用如下的一个SpriteSheet来作为一个图标库,用来给不同的TreeItem显示不同的图标。

roller_sprites.png

  • 原图尺寸是900×150像素,单个图标的尺寸就是150×150像素。
  • 而我们将最终显示在TreeItem上的图标宽度限定为18像素,这样最终呈现的大小就是18×18像素。
var icon = preload("res://items.png") # 使用SpriteSheet或打包纹理
var cell_size = Vector2(150,150)      # 单元格尺寸

# ------ 创建根节点 ------ 
var root:TreeItem = tree.create_item()
root.set_text(0,"root")             # 设定根节点文本
root.set_icon(0,icon)               # 设定根节点图标
root.set_icon_max_width(0,18)       # 设定根节点图标宽度
var cell_pos = Vector2(0,0)         # 帧的位置
# 显示图片局部区域作为图标
root.set_icon_region(0,Rect2(cell_pos * cell_size,cell_size))

# ------ 为根节点创建5个子节点 ------ 
for i in range(5):
    var itm:TreeItem = root.create_child()
    itm.set_text(0,"item%d" % i)
    itm.set_icon(0,icon)               # 设定根节点图标
    itm.set_icon_max_width(0,18)       # 设定根节点图标宽度
    cell_pos = Vector2(i+1,0)         # 帧的位置
    itm.set_icon_region(0,Rect2(cell_pos * cell_size,cell_size))

效果:

image.png

对图标颜色进行调制

我们连接并处理Tree控件的item_selected信号。

image.png
信号处理函数代码如下:

# 处理Tree控件的item_selected信号
func _on_tree_item_selected():
	# 获取选中节点
	var selected_item:TreeItem = tree.get_selected()
	# 恢复其他节点的图标颜色
	var root:TreeItem = tree.get_root()
	root.set_icon_modulate(0,Color.WHITE)
	for itm in root.get_children():
		itm.set_icon_modulate(0,Color.WHITE)
	# 修改选中节点的图标颜色
	selected_item.set_icon_modulate(0,Color.BLUE)

运行后可以看到,选中项的图标颜色用蓝色调制的效果,没有使用额外的图标,而是通过颜色调制,做出了选中状态与非选中状态的图标差异效果。

调制图标颜色.gif

创建多列

启用和添加多列

Tree控件支持多列视图,其columns属性控制列的数目。我们可以在检视器面板直接修改,或者使用代码形式设定。

image.png

以下是代码形式:

# 设定显示两列信息
tree.columns = 2
# 创建根节点
var root:TreeItem = tree.create_item()
root.set_text(0,"root")             # 设定根节点第1列文本
root.set_text(1,"第2列")             # 设定第2列文本

我们通过设定第2列文本,就可以看到如下的效果:

image.png

每一列都可以像第1列一样设置图标或其他。

const icon = preload("res://icon.svg")
# 设定显示两列信息
tree.columns = 2
# 创建根节点
var root:TreeItem = tree.create_item()
root.set_text(0,"root")             # 设定根节点第1列文本
root.set_icon(0,icon)               # 设定第1列图标
root.set_icon_max_width(0,16)       # 设定第1列图标最大宽度
root.set_text(1,"第2列")             # 设定第2列文本
root.set_icon(1,icon)               # 设定第1列图标
root.set_icon_max_width(1,16)       # 设定第1列图标最大宽度

上面代码,我们为两列都设定的图标和图标最大宽度。

image.png

显示列标题

和一些其他可视化程序开发语言或数据表格软件的表格控件一样,Tree控件也可以显示列标题(或者通俗叫“字段”)。

你需要用代码或在检视器面板手动开启column_titles_visible

image.png

启用后就会在每列上方显示两个按钮,目前因为还没有设置其文本,所以是不完全的形态:

image.png

通过Treeset_column_title()方法,我们可以设定所有列标题按钮的文本:

# 设定和显示列标题
tree.column_titles_visible = true    # 显示列标题
tree.set_column_title(0,"第1列")     # 设定第1列列标题
tree.set_column_title(1,"第2列")     # 设定第2列列标题

上面代码设置后的效果:

image.png

是树型列表也是二维表格

我们为根节点添加一个子节点:

# 添加子节点
var itm:TreeItem = tree.create_item(root)
itm.set_text(0,"itm1")             # 设定根节点第1列文本
itm.set_icon(0,icon)               # 设定第1列图标
itm.set_icon_max_width(0,16)       # 设定第1列图标最大宽度
itm.set_text(1,"第2列")             # 设定第2列文本
itm.set_icon(1,icon)               # 设定第1列图标
itm.set_icon_max_width(1,16)       # 设定第1列图标最大宽度

此时的效果如下:

image.png

可以看到Tree的第一列保持了树形列表的特征,同时每一列的单元格都可以单独选中和交互。节点的折叠与展开也不受影响,表现出一种树形结构+二维表格的特性。

设定列标题文本对齐方式

  • 对列标题的,也可以设定其文本对齐方式,宽度等细节。

  • set_column_title_alignment设定列标题文本的对齐方式:

tree.set_column_title_alignment(0,HORIZONTAL_ALIGNMENT_LEFT)   # 居左显示

上面的代码设定第一列的列标题居左显示:

image.png

设定最小列宽

tree.set_column_custom_minimum_width(0,100)  # 设定第一列最小宽度

上面的代码设定第一列的最小宽度为100像素。
image.png

处理列标题点击

我们可以连接和处理Tree控件的column_title_clicked信号,来处理列标题的点击。

# 列标题被点击
func _on_tree_column_title_clicked(column, mouse_button_index):
	tree.select_mode = Tree.SELECT_MULTI # 设置多选模式
	# 获取Tree的所有节点
	var root:TreeItem = tree.get_root()
	var items = [root]
	items.append_array(root.get_children())
	
	# 选中指定列所有单元格
	for itm in items:
		for i in range(tree.columns):
			if i == column:
				itm.select(column)
			else:
				itm.deselect(i)

等价写法:

# 列标题被点击
func _on_tree_column_title_clicked(column, mouse_button_index):
	tree.select_mode = Tree.SELECT_MULTI # 设置多选模式
	# 获取Tree的所有节点
	var root:TreeItem = tree.get_root()
	var items = [root]
	items.append_array(root.get_children())
	
	tree.deselect_all()  # 清除所有选择
	# 选中指定列所有单元格
	for itm in items:
		itm.select(column)

上面的代码实现点击列标题时,选中当前列的所有单元格:

处理列标题按钮点击.gif

设定选择模式

Tree控件有三种选择模式,不同模式下选中TreeItem的效果哈方式不同,并且可能会影响某些信号的触发和处理。

检视器面板设定:

image.png

代码方式设定:

# 设定选择模式
tree.select_mode = Tree.SELECT_SINGLE # 单个单元格选择
tree.select_mode = Tree.SELECT_ROW    # 按行选择
tree.select_mode = Tree.SELECT_MULTI  # 多选

效果:
在这里插入图片描述

select_mode属性值效果
SELECT_SINGLE如果有多列,则一次只能单独选中某项的某列,也就是某个单元格
SELECT_ROW每次只能选中一行,也就是选中某项的所有列
SELECT_MULTI可以使用Ctrl或Shift键进行多选,一次可以选中多个单元格

创建按钮

在每列的单元格中都可以创建1个或多个按钮。按钮显示在单元格的最右侧,并且只显示一个图标,不显示文本。

但是可以设定其鼠标提示文本等。

这种按钮可以作为树控件单元格或行数据交互的一种形式。

const DIR = preload("res://custom_nodes/icons/dir.png")
# 创建根节点
var root:TreeItem = tree.create_item()
root.set_text(0,"root")             # 设定根节点第1列文本
root.set_icon(0,icon)               # 设定第1列图标
root.set_icon_max_width(0,16)       # 设定第1列图标最大宽度
root.add_button(0,DIR)   # 为根节点0列的单元格创建按钮
tree.set_column_custom_minimum_width(0,200)

上面的代码为两项的两列都添加了一个按钮。

image.png

处理按钮的点击

我们可以连接Treebutton_clicked信号,来处理单元格中添加的按钮的信号。
其参数返回:

  • item:按钮所在的TreeItem
  • column:按钮所在的列
  • id:按钮在所在单元格按钮中的ID或索引
  • mouse_button_index:点击按钮的鼠标按键,鼠标左键、中键、右键还是其他额外按键。
func _on_tree_button_clicked(item, column, id, mouse_button_index):
	if mouse_button_index == MOUSE_BUTTON_LEFT: # 鼠标左键
		match column:  # 某一列
			0,1:
				match id:   # 某按钮
					0:
						item.set_text(column,"")

上面的信号处理代码,可以让我们清空所在单元格的文本:

处理按钮点击.gif

快速编辑单元格文本

单元格可以进入文本编辑状态,显示一个可以编辑的文本框,从而可以快速修改单元格的文本内容,回车后完成编辑状态。

双击进入编辑状态

Treeitem_activated()信号在TreeItem或其某列单元格双击时触发。

我们通过连接此信号,创建信号处理函数,并设定如下的处理代码:

# 双击单元格
func _on_tree_item_activated():
	tree.edit_selected(true)  # 选中单元格进入编辑状态

此时,我们就可以通过双击单元格,进入单元格文本的编辑状态,修改完成后,回车确认,退出编辑状态:

双击编辑单元格文本.gif

编辑后的处理

  • Treeitem_edited()信号,在编辑完某个单元格并按回车确认后触发
  • Treeget_edited()方法可以获取当前编辑的TreeItem
  • 通过Treeget_edited_column()方法可以获取刚刚被编辑的TreeItem的列。

这里我只简单的打印输出单元格被修改后的文本:

# 单元格编辑完成后
func _on_tree_item_edited():
	var edt:TreeItem = tree.get_edited()    # 获取被编辑的TreeItem
	var col:int = tree.get_edited_column()  # 被编辑的列索引
	print(edt.get_text(col))                # 打印修改后的单元格文本

处理TreeItem或单元格选中

  • item_selected()信号,在TreeItem选中时触发,但仅在select_modeSELECT_ROWSELECT_SINGLE 时有效。
# TreeItem被选中或单击
func _on_tree_item_selected():
	print(tree.get_selected())
	pass
  • select_modeSELECT_MULTISELECT_SINGLE时,则可以响应cell_selected()信号。
# TreeItem的单元格被选中或点击
func _on_tree_cell_selected():
	var sel:TreeItem = tree.get_selected()    # 选中的单元格所在TreeItem
	var col:int = tree.get_selected_column()  # 选中的单元格列索引
	print(sel.get_text(col))

总结一下就是:

select_mode属性值item_selected()信号cell_selected()信号
SELECT_SINGLE
SELECT_ROW×
SELECT_MULTI×

用按钮控制Tree控件项的增、删、移动

我们创建一个如下的用户界面场景,创建一个Tree以及多个Button

通过这些按钮,我们实现为Tree控件添加、删除好移动项。

image.png

为场景根节点添加如下代码:

extends Control

@onready var tree = $HBoxContainer/Tree

@onready var add_btn = $HBoxContainer/VBoxContainer/addBtn
@onready var del_btn = $HBoxContainer/VBoxContainer/delBtn
@onready var moveup_btn = $HBoxContainer/VBoxContainer/moveupBtn
@onready var movedown_btn = $HBoxContainer/VBoxContainer/movedownBtn
@onready var clear_btn = $HBoxContainer/VBoxContainer/clearBtn


# 添加
func _on_add_btn_pressed():
	var parent:TreeItem = null
	if tree.get_root(): # 树不是空的
		if tree.get_selected(): # 有选中项
			parent = tree.get_selected()
		else:
			parent = tree.get_root()
	var itm = tree.create_item(parent)
	var idx:int = parent.get_child_count() if parent else 0
	itm.set_text(0,"新节点%d" % idx)


# 删除
func _on_del_btn_pressed():
	if tree.get_root(): # 树不是空的
		if tree.get_selected(): # 有选中项
			tree.get_selected().free()
	pass


# 上移
func _on_moveup_btn_pressed():
	var sel:TreeItem = tree.get_selected()
	if sel and sel.get_prev(): # 有选中项
		sel.move_before(sel.get_prev())

# 下移
func _on_movedown_btn_pressed():
	var sel:TreeItem = tree.get_selected()
	if sel and sel.get_next(): # 有选中项
		sel.move_after(sel.get_next())

# 清空
func _on_clear_btn_pressed():
	tree.clear()
	pass

可以看到其中主要是对按钮信号的处理代码,实现增、删,上下移动以及清空,效果如下动图所示:

按钮操控-添加.gif按钮操控-删除.gif
按钮操控-上移和下移.gif按钮操控-清空.gif

自由拖放

通过为Tree控件添加基本的控件拖放逻辑,就可以实现用鼠标对TreeItem的移动和放置。

extends Tree

func _get_drag_data(at_position):
	if get_tree(): # 不为空
		var sel:TreeItem = get_item_at_position(at_position)
		if sel: # 有选中项
			set_drag_preview(make_drag_preview(sel))
			return [sel]

func _can_drop_data(at_position, data):
	# 如果拖放数据是一个TreeItem就可以放置
	# 拖放完毕恢复拖动标志设定
	drop_mode_flags = DROP_MODE_ON_ITEM | DROP_MODE_INBETWEEN
	return data.size() > 0 and (data[0] is TreeItem)

func _drop_data(at_position, data):
	# 获取目标拖放位置,-1,0,1分别代表在某项之前、之上和之后
	var target_pos = get_drop_section_at_position(at_position)
	# 获取鼠标位置处的TreeItem
	var target_itm:TreeItem = get_item_at_position(at_position)
	# 如果目标位置处TreeItem是data[0]的子孙节点
	if target_itm in get_items(data[0]):
		return # 禁止移动
	match target_pos:
		-1: # 拖放到了某个TreeItem之前
			# 根据是否同级进行区别处理
			if data[0].get_parent() == target_itm.get_parent(): # 如果同级
				data[0].move_before(target_itm)
			else:
				data[0].get_parent().remove_child(data[0])         # 先从原来的父节点删除
				target_itm.add_child(data[0])                      # 添加到目标位置的TreeItem
				data[0].move_before(target_itm)
				
		0:  # 拖放到了某个TreeItem上
			data[0].get_parent().remove_child(data[0])         # 先从原来的父节点删除
			target_itm.add_child(data[0])                      # 添加到目标位置的TreeItem
		1: # 拖放到了某个TreeItem之后
			# 根据是否同级进行区别处理
			if data[0].get_parent() == target_itm.get_parent(): # 如果同级
				data[0].move_after(target_itm)
			else:
				data[0].get_parent().remove_child(data[0])         # 先从原来的父节点删除
				target_itm.add_child(data[0])                      # 添加到目标位置的TreeItem
				data[0].move_after(target_itm)

# 返回某个TreeItem下所有子孙节点的集合
func get_items(item:TreeItem) -> Array[TreeItem]:
	var arr:Array[TreeItem]
	if item.get_child_count()>0:
		arr.append_array(item.get_children())
		for chd in item.get_children():
			arr.append_array(get_items(chd))
	return arr

# 创建拖动预览
func make_drag_preview(itm:TreeItem) -> Button:
	var btn = Button.new()
	#btn.flat = true
	btn.text = itm.get_text(0)
	btn.icon = itm.get_icon(0)
	return btn

实现效果:

自由拖放.gif

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

低通滤波器(SMART PLC双线性变换法)

低通滤波器的详细介绍可以参考信号处理专栏,常用链接如下: 1、双线性变换+欧拉后向差分 https://rxxw-control.blog.csdn.net/article/details/128586285https://rxxw-control.blog.csdn.net/article/details/1285862852、博途PLC一阶低通滤波器 https://rxxw-control.blo…

设计模式学习笔记(二):工厂方法模式

一、定义 工厂方法模式(Factory Method Pattern)是一种创建型设计模式,它提供了一种在不指定具体类的情况下创建对象的方法。工厂方法模式定义了一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟…

大语言模型系列-GPT-3.5(ChatGPT)

文章目录 前言一、GPT-3.5的创新点二、GPT-3.5的训练流程SFT数据集RM数据集PPO数据集 三、ChatGPT的诞生总结 前言 《Training language models to follow instructions with human feedback,2022》 前文提到了GPT-3的缺点,其中最大的问题是&#xff1…

C++ 11 新特性 override和final

一.override和final介绍 在C11中,override和final是两个用于支持继承和多态的重要关键字。它们的具体作用如下: override:这个关键字用于派生类中,以确保虚函数的正确重写。当一个派生类的函数被声明为override时,编译…

【Ubuntu 20.04 / 22.04 LTS】最新 esp-matter SDK 软件编译环境搭建步骤

仓库链接:esp-matter SDK官方软件说明:ESP Matter Programming Guide官方参考文档:使用 Matter-SDK 快速搭建 Matter 环境 (Linux) 环境要求 Ubuntu 20.04 或 Ubuntu22.04网络环境支持访问 Gihub 在安装 esp-matter SDK 软件编译环境之前&a…

基于C++中netCDF库读取.nc数据时的一些坑

本文介绍基于C 语言的netCDF库读取.nc格式的栅格文件时,出现数据无法读取、数据读取错误、无法依据维度提取变量等情况的原因与解决方法。 最近,由于需要读取ERA5气象数据,因此使用C语言中的netCDF库读取.nc格式文件;这其中也是踩…

Docker基础教程 - 7 容器数据卷

更好的阅读体验:点这里 ( www.doubibiji.com ) 7 容器数据卷 什么是容器卷,为什么需要容器卷? 我们在运行容器的时候,产生的数据都是保存在容器内部的。如果使用Docker来运行mysql容器,数据…

网络性能优化工具

网络优化是 IT 行业的一个重要方面,网络很复杂,管理员努力保持其平稳运行,然而,网络环境也是不可预测和动态的,任何未受监控的问题都可能像滚雪球一样变成中断。 优化网络性能需要引入: 新设备和应用程序…

Axure RP 10:让原型设计更快、更直观、更智能 mac版

Axure RP 10是一款强大的原型设计工具,它能够帮助设计师快速创建高保真、交互式的原型,从而更好地展示和测试设计方案。这款软件凭借其直观易用的界面和丰富的功能,已经成为了许多设计师的首 选工具。 Axure RP 10 for Mac版软件获取 首先&a…

还在使用 RESTful API ? 试一试 GraphQL

前言 GraphQL 和 RESTful API 是两种不同的网络通信接口设计理念,它们都可以用于客户端和服务器之间的数据交换,但是有着不同的工作方式和特点。 各自的特点以及优缺点 GraphQL: 特点: 查询语言: GraphQL 是一个查询语言&…

【MySQL 系列】MySQL 架构篇

在我们开始了解 MySQL 核心功能之前,首先我们需要站在一个全局的视角,来看 SQL 是如何运作执行的。通过这种方式,我们可以在头脑中构建出一幅 MySQL 各组件之间的协同工作方式,有助于我们加深对 MySQL 服务器的理解。 文章目录 1、…

DEYO: DETR with YOLO for End-to-End Object Detection论文翻译

DEYO:DETR与YOLO用于端到端目标检测 摘要 DETR的训练范式在很大程度上取决于在ImageNet数据集上预训练其骨干。然而,由图像分类任务和一对一匹配策略提供的有限监督信号导致DETR的预训练不充分的颈部。此外,在训练的早期阶段匹配的不稳定性会…

利用Cocos游戏开发中的跑马灯祝女神们节日快乐

点击上方亿元程序员+关注和★星标 引言 Cocos游戏开发中的跑马灯广播效果 大家好,今天是国际劳动妇女节,也就是我们如今熟知的女神节。 今天打算通过游戏开发中的跑马灯广播这最直接的方式祝女神们节日快乐! 跑马灯作为游戏中常见的UI元素,通常被用来展示重要的信息或者…

Gafana Redis Overview dashboard

1. 简介 根据提供的 Redis 监控仪表盘 JSON 文件,包含的监控指标及其简要描述如下: redis_uptime_in_seconds: Redis 实例的运行时间(秒)。 redis_connected_clients: 当前连接到 Redis 实例的客户端数量。 redis_memory_used_bytes: Redis 实例使用的内存量(字节)。 redis_m…

Qt + mqtt对接阿里云平台(一)

一、阿里云平台 官网:点击跳转 二、创建产品与设备 1、“公共实例” 2、“设备管理”->“产品”->“创建产品” 3、“产品名称”->“自定义品类”->"确认" 4、“前往添加” 5、“添加设备” 6、摄入DeviceName和备注名称 7、"前往查…

css-vxe-form-item中输入框加自定义按钮(校验位置错误)

1.浮动错误效果 提示内容不对 2.不使用浮动&#xff0c;使用行内块元素 代码如下 <vxe-form-item title"yoyo:" field"assembleWorkNo" span"8"><template #default><vxe-input style"width:70%;display:inline-block;&quo…

Linux之cd、pwd、mkdir 命令

cd命令&#xff0c;切换目录 1&#xff09;当Linux终端&#xff08;命令行&#xff09;打开的时候&#xff0c;会默认以用户的HOME目录作为当前的工作目录。 2&#xff09;我们可以通过cd命令&#xff0c;更改当前所在的工作目录。 3&#xff09;cd命令来自英文&#xff1a;C…

基于FPGA的PSRAM接口设计与实现

一 PSRAM与HyperRAM 1、概述 2、异同 待完善 二 PSRAM分析 1、特性 1、关键点 待完善 三 PSRAM方案设计与验证 待完善 1、整体方案设计 2、验证 仿真工具采用VCSVerdi&#xff0c;PSRAM接口控制IPAPS6408L model进行验证。 四 结论 备注&#xff1a;以AP公司的APS6408L…

IP传输方式——组播

组播作为IP传输三种方式之一&#xff0c;指的是报文从一个源发出&#xff0c;被转发到一组特定的接收者&#xff0c;相同的报文在每条链路上最多有一份。相较于传统的单播和广播&#xff0c;组播可以有效地节约网络带宽、降低网络负载&#xff0c;所以被广泛应用于IPTV、实时数…

mysql如何开启远程访问?

MySQL是一种常见的关系型数据库管理系统&#xff0c;广泛应用于各行各业。默认情况下&#xff0c;MySQL仅允许本地访问&#xff0c;即只能在本地主机上进行数据库操作。有时候我们需要通过远程连接访问MySQL数据库&#xff0c;以便实现更灵活的管理和操作。本文将介绍如何在MyS…