Unity【GUI】基础知识

什么是UI系统

Ul是UserInterface(用户界面)的简称

系统的主要学习内容

1.UI控件的使用
2.U控件的事件响应 
3.U的分辨率自适应

文章目录

  • 基础知识
    • 1、工作原理和主要作用
    • 2、基本控件
      • 1、文本和按钮控件
      • 2、多选框和单选框
      • 3、输入框和拖动条
      • 4、图片绘制和框
    • 3、复合控件
      • 1、工具栏和选择网格
      • 2、滚动视图和分组
      • 3、窗口相关
    • 4、自定义整体样式
      • 1、GUIskin
      • 2、GUILayout
  • 实践小项目
    • 1、需求分析
    • 2、九宫格布局概念
    • 3、控件位置信息类
    • 4、控件父类
    • 5、父对象控制绘制顺序
    • 6、自定义常用控件
      • 1、自定义文本和按钮
      • 2、自定义多选框
      • 3、自定义多选框控件(单选)
      • 4、自定义输入框和拖动条
      • 5、自定义图片绘制

基础知识

1、工作原理和主要作用

1、GUI概念

即时模式游戏用户交互界面(IMGUI)
在Unity简称GUI
它是一个代码驱动的UI系统

2、GUI作用

1,作为程员的调试,创建游戏内调试身
2.为脚本组件创建自定义检视面板
3.创建新的编辑器窗口和工具以拓展Unity本身(一般用作内置游戏工具)

3、GUI的工作原理

在继承MonoBehaviour的脚本中的特殊函数里
调用GUI提供的方法,类似生命周期函数
    private void OnGUI()
    {
        //在其中书写GUI相关代码即可显示GUI内容
    }
注意:
	1.它每顿热行相当于是用于专门绘制GUI界面的函数
    2:一般只在其中执行GUI相关界面绘制和操作逻辑
	3.该函数在【OnDisable】之前【LateUpdate】之后执行
    4.只要是继承Mono的脚本都可以在OnGUI中绘制GUI

2、基本控件

在这里插入图片描述

1、文本和按钮控件

1、GUI控件绘制的共同点

1.他们都是GUI公共类中提供的静态函数,直接调用即可
2.他们的参数都大同小异
    位置参数:Rect参数 x y位置 w h尺寸
    显示文本:string参数
    图片信息:Texture参数
    综合信息:GUIContent参数
    自定义样式:GUIStyle参数
3.每一种控件都有多种重载,都是各个参数的排列组合
	必备的参数内容是【位置信息】和【显示信息】

2、文本控件

public Rect rect; //位置
public Texture text; //图片
public GUIContent content; //综合使用
public GUIStyle style; //自定义样式

private void OnGUI()
{
    1、基本使用
        GUI.Label(new Rect(0, 0, 100, 20), "文本控件");
        GUI.Label(rect, text);
    2、综合使用 (左图,右文字)
        GUI.Label(rect, content);
    3、获取GUI控件对应的信息
        Debug.Log(GUI.tooltip);
    4、自定义样式
        GUI.Label(new Rect(0, 0, 100, 20), "文本控件", style);
    	字体路径 C:\Windows\Fonts
}

3、按钮控件

public Rect btnRect;
public GUIContent btnContent;
public GUIStyle btnStyle;

private void OnGUI()
{
    if(GUI.Button(btnRect, btnContent, btnStyle))
    //Button 按下抬起算一次点击
    //RepeatButton 长按,一直返回true
    {
        Debug.Log("按钮被点击");
    }
}

2、多选框和单选框

1、多选框

普通样式
     private bool isSel;

     private void OnGUI()
     {
         isSel = GUI.Toggle(new Rect(0, 0, 100, 30), isSel, "效果开关");
     }

自定义样式
    修改固定宽高 fixedWidth 和 fixedHeight
    修改从GUIStyle边缘到内容起始处的空间 padding

2、单选框

private int nowSelIndex = 1;

private void OnGUI()
{
    //Toggle点击后返回true
    if(GUI.Toggle(new Rect(0, 100, 100, 20), nowSelIndex == 1, "选项一"))
        nowSelIndex = 1;
    if (GUI.Toggle(new Rect(0, 140, 100, 20), nowSelIndex == 2, "选项二"))
        nowSelIndex = 2;
    if (GUI.Toggle(new Rect(0, 180, 100, 20), nowSelIndex == 3, "选项三"))
        nowSelIndex = 3;
}

