
目录更多 Blocks 特性示例持续运行事件收集事件数据验证总结上一篇Gradio.Net (https://github.com/feiyun0112/Gradio.Net)是一个开源的 .NET 库它是 Gradio 的 .NET 移植版本允许你为机器学习模型、API 或任何 C# 函数快速构建演示或 Web 应用程序无需任何 JavaScript、CSS 或 Web 开发经验更多 Blocks 特性示例与Interface一样Blocks也支持添加示例数据。示例数据会显示在界面底部点击后自动填充输入组件方便用户快速体验。使用gr.Examples()方法向Blocks添加示例。参数与Interface一致examples示例数据列表每个元素对应一行示例其中各项按 inputs顺序排列。inputs需要填充的输入组件列表。outputs可选需要填充的输出组件列表。fn可选点击示例时运行的函数如不指定则只填充输入。下面是一个带示例的计算器示例using Gradio.Net; using Gradio.Net.Components; using var demo gr.Blocks(); double Calculator(double num1, string operation, double num2) { return operation switch { add num1 num2, subtract num1 - num2, multiply num1 * num2, divide num2 ! 0 ? num1 / num2 : throw new DivideByZeroException(Cannot divide by zero), _ throw new ArgumentException($Unknown operation: {operation}) }; } var num1 gr.Number(value: 4, label: First Number); var operation gr.Radio(choices: new Liststring { add, subtract, multiply, divide }, label: Operation); var num2 gr.Number(value: 0, label: Second Number); var submitBtn gr.Button(value: Calculate); var result gr.Number(label: Result); submitBtn.Click( fn: (double n1, string op, double n2) Calculator(n1, op, n2), inputs: new ListComponent { num1, operation, num2 }, outputs: result); gr.Examples( examples: new ListListobject { new Listobject { 5, add, 3 }, new Listobject { 4, divide, 2 }, new Listobject { -4, multiply, 2.5 }, new Listobject { 0, subtract, 1.2 } }, inputs: new ListComponent { num1, operation, num2 }); await demo.Launch();持续运行事件Timer组件可以按照固定时间间隔触发事件。创建Timer组件后使用.On(trigger: Events.Tick, ...)来注册 tick 处理函数。在下面的例子中计时器每秒触发一次每次 tick 都会更新时间戳并生成一个随机数。另外我们添加了开始、停止按钮以及一个加速按钮。这里有一个技巧点击开始时我们返回gr.Timer(active: true)并将其作为timer组件的输出这样就可以在运行时修改 timer 的属性。using Gradio.Net; using Gradio.Net.Components; using Gradio.Net.Events; using GrTimer Gradio.Net.Components.Timer; using var demo gr.Blocks(); var timer gr.Timer(value: 1, active: true); var timestamp gr.Number(label: Time); timer.Tick(fn: () (long)DateTimeOffset.UtcNow.ToUnixTimeSeconds(), outputs: timestamp, apiName: timestamp); var randomNumber gr.Number(value: () Random.Shared.Next(1, 11), every: timer, label: Random Number); using (gr.Row()) { gr.Button(Start).Click(fn: () gr.Timer(active: true), inputs: null, outputs: timer); gr.Button(Stop).Click(fn: () gr.Timer(active: false), inputs: null, outputs: timer); gr.Button(Go Fast).Click(fn: () 0.2, inputs: null, outputs: timer); } await demo.Launch();注意Number组件的every参数对应 Python 的everytimer在 Gradio.Net 中通过timer.On(trigger: Events.Tick, ...)实现。收集事件数据你可以在事件处理函数中通过添加SelectData类型参数来获取事件相关的元数据。例如某些组件在触发.select()事件时会附带被选中的数据。在下面的井字棋例子中我们通过SelectData获取用户点击的单元格位置行、列并在对应位置落子using Gradio.Net; using Gradio.Net.Components; using Gradio.Net.Events; using var demo gr.Blocks(); var turn gr.Textbox(X, interactive: false, label: Turn); var board gr.Dataframe( value: new ListListobject? { new() { , , }, new() { , , }, new() { , , } }, interactive: false, type: array); (ListListobject?, string) Place(ListListobject? boardData, string currentTurn, SelectData eventData) { var indexList eventData.Index as Listobject; int row Convert.ToInt32(indexList?[0]); int col Convert.ToInt32(indexList?[1]); if (eventData.Value is string v !string.IsNullOrEmpty(v)) return (boardData, currentTurn); boardData[row][col] currentTurn; var nextTurn currentTurn X ? O : X; return (boardData, nextTurn); } board.On( trigger: Events.Select, fn:Place, inputs: new ListComponent { board, turn }, outputs: new ListComponent { board, turn }, showProgress: hidden); await demo.Launch();SelectData包含以下属性Index被选中项目的索引对于 Dataframe 是 [row, col]的 JSON 数组。Value被选中项目的值。RowValue所在行的所有值仅 Dataframe 支持。ColValue所在列的所有值仅 Dataframe 支持。Selectedtrue表示已选中false表示取消选中。验证Gradio 支持在事件触发时对输入进行验证。你可以在.Click()或其他事件方法中传入validator参数它接受一个委托该委托接收与主函数相同的输入并返回验证结果列表。使用Helpers.Validate(bool isValid, string message)来创建验证结果。如果isValid为falseGradio 会在界面中高亮对应组件并显示错误消息阻止主函数执行。using Gradio.Net; using Gradio.Net.Components; using Gradio.Net.Events; using var demo gr.Blocks(); gr.Markdown(# Validator Parameter Test Demo); Number age; Textbox location; using (gr.Row()) { using (gr.Column()) { age gr.Number(label: Enter age, placeholder: Enter age); location gr.Textbox(maxLines: 3, label: Enter location, placeholder: Enter location); } } var validateBtn gr.Button(Process with Validation, variant: primary); var outputWithValidation gr.Textbox(label: Output (with validation), interactive: false); string ProcessText(double age, string location) { return $Processed: {age} -- {location.ToUpper()}; } ListDictionarystring, object ValidateInput(double age, string location) { return new ListDictionarystring, object { gr.Validate(age 0 || age 3, Age must be at least 3), gr.Validate(!location.ToLower().Contains(london), Location must not be in London), }; } validateBtn.Click( fn: ProcessText, validator: ValidateInput, inputs: new ListComponent { age, location }, outputs: outputWithValidation); await demo.Launch();验证器的返回列表中每个元素对应一个输入组件按顺序Gradio 会根据验证结果决定是否允许主函数执行。总结本章你学习了使用 gr.Examples()为 Blocks 应用添加示例数据使用 Timer组件和 .On(trigger: Events.Tick, ...)实现周期性事件通过 SelectData参数获取 select 事件的详细数据使用 validator参数和 Helpers.Validate()实现表单验证。引入地址