Godot UI线程,Task异步和消息弹窗通知
前言
最近我在研究Godot的全局消息,然后发现Godot 也是有UI线程限制的,只能在主线程的子线程里面修改UI。
线程安全


全局消息IOC注入
我之前写过Godot 的IOC注入,这些都是CSDN时期的博客。但是后面CSDN的广告实在是太多了,我就转到博客园里面来了。
Godot.NET C# 工程化开发(1):通用Nuget 导入+ 模板文件导出,包含随机数生成,日志管理,数据库连接等功能
注意,我后面的都是基于我那个IOC框架来写的。

消息窗口搭建
如何修改Label样式可以看我上一篇文章
最简单的消息提示

using Godot;
using Godot_UI_Test.Utils;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Reflection.Emit;
using System.Text;
using System.Threading.Tasks;
namespace Godot_UI_Test.SceneModels
{
public class MessageSceneModel : ISceneModel
{
private PrintHelper printHelper;
private Godot.Label title;
private Godot.Label content;
private VBoxContainer container;
private ColorRect colorRect;
public MessageSceneModel(PrintHelper printHelper) {
this.printHelper = printHelper;
printHelper.SetTitle(nameof(MessageSceneModel));
}
public override void Process(double delta)
{
//throw new NotImplementedException();
}
public override void Ready()
{
printHelper.Debug("加载完成");
colorRect = Scene.GetNode<ColorRect>("ColorRect");
container = colorRect.GetNode<VBoxContainer>("VBoxContainer");
title = container.GetNode<Godot.Label>("Title");
content = container.GetNode<Godot.Label>("Content");
//同步容器大小
container.Size = colorRect.Size;
printHelper.Debug(JsonConvert.SerializeObject(title.Size));
//默认设置为不可见
Scene.Visible = false;
//throw new NotImplementedException();
}
/// <summary>
/// 弹窗延迟退出
/// </summary>
/// <param name="message"></param>
/// <returns></returns>
public async Task ShowInfo(string message)
{
Scene.Visible = true;
printHelper.Debug("Info打印信息");
printHelper.Debug(message);
await Task.Delay(3000);
Scene.Visible = false;
}
}
}
简单使用

虽然有点丑,但是能用

仿Element UI
ElementUI 效果

简单的Label样式

简单的画一下,我就不给具体的参数了,大家点一下就知道了

如何快速加载多个相同节点
如果我们把这个作为场景,又没有那么的复杂。如果用代码生成,写起来很麻烦,也不直观。最好的方法就是复制节点添加。

using Godot;
using Godot_UI_Test.Utils;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Reflection.Emit;
using System.Text;
using System.Threading.Tasks;
namespace Godot_UI_Test.SceneModels
{
public class MessageSceneModel : ISceneModel
{
private PrintHelper printHelper;
private VBoxContainer vBoxContainer;
private AssetsHelper assetsHelper;
private Godot.Label label;
public MessageSceneModel(PrintHelper printHelper, AssetsHelper assetsHelper)
{
this.printHelper = printHelper;
printHelper.SetTitle(nameof(MessageSceneModel));
this.assetsHelper = assetsHelper;
}
public override void Process(double delta)
{
//throw new NotImplementedException();
}
public override void Ready()
{
printHelper.Debug("加载完成");
vBoxContainer = Scene.GetNode<VBoxContainer>("VBoxContainer");
label = Scene.GetNode<Godot.Label>("Label");
//将vBoxContainer居中,GodotProjectSetting是自己设置的
vBoxContainer.Position = new Vector2(GodotProjectSetting.Width/4, 10);
//添加label的靠别,不能直接添加label,因为label已经拥有了父节点
var newLabel = label.Duplicate() as Godot.Label;
//显示Label
newLabel.Visible =true;
vBoxContainer.AddChild(newLabel.Duplicate());
vBoxContainer.AddChild(newLabel.Duplicate());
vBoxContainer.AddChild(newLabel.Duplicate());
//CreateText("te321");
//CreateText("te321 3213 321 3434 4 2 41321 st1 te321 3213 321 3434 4 2 41321 st1 te321 3213 321 3434 4 2 41321 st1");
printHelper.Debug(JsonConvert.SerializeObject(vBoxContainer.Position));
printHelper.Debug(JsonConvert.SerializeObject(vBoxContainer.GetWindow().Position));
//Scene.Visible = false;
//throw new NotImplementedException();
}
private void CreateText(string text)
{
var res = new Godot.Label();
res.AddThemeStyleboxOverride("normal", assetsHelper.MessageItemStyle);
res.AutowrapMode = TextServer.AutowrapMode.WordSmart;
res.HorizontalAlignment = HorizontalAlignment.Center;
res.Text = text;
res.CustomMinimumSize = new Vector2(200, 0);
label = res;
vBoxContainer.AddChild(res);
}
/// <summary>
/// 延迟打印
/// </summary>
/// <param name="message"></param>
/// <returns></returns>
public async Task ShowInfo(string message)
{
printHelper.Debug("Info打印信息");
}
}
}