3、输入框和拖动条

1、输入框

普通输入
    private string inputStr;
    private void OnGUI()
    {
        //5为最大输入长度
        inputStr = GUI.TextField(new Rect(0, 0, 100, 30), inputStr,5);
    }
密码输入
    private string inputPW;
    private void OnGUI()
    {
        inputPW = GUI.PasswordField(new Rect(0, 0, 100, 30), inputPW, '*');
    }

2、拖动条

水平拖动条
    private float nowValue = 0.5f;
    private void OnGUI()
    {
        nowValue = GUI.HorizontalSlider(new Rect(0, 100, 100, 50), nowValue, 0, 1);
    }
竖直拖动条
    nowValue = GUI.VerticalSlider(new Rect(0, 150, 50, 100), nowValue, 0, 1);

4、图片绘制和框

1、图片绘制

public Rect texPos;
public Texture tex;
public ScaleMode mode; //显示模式
	//ScaleAndCrop: 通过宽高裁剪
	//ScaleToFit: 缩放不会变形
	//ScaleToFill: 填充满宽高(默认)
public bool alpha; //背景是否透明
private void OnGUI()
{
    GUi.DrawTexture(texPos, tex, mode, alpha);
}

2、框绘制

GUI.Box(texPos, "");

3、复合控件

在这里插入图片描述

1、工具栏和选择网格

1、工具栏

private int toolbarIndex = 0;
private string[] toolbarInfos = new string[] { "选项一", "选项二", "选项三" };

private void OnGUI()
{
    toolbarIndex = GUI.Toolbar(new Rect(0, 0, 200, 30), toolbarIndex, toolbarInfos);
}
private void DrawWindow(int id)
{
    switch (id)
    {
        case 1:
            GUI.Button(new Rect(0, 30, 30, 20), "按钮1");
            break;
        case 2:
            GUI.Button(new Rect(0, 30, 30, 20), "按钮2");
            break;
        case 3:
            GUI.DragWindow();
            break;
    } 
}

2、选择网格

private int selGridIndex = 0;
private void OnGUI()
{
    //xCount 水平方向最多显示数量,超过的另起一行
    selGridIndex = GUI.SelectionGrid(new Rect(0, 50, 200, 90), selGridIndex, toolbarInfos, 1);
}

2、滚动视图和分组

1、分组

用于批量控制空间位置
public Rect groupPos;
private void OnGUI()
{
    GUI.BeginGroup(groupPos);
    GUI.Button(new Rect(0, 0, 100, 50), "按钮");
    GUI.Label(new Rect(0, 60, 100, 20), "Lable");
    GUI.EndGroup();
}

2、滚动列表

public Rect scPos; //可视范围
public Rect showPos; //内容
private Vector2 nowPos;
private string[] strs = new string[] { "选项一", "选项二", "选项三" };

private void OnGUI()
{
    nowPos = GUI.BeginScrollView(scPos, nowPos, showPos);
    GUI.Toolbar(new Rect(0, 0, 300, 50), 0, strs);
    GUI.EndScrollView();
}

3、窗口相关

1、窗口

private void DrawWindow(int id)
{
    GUI.Button(new Rect(0, 30, 30, 20), "按钮");
}
private void OnGUI()
{
    //参数1:id
    GUI.Window(1, new Rect(100, 100, 200, 150), DrawWindow, "窗口");
}

2、模态窗口

优先处理窗口(警告窗口)
    GUI.ModalWindow(2, new Rect(100, 100, 200, 150), DrawWindow, "模态窗口");

3、拖动窗口

dragWinPos = GUI.Window(3, dragWinPos, DrawWindow, "窗口");
//参数用来设置可拖动位置
private void DrawWindow(int id)
{
	GUI.DragWindow();
}

4、自定义整体样式

在这里插入图片描述

1、GUIskin

1、全局颜色

全局着色,影响背景和文本颜色
    GUI.color = Color.red;
文本着色
    GUI.contentColor = Color.yellow;
背景元素着色
    GUI.backgroundColor = Color.red;
