nicegui:Python 图形界面库,简单好用

前言

在现代计算机应用程序开发中,图形用户界面(GUI)是用户与程序交互的重要组成部分。然而,GUI 开发往往需要大量的代码和复杂的布局,给开发者带来了一定的挑战。在本篇博文中,将介绍 nicegui,它是一个简单易用的图形用户界面库,提供了一种简化 GUI 开发的方式,使开发者能够更快速地构建吸引人的用户界面。

实现原理

nicegui 基于 Python 编程语言开发,采用了声明式的方式来描述用户界面。它的设计灵感来自于 Web 开发中的 HTML 和 CSS,通过一种类似的结构化语法来描述界面的组件和样式。

nicegui 的核心思想是将用户界面分为多个组件,每个组件具有自己的属性和样式。开发者可以使用 nicegui 提供的组件库,如按钮、文本框、下拉菜单等,通过简单的代码来定义和布局这些组件。同时,nicegui 还支持自定义组件,开发者可以根据自己的需求扩展组件库。

安装

可以使用 pip 安装,具体操作如下

pip install nicegui

示例代码

下面是一个简单的 nicegui 示例代码

from nicegui import ui

上述代码中,首先导入 nicegui 中的 ui 模块,模块中包含了常用的组件

例子中使用了 label 和 button,默认情况下,它们是垂直布局的,启动服务使用 run 方法

执行上述脚本,就可以在浏览器中访问 http://127.0.0.1:8080 看到效果了

点击 BUTTON 按钮,在下方会显示提示信息

下面,再来看一个完整的示例

from dataclasses import dataclass, field
from typing import Callable, List

from nicegui import ui


@dataclass
class TodoItem:
    name: str
    done: bool = False


@dataclass
class ToDoList:
    title: str
    on_change: Callable
    items: List[TodoItem] = field(default_factory=list)

    def add(self, name: str, done: bool = False) -> None:
        self.items.append(TodoItem(name, done))
        self.on_change()

    def remove(self, item: TodoItem) -> None:
        self.items.remove(item)
        self.on_change()


@ui.refreshable
def todo_ui():
    if not todos.items:
        ui.label('List is empty.').classes('mx-auto')
        return
    ui.linear_progress(sum(item.done for item in todos.items) / len(todos.items), show_value=False)
    with ui.row().classes('justify-center w-full'):
        ui.label(f'Completed: {sum(item.done for item in todos.items)}')
        ui.label(f'Remaining: {sum(not item.done for item in todos.items)}')
    for item in todos.items:
        with ui.row().classes('items-center'):
            ui.checkbox(value=item.done, on_change=todo_ui.refresh).bind_value(item, 'done')
            ui.input(value=item.name).classes('flex-grow').bind_value(item, 'name')
            ui.button(on_click=lambda item=item: todos.remove(item), icon='delete').props('flat fab-mini color=grey')


todos = ToDoList('My Weekend', on_change=todo_ui.refresh)
todos.add('Order pizza', done=True)
todos.add('New NiceGUI Release')
todos.add('Clean the house')
todos.add('Call mom')

with ui.card().classes('w-80 items-stretch'):
    ui.label().bind_text_from(todos, 'title').classes('text-semibold text-2xl')
    todo_ui()
    add_input = ui.input('New item').classes('mx-12')
    add_input.on('keydown.enter', lambda: (todos.add(add_input.value), add_input.set_value('')))

ui.run()

这段代码使用 nicegui 创建了一个简单的待办事项列表应用。让我们一步一步地解析它的功能和逻辑

首先,导入了必要的模块和类。dataclasses 模块提供了一个装饰器 dataclass,用于创建简洁而强大的数据类。数据类是一种特殊的类,主要用于存储数据,并且通常只包含属性而没有方法。

接着,定义了两个数据类:TodoItem 和 ToDoList。TodoItem 表示待办事项,具有 name 和 done 两个属性,其中 done 表示待办事项是否已完成。ToDoList 表示待办事项列表,具有 title、on_change 和 items 三个属性,其中 items 是一个 TodoItem 对象的列表。ToDoList 还提供了 add 和 remove 方法,用于添加和移除待办事项。

接下来,定义了一个名为 todo_ui 的界面函数,并使用 @ui.refreshable 装饰器标记为可刷新的界面函数。todo_ui 函数用于渲染待办事项列表的界面。

在 todo_ui 函数中,首先检查待办事项列表是否为空,如果为空,则显示一个标签,内容为 List is empty.,并进行居中显示。然后,使用 ui.linear_progress 创建一个线性进度条,用于显示已完成任务的比例,计算已完成任务的数量并除以总任务数量,然后将该值传递给 ui.linear_progress 函数。接着,使用 ui.row 创建一个行布局容器,并在容器中添加两个标签,分别显示已完成的任务数量和剩余的任务数量。通过遍历待办事项列表中的每个事项,计算已完成任务的数量和剩余任务的数量,并显示在标签中。接下来,使用 ui.row 和 ui.checkbox 创建一个行布局和一个复选框,用于显示和编辑待办事项的完成状态。通过设置 value 参数来绑定复选框的值,并使用 on_change 参数指定当复选框状态发生变化时调用的回调函数。使用 bind_value 方法将复选框的值与待办事项对象的 done 属性进行绑定,以实现动态更新。然后,使用 ui.row 和 ui.input 创建一个行布局和一个输入框,用于显示和编辑待办事项的名称。通过设置输入框的初始值和使用 bind_value 方法将输入框的值与待办事项对象的 name 属性进行绑定。

最后,使用 ui.row 和 ui.button 创建一个行布局和一个删除按钮,用于删除待办事项。通过设置按钮的 on_click 参数来指定点击按钮时调用的回调函数,并使用 lambda 表达式传递待办事项对象作为参数。使用 props 方法设置按钮的样式和图标。

在主程序中,创建了一个 ToDoList 实例 todos,设置了标题为 My Weekend,并指定了当待办事项列表发生变化时刷新界面函数 todo_ui。然后,通过调用 todos.add 方法添加了一些初始的待办事项。接下来,使用 ui.card 创建一个卡片容器,并设置其样式,在卡片容器中,创建一个标签,并使用 bind_text_from 方法将其文本与 todos 实例的 title 属性进行绑定,以实现动态更新。然后,调用 todo_ui 函数以渲染待办事项列表的界面。创建一个输入框 add_input,用于添加新的待办事项,通过监听 add_input 输入框的 keydown.enter 事件,当用户按下回车键时,调用 todos.add 方法将输入框的值作为新的待办事项添加到列表中,并将输入框的值重置为空字符串。

最后,调用 ui.run 启动 nicegui 应用程序的事件循环,显示界面并等待用户交互。

通过这个示例项目,我们可以看到 nicegui 的简洁和易用性,开发者可以快速构建出一个功能完善的应用程序界面。

参考资料

posted @ 2023-09-07 19:36  luckzack  阅读(4010)  评论(2编辑  收藏  举报