修改一下,IOC按钮事件注册
using Godot;
using Godot_UI_Test.Utils;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Reflection.Emit;
using System.Text;
using System.Threading.Tasks;
namespace Godot_UI_Test.SceneModels
{
public class MessageSceneModel : ISceneModel
{
private PrintHelper printHelper;
private VBoxContainer vBoxContainer;
private AssetsHelper assetsHelper;
private Godot.Label label;
public MessageSceneModel(PrintHelper printHelper, AssetsHelper assetsHelper)
{
this.printHelper = printHelper;
printHelper.SetTitle(nameof(MessageSceneModel));
this.assetsHelper = assetsHelper;
}
public override void Process(double delta)
{
//throw new NotImplementedException();
}
public override void Ready()
{
printHelper.Debug("加载完成");
vBoxContainer = Scene.GetNode<VBoxContainer>("VBoxContainer");
label = Scene.GetNode<Godot.Label>("Label");
//将vBoxContainer居中,GodotProjectSetting是自己设置的
vBoxContainer.Position = new Vector2(GodotProjectSetting.Width/4, 10);
//CreateText("te321 3213 321 3434 4 2 41321 st1 te321 3213 321 3434 4 2 41321 st1 te321 3213 321 3434 4 2 41321 st1");
printHelper.Debug(JsonConvert.SerializeObject(vBoxContainer.Position));
printHelper.Debug(JsonConvert.SerializeObject(vBoxContainer.GetWindow().Position));
//Scene.Visible = false;
//throw new NotImplementedException();
}
/// <summary>
/// 挂载Label
/// </summary>
/// <param name="text"></param>
private Godot.Label CreateText(string text)
{
var newLabel = label.Duplicate() as Godot.Label;
newLabel.Text = text;
newLabel.Visible=true;
vBoxContainer.AddChild(newLabel);
return newLabel;
}
/// <summary>
/// 延迟打印
/// </summary>
/// <param name="message"></param>
/// <returns></returns>
public async Task ShowInfo(string message)
{
printHelper.Debug("Info打印信息");
var newLabel = CreateText(message);
await Task.Delay(3 * 1000);
newLabel.Free();
}
}
}