注意:会和全局颜色相乘

2、整体皮肤样式

public GUISkin skin;
	GUI.skin = skin;

2、GUILayout

1、GUILayout 自动布局

GUILayout.BeginArea(new Rect(100,100,100,100)); //设置整体位置,宽高为可见范围
//GUI.BeginGroup(new Rect(100,100,100,100)); GUI综合使用
GUILayout.BeginHorizontal(); //水平布局
GUILayout.BUtton("按钮");
GUILayout.Endorizontal();
GUILayout.EndArea;
GUI.EndGroup();

2、GUILayoutOption 布局选项

GUILayout.BUtton("按钮",GUILayout.With(300));

控件的固定宽高
	GUILayout.Width(300); GUILayout.Height(200); 
充许控件的最小宽高
	GuILayout.Minwidth(50); GuILayout.MinHeight(50));
充许控件的最大宽高
	GuILayout.Maxwidth(100) GUILayout.MaxHeight(100)); 
充许或禁止水平拓展
	GuILayout.Expandwidth(true); //允许
    GUILayout.ExpandHeight(false); //禁止
    GUILayout.ExpandHeight(true); //允许
    GUILayout.ExpandHeight(false); //禁止

编辑模式下让指定代码运行

添加特性
	[ExecuteAlways]

实践小项目

1、需求分析

1、位置信息类

位置信息类
    中心点位置
    偏移位置
    宽高
    最终位置

    中心点对齐方式
    屏幕对齐方式

2、控件基类

控件基类
    位置信息
    内容信息
    自定义样式

    是否开启自定义样式

2、九宫格布局概念

九宫格原点:
    左上(0,0)(w/2,0)    右上(w,0)(0,h/2)(w/2,h/2)(w,h/2)
    左下(0,h)(w/2,h)    右下(w,h)

控件位置:
    (0,0)      (-cw/2,0)      (-cw,0)
    (0,-ch/2)  (-cw/2,-ch/2)  (-cw,-ch/2)
    (0,-ch)    (-cw/2,-ch)    (-cw,-ch)

控件坐标计算公式:
	相对屏幕位置 + 中心点偏移位置 + 偏移位置

3、控件位置信息类

CustomGUIPos

using UnityEngine;

public enum E_Alignment_Type
{
    Up, Down, Left, Right,
    Center,
    Left_Up, Left_Down, Right_Up, Right_Down,
}

public class CustomGUIPos
{
    private Rect rpos = new Rect(0, 0, 100, 100);

    //屏幕九宫格对齐方式
    public E_Alignment_Type screen_Alignment_Type;
    //控件中心对齐方式
    public E_Alignment_Type control_Center_Alignment_Type;
    //偏移位置
    public Vector2 pos;
    //控件宽高
    public float width = 100;
    public float height = 50;
    //中心点
    private Vector2 centerPos;
    //控件中心点偏移位置
    private void CalcCenterPos()
    {
        switch (control_Center_Alignment_Type)
        {
            case E_Alignment_Type.Up:
                centerPos.x = -width / 2;
                centerPos.y = 0;
                break;
            case E_Alignment_Type.Down:
                centerPos.x = -width / 2;
                centerPos.y = -height;
                break;
            case E_Alignment_Type.Left:
                centerPos.x = 0;
                centerPos.y = -height / 2;
                break;
            case E_Alignment_Type.Right:
                centerPos.x = -width;
                centerPos.y = -height / 2;
                break;
            case E_Alignment_Type.Center:
                centerPos.x = -width / 2;
                centerPos.y = -height / 2;
                break;
            case E_Alignment_Type.Left_Up:
                centerPos.x = 0;
                centerPos.y = 0;
                break;
            case E_Alignment_Type.Left_Down:
                centerPos.x = 0;
                centerPos.y = -height;
                break;
            case E_Alignment_Type.Right_Up:
                centerPos.x = -width;
                centerPos.y = 0;
                break;
            case E_Alignment_Type.Right_Down:
                centerPos.x = -width;
                centerPos.y = -height;
                break;
        }
    }
    //最终位置
    private void CalcPos()
    {
        switch (screen_Alignment_Type)
        {
            case E_Alignment_Type.Up:
                //相对屏幕位置 + 中心点偏移位置 + 偏移位置
                rpos.x = Screen.width / 2 + centerPos.x + pos.x;
                rpos.y = 0 + centerPos.y + pos.y;
                break;
            case E_Alignment_Type.Down:
                rpos.x = Screen.width / 2 + centerPos.x + pos.x;
                rpos.y = Screen.height + centerPos.y - pos.y;
                break;
            case E_Alignment_Type.Left:
                rpos.x = 0 + centerPos.x + pos.x;
                rpos.y = Screen.height / 2 + centerPos.y + pos.y;
                break;
            case E_Alignment_Type.Right:
                rpos.x = Screen.width + centerPos.x - pos.x;
                rpos.y = Screen.height / 2 + centerPos.y + pos.y;
                break;
            case E_Alignment_Type.Center:
                rpos.x = Screen.width / 2 + centerPos.x + pos.x;
                rpos.y = Screen.height / 2 + centerPos.y + pos.y;
                break;
            case E_Alignment_Type.Left_Up:
                rpos.x = centerPos.x + pos.x;
                rpos.y = centerPos.y + pos.y;
                break;
            case E_Alignment_Type.Left_Down:
                rpos.x = centerPos.x + pos.x;
                rpos.y = Screen.height + centerPos.y - pos.y;
                
                break;
            case E_Alignment_Type.Right_Up:
                rpos.x = Screen.width + centerPos.x - pos.x;
                rpos.y = centerPos.y + pos.y;
                break;
            case E_Alignment_Type.Right_Down:
                rpos.x = Screen.width + centerPos.x - pos.x;
                rpos.y = Screen.height + centerPos.y - pos.y;
                break;
        }
    }
    public Rect Pos
    {
        get
        {
            //计算中心点偏移
            CalcCenterPos();
            //相对屏幕坐标点
            CalcPos();
            //修改控件的宽高
            rpos.width = width;
            rpos.height = height;
            return rpos;
        }
    }
}

4、控件父类

CustomGUIControl

using UnityEngine;

public enum E_style_OnOff
{
    On,Off,
}
public class CustomGUIControl : MonoBehaviour
{
    //位置信息
    public CustomGUIPos guiPos;
    //显示内容信息
    public GUIContent content;
    //自定义样式
    public GUIStyle style;
    //自定义样式开关
    public E_style_OnOff styleOn_or_Off = E_style_OnOff.Off;

    private void OnGUI()
    {
        switch (styleOn_or_Off)
        {
            case E_style_OnOff.On:
                StyleOnDraw();
                break;
            case E_style_OnOff.Off:
                StyleOffDraw();
                break;
        }
    }

    protected virtual void StyleOnDraw()
    {
        //GUI.Button(guiPos.Pos, content, style);
    }
    protected virtual void StyleOffDraw()
    {
        //GUI.Button(guiPos.Pos, content);
    }
}

5、父对象控制绘制顺序

修改CustomGUIControl

//public void OnGUI()修改为
public void DrawGUI(){}

CustomGUIRoot

using UnityEngine;

[ExecuteAlways] //编辑模式下能看到GUI
public class CustomGUIRoot : MonoBehaviour
{
    //存储子对象所有的GUI控件的容器
    private CustomGUIControl[] allControls;
    void Start()
    {
        allControls = this.GetComponentsInChildren<CustomGUIControl>();
    }
    //同一绘制子对象控件
    private void OnGUI()
    {
        if (!Application.isPlaying)
        {
            //得到父类脚本
            allControls = this.GetComponentsInChildren<CustomGUIControl>();
        }

        //可以控件控件的绘制顺序
        for (int i = 0; i < allControls.Length; i++)
        {
            //绘制每个控件
            allControls[i].DrawGUI();
        }
    }
}

6、自定义常用控件

1、自定义文本和按钮

CustomGUILable

using UnityEngine;

public class CustomGUILable : CustomGUIControl
{
    protected override void StyleOffDraw()
    {
        GUI.Label(guiPos.Pos, content);
    }

    protected override void StyleOnDraw()
    {
        GUI.Label(guiPos.Pos, content, style);
    }
}

CustomGUIButton

using UnityEngine;
using UnityEngine.Events;