总结
我只是很潦草的实现了消息弹窗这个功能,还没加动画效果。不过这个确实让我学到了很多,尤其是节点挂载这个事情。
Godot UI线程,Task异步和消息弹窗通知的更多相关文章
- Android异步处理一:使用Thread+Handler实现非UI线程更新UI界面
Android应用的开发过程中需要把繁重的任务(IO,网络连接等)放到其他线程中异步执行,达到不阻塞UI的效果. 下面将由浅入深介绍Android进行异步处理的实现方法和系统底层的实现原理. 本文介绍 ...
- 细说UI线程和Windows消息队列(经典)
在Windows应用程序中,窗体是由一种称为“UI线程(User Interface Thread)”的特殊类型的线程创建的. 首先,UI线程是一种“线程”,所以它具有一个线程应该具有的所有特征,比如 ...
- 细说UI线程和Windows消息队列
在 Windows应用程序中,窗体是由一种称为“ UI线程( User Interface Thread)”的特殊类型的线程创建的. 首先, UI线程是一种“线程”,所以它具有一个线程应该具有的所有特 ...
- 【转】细说UI线程和Windows消息队列
在Windows应用程序中,窗体是由一种称为“UI线程(User Interface Thread)”的特殊类型的线程创建的. 首先,UI线程是一种“线程”,所以它具有一个线程应该具有的所有特征,比如 ...
- c#多线程(UI线程,控件显示更新) Invoke和BeginInvoke 区别
如果只是直接使用子线程访问UI控件,直接看内容三,如果想深入了解从内容一看起. 一.Control.Invoke和BeginInvoke方法的区别 先上总结: Control.Invoke 方法 (D ...
- [转] c#多线程(UI线程,控件显示更新) Invoke和BeginInvoke 区别
如果只是直接使用子线程访问UI控件,直接看内容三,如果想深入了解从内容一看起. 一.Control.Invoke和BeginInvoke方法的区别 先上总结: Control.Invoke 方法 (D ...
- 千万别在UI线程上调用Control.Invoke和Control.BeginInvoke,因为这些是依然阻塞UI线程的,造成界面的假死
原文地址:https://www.cnblogs.com/wangchuang/archive/2013/02/20/2918858.html .c# Invoke和BeginInvoke 区别 Co ...
- Android UI线程和非UI线程
Android UI线程和非UI线程 UI线程及Android的单线程模型原则 当应用启动,系统会创建一个主线程(main thread). 这个主线程负责向UI组件分发事件(包括绘制事件),也是在这 ...
- android脚步---如何看log之程序停止运行,和UI线程和非UI线程之间切换
经常运行eclipse时,烧到手机出现,“停止运行”,这时候得通过logcat查log了.一般这种情况属于FATAL EXCEPTION,所以检索FATAL 或者 EXCEPTION,然后往下看几行 ...
- 关于“UI线程”
http://www.cppblog.com/Streamlet/archive/2013/05/05/199999.html 缘起 这是一篇找喷的文章. 由于一些历史原因和人际渊源,周围同事谈论一些 ...
随机推荐
- 基于STM32F407MAC与DP83848实现以太网通讯三(STM32F407MAC配置以及数据收发)
本章实现了基于STM32F407MAC的数据收发功能,通过开发板的RJ45接口连接网线到电脑,电脑使用Wiershark工具抓包验证,工程源码.资料和软件见文末. 参考文档: DP83848IV英文 ...
- config.baseUrl.dev 变量 转移到 .env.local 中
config.baseUrl.dev 变量 转移到 .env.local 中 上下文 vue前端开发 问题 多人写代码的时候,会提交config.js里面的配置文件 解决方案 在根目录创建 .env. ...
- C#实现软件开机自启动(不需要管理员权限)
目录 原理简介 使用方法 完整代码 原理简介 本文参考C#/WPF/WinForm/程序实现软件开机自动启动的两种常用方法,将里面中的第一种方法做了封装成AutoStart类,使用时直接两三行代码就可 ...
- 在使用sudo apt-get -f install的时候,出现了更换介质的问题-依赖问题
这四个选项都选上,然后apt-get update 在修补依赖问题,apt-get -f install 就好了
- 手撕fft算法--fft原理和源码解析
一 前言 在音频信号处理中,fft变换是一个无法绕过过去的存在.借着一次算法出来的机会,把fft熟悉一下不为过啊. 二 问题 这里,其实是由一个问题驱动的,那就是:怎么通过fft的变化来得 ...
- 记录--前端路由 hash 与 history 差异
这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 简单介绍 Vue Router Vue Router 是 Vue.js 官方的路由插件,它和 Vue.js 是深度集成的,适合用于构建单页 ...
- 记录--JS原型链
这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 引子 对于初学者学习原型链,还是有很大的困难.一方面是函数与对象分不太清楚:另一方面,不懂原型链的继承等.本人曾今也深受困惑,并且把疑惑的 ...
- 使用元类实现Django的ORM
一.ORM基本介绍 ORM 是 python编程语言后端web框架 Django的核心思想,"Object Relational Mapping",即对象-关系映射,简称ORM. ...
- Avalonia项目生成银河麒麟操作系统安装包
1 在项目根目录添加xxx.desktop文件,文件内容: [Desktop Entry] Name=xxx Type=Application Exec=/usr/share/xxx/xxx Icon ...
- Spring Cloud 服务的注册与发现之eureka客户端注册
1.在客户端maven项目中添加eureka客户端依赖 <dependency> <groupId>org.springframework.cloud</groupId& ...