public class CustomGUIButton : CustomGUIControl
{
    public event UnityAction clickEvent;
    protected override void StyleOffDraw()
    {
        if (GUI.Button(guiPos.Pos,content))
        {
            clickEvent?.Invoke();
        }
    }

    protected override void StyleOnDraw()
    {
        if (GUI.Button(guiPos.Pos, content, style))
        {
            clickEvent?.Invoke();
        }
    }
}

2、自定义多选框

CustomGUIToggle

using UnityEngine;
using UnityEngine.Events;

public class CustomGUIToggle : CustomGUIControl
{
    public bool isSel;
    public event UnityAction<bool> changeValue;
    private bool isOldSel;
    protected override void StyleOffDraw()
    {
        isSel = GUI.Toggle(guiPos.Pos, isSel, content);
        if(isOldSel != isSel )
        {
            changeValue?.Invoke(isSel);
            isOldSel = isSel;
        }
    }

    protected override void StyleOnDraw()
    {
        isSel = GUI.Toggle(guiPos.Pos, isSel, content, style);
        if (isOldSel != isSel)
        {
            changeValue?.Invoke(isSel);
            isOldSel = isSel;
        }
    }
}

3、自定义多选框控件(单选)

CustomGUIToggleGroup

using UnityEngine;

public class CustomGUIToggleGroup : MonoBehaviour
{
    public CustomGUIToggle[] toggles;
    private CustomGUIToggle frontTrueTog;
    void Start()
    {
        if (toggles.Length == 0)
            return;
        for (int i = 0; i < toggles.Length; i++)
        {
            CustomGUIToggle toggle = toggles[i];
            toggle.changeValue += (value) =>
            {
                if(value)
                {
                    for (int j = 0; j < toggles.Length; j++)
                    {
                        //其他的变false
                        if (toggles[j] != toggle)
                        {
                            toggles[j].isSel = false;
                        }
                    }
                    frontTrueTog = toggle;
                }
                else if (toggle == frontTrueTog)
                {
                    toggle.isSel = true;
                }
            };
        }
    }
}

4、自定义输入框和拖动条

CustomGUIInput

using UnityEngine;
using UnityEngine.Events;

public class CustomGUIInput : CustomGUIControl
{
    public event UnityAction<string> textChange;
    private string oldStr = "";
    protected override void StyleOffDraw()
    {
        content.text = GUI.TextField(guiPos.Pos,content.text);
        if(oldStr != content.text)
        {
            textChange?.Invoke(oldStr);
            oldStr = content.text;
        }
    }

    protected override void StyleOnDraw()
    {
        content.text = GUI.TextField(guiPos.Pos, content.text, style);
        if (oldStr != content.text)
        {
            textChange?.Invoke(oldStr);
            oldStr = content.text;
        }
    }
}

CustomGUISlider

using UnityEngine;
using UnityEngine.Events;

public enum E_Slider_Type
{
    Horizontal, //水平
    Vertical, //竖直
}
public class CustomGUISlider : CustomGUIControl
{
    public float minValue = 0;
    public float maxValue = 1;
    public float nowValue = 0;
    public E_Slider_Type type = E_Slider_Type.Horizontal;
    public GUIStyle styleThumb; //小按钮的style
    public event UnityAction<float> changeValue;
    private float oldValue = 0;
    protected override void StyleOffDraw()
    {
        switch (type)
        {
            case E_Slider_Type.Horizontal:
                nowValue = GUI.HorizontalSlider(guiPos.Pos, nowValue, minValue, maxValue);
                break;
            case E_Slider_Type.Vertical:
                nowValue = GUI.VerticalSlider(guiPos.Pos, nowValue, minValue, maxValue);
                break;
        }
        if (oldValue!=nowValue)
        {
            changeValue?.Invoke(nowValue);
            oldValue = nowValue;
        }

    }

    protected override void StyleOnDraw()
    {
        switch (type)
        {
            case E_Slider_Type.Horizontal:
                nowValue = GUI.HorizontalSlider(guiPos.Pos, nowValue, minValue, maxValue, style, styleThumb);
                break;
            case E_Slider_Type.Vertical:
                nowValue = GUI.VerticalSlider(guiPos.Pos, nowValue, minValue, maxValue, style, styleThumb);
                break;
        }
        if (oldValue != nowValue)
        {
            changeValue?.Invoke(nowValue);
            oldValue = nowValue;
        }
    }
}

5、自定义图片绘制

CustomGUITexture

using UnityEngine;

public class CustomGUITexture : CustomGUIControl
{
    public ScaleMode scaleMode = ScaleMode.StretchToFill;
    protected override void StyleOffDraw()
    {
        GUI.DrawTexture(guiPos.Pos,content.image, scaleMode);
    }

    protected override void StyleOnDraw()
    {
        GUI.DrawTexture(guiPos.Pos, content.image, scaleMode);
    }
}

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

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

相关文章

[图解]SysML和EA建模住宅安全系统-03-现有运营领域-图标表示结构

1 00:00:01,590 --> 00:00:04,260 接下来&#xff0c;我们来看图17.8 2 00:00:05,590 --> 00:00:08,430 图17.8跟图17.7是一样的 3 00:00:08,440 --> 00:00:14,610 它也是描述运营领域现状的一个BDD 4 00:00:16,150 --> 00:00:18,340 但是它用图标来表示 5 00:…

2000-2022年 省、市、县三级逐年归一化植被指数NDVI

NDVI&#xff08;归一化植被指数&#xff09;是一种重要的遥感指数&#xff0c;广泛应用于植被生长状况的监测和评估。以下是对省、市、县三级逐年归一化植被指数NDVI数据的介绍&#xff1a; 数据简介 定义&#xff1a;NDVI是一种基于植被在红光和近红外波段反射特性的遥感指…

财务RPA与数字化转型——财务RPA如何促进企业的数字化转型

在数字化时代&#xff0c;企业面临着推动创新、提高效率的巨大挑战。RPA财务机器人作为智慧财务不可或缺的新动能&#xff0c;不仅能够优化财务流程&#xff0c;还能够在整个企业中引领数字化变革。本文金智维将深入探讨财务RPA如何成为企业数字化转型的战略利器&#xff0c;为…

WordPress Quiz Maker插件 SQL注入漏洞复现(CVE-2024-6028)

0x01 产品简介 WordPress Quiz Maker插件是一款功能强大的测验生成工具,旨在帮助用户轻松、快速地构建复杂的测验和考试。插件支持多种问题类型,包括单选框(MCQ)、复选框(MCQ)、下拉列表(MCQ)、文本、短文本、数字、日期等。还支持横幅(HTML)显示信息性消息、填空题…

Java应用cpu过高如何分析

1. 查看进程cpu使用情况 top 2. 根据PID查看指定进程的各线程的cpu使用情况 top -H -p PID

使用 Compose Multiplatform Media Player 实现跨平台媒体播放

使用 Compose Multiplatform Media Player 实现跨平台媒体播放 在跨平台开发中,媒体播放功能是一个常见且重要的需求。Compose Multiplatform Media Player 是一个专为 Compose Multiplatform 项目设计的强大媒体播放器库,它可以在 iOS 和 Android 平台上无缝实现视频播放、…

小程序驾校预约系统的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;学员管理&#xff0c;教练管理&#xff0c;驾校信息管理&#xff0c;驾校车辆管理&#xff0c;教练预约管理&#xff0c;考试信息管理 微信端账号功能包括&#xff1a;系统首页&#xff0c;驾校信息&am…

python--基础篇--正则表达式--py脚本--题目解答

文章目录 验证输入用户名和QQ号是否有效并给出对应的提示信息从一段文字中提取出国内手机号码替换字符串中的不良内容拆分长字符串 验证输入用户名和QQ号是否有效并给出对应的提示信息 """ 验证输入用户名和QQ号是否有效并给出对应的提示信息要求&#xff1a;用…

智能农业技术:物联网、无人机与机器人引领的绿色革命

在这个信息化与智能化并行的时代&#xff0c;农业——这个最古老的人类产业&#xff0c;正经历一场前所未有的科技变革。物联网&#xff08;IoT&#xff09;、无人机&#xff08;UAV&#xff09;和机器人技术的深度融合&#xff0c;正逐步构建起一个高效、精准、可持续的现代农…

华为HCIP Datacom H12-821 卷18

1.问答题 (拖拽题)如图所示,请根据 DHCPv6 的四歩交互流程, 将报文按照顺序拖拽到相应的位置 参考答案: 1--solicit ,2--advertise , 3--equest, 4--reply 解析: DHCPv6的报文交互流程,类似于V4,先组播发现,服

静态链表详解(C语言版)

顺序表和链表的优缺点 顺序表和链表是两种基本的线性数据结构&#xff0c;它们各自有不同的优缺点&#xff0c;适用于不同的应用场景。 顺序表&#xff08;Sequential List&#xff0c;通常指数组&#xff09; 优点&#xff1a; 随机访问&#xff1a;可以通过索引快速访问任…

【前端】简易化看板

【前端】简易化看板 项目简介 看板分为三个模块&#xff0c;分别是待办&#xff0c;正在做&#xff0c;已做完三个部分。每个事件采取"卡片"式设计&#xff0c;支持任务间拖拽&#xff0c;删除等操作。 代码 import React, { useState } from react; import { Car…

如何有效保护生物医药企业隔离网数据导出的安全性?

生物医药企业的核心数据保护至关重要&#xff0c;企业为了保护内部的核心数据&#xff0c;会将网络进行物理隔离&#xff0c;将企业内⽹与外⽹隔离。⽹络隔离后&#xff0c;仍存在重要数据从内网导出至外网的隔离网数据导出需求。以下是一些需要特别保护的核心数据类型&#xf…

【图论 树 深度优先搜索】2246. 相邻字符不同的最长路径

本文涉及知识点 图论 树 图论知识汇总 深度优先搜索汇总 LeetCode 2246. 相邻字符不同的最长路径 给你一棵 树&#xff08;即一个连通、无向、无环图&#xff09;&#xff0c;根节点是节点 0 &#xff0c;这棵树由编号从 0 到 n - 1 的 n 个节点组成。用下标从 0 开始、长度…

Python学习笔记五

1.当循环执行完整后&#xff0c;就会执行else里面的代码 s0 i1 while i<100:sii1 else:print(s) 当循环不完整就会如下 s0 i1 while i<100:sii1if s6:break; else:print(s) 2. 实现密码匹配&#xff0c;可以输入三次&#xff0c;若输入三次错误会退出&#xff0c;或者输…

Reactor模型:网络线程模型演进

一&#xff0c;阻塞IO线程池模型&#xff08;BIO&#xff09; 这是传统的网络编程方案所采用的线程模型。 即有一个主循环&#xff0c;socket.accept阻塞等待&#xff0c;当建立连接后&#xff0c;创建新的线程/从线程池中取一个&#xff0c;把该socket连接交由新线程全权处理。…

【C++课程设计——演讲比赛系统】

文章目录 前言一、演讲比赛程序需求二、每个功能模块的实现1. 创建管理类(.h文件)2.1. 创建管理类(.cpp文件)3.创建参赛选手类(.h)4.将整体逻辑进行封装 测试项目总结 前言 在学习完C的stl容器后&#xff0c;我们来写一下小项目对其进行应用&#xff01; 项目名称为&#xff1…

常见的反爬手段和解决思路(爬虫与反爬虫)

常见的反爬手段和解决思路&#xff08;爬虫与反爬虫&#xff09; 学习目标1 服务器反爬的原因2 服务器长反什么样的爬虫&#xff08;1&#xff09;十分低级的应届毕业生&#xff08;2&#xff09;十分低级的创业小公司&#xff08;3&#xff09;不小心写错了没人去停止的失控小…

排序算法(1)之插入排序----直接插入排序和希尔排序

个人主页&#xff1a;C忠实粉丝 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 C忠实粉丝 原创 排序之插入排序----直接插入排序和希尔排序(1) 收录于专栏【数据结构初阶】 本专栏旨在分享学习数据结构学习的一点学习笔记&#xff0c;欢迎大家在评论区交流讨…

JavaParser抽取测试用例对应的被测方法

背景介绍 博主目前要做的工作需要将一个java项目的所有RD手写的测试用例和被测方法对应起来&#xff0c;最后将得到的结果存入一个json文件。 本教程以项目GitHub - binance/binance-connector-java 为例。 结果展示 最终会得到一个 funcTestMap.json&#xff0c;里面存放着…