Python Web 应用开发:NiceGUI 页面布局详解

1. 概述

NiceGUI 是一个基于 Python 的 Web UI 框架,采用声明式编程模式,让开发者能够专注于业务逻辑而非前端技术细节,轻松构建交互式 Web 界面。

在 Web 应用开发中,页面布局是用户体验的基石。良好的布局设计能够:

  • 提升用户操作效率
  • 增强信息可读性
  • 构建直观导航结构
  • 适配不同设备和屏幕尺寸

NiceGUI 布局系统的核心特点:

  • 上下文管理:自动维护元素父子关系
  • 响应式设计:自适应不同屏幕尺寸
  • 组件化架构:提供丰富的布局容器组件
  • Quasar 集成:基于成熟的 Quasar UI 框架

2. 自动上下文管理

2.1 上下文管理原理

NiceGUI 利用 Python 的上下文管理器(with 语句)自动追踪元素创建环境,无需显式指定父元素,系统会自动将元素添加到当前上下文中。

from nicegui import ui

with ui.card():  # 创建卡片作为上下文
    ui.label('Card content')  # 自动添加到卡片中
    ui.button('Add label', on_click=lambda: ui.label('Click!'))  # 也添加到卡片中

效果示例:

Python Web 应用开发:NiceGUI 页面布局详解

2.2 上下文优势

  1. 代码简洁:省去手动管理父子关系的繁琐
  2. 可维护性强:组件移动时无需修改内部代码
  3. 模块化设计:便于创建可复用的组件

2.3 注意事项

  • 确保在正确的上下文中创建元素
  • 避免在上下文外创建依赖特定父元素的组件
  • 使用 with 语句保证正确的嵌套关系

3. 基础布局容器

3.1 卡片 (Card)

卡片是常用的容器组件,提供带边框和阴影的视觉区域,适合内容分组展示。

核心特性

  • 默认带阴影和内边距
  • 支持紧凑模式(tight)
  • 可嵌套其他布局组件

语法定义

ui.card(tight: bool = False) -> Card

参数说明

  • tight:是否使用紧凑模式(默认 False)

应用示例

from nicegui import ui

# 基本卡片
with ui.card():
    ui.label('基本卡片内容')
    ui.button('按钮')

# 紧凑模式卡片
with ui.card().tight():
    ui.image('https://picsum.photos/id/684/640/360')
    with ui.card_section():
        ui.label('紧凑模式下的内容')

# 商品卡片组件示例
def create_product_card(name: str, price: float, description: str):
    with ui.card().classes('w-64 shadow-lg hover:shadow-xl transition-shadow'):
        # 商品图片
        ui.image(f'https://picsum.photos/id/{hash(name) % 100}/300/200')
        
        # 商品信息
        with ui.card_section():
            ui.label(name).classes('text-h6 font-bold')
            ui.label(description).classes('text-caption text-grey-7')
            
            # 价格和操作区
            with ui.row().classes('items-center justify-between'):
                ui.label(f'¥{price:.2f}').classes('text-h6 text-primary')
                ui.button('购买', icon='shopping_cart').props('outline')

# 使用卡片布局
with ui.grid(columns=3).classes('gap-4 p-4'):
    create_product_card('无线鼠标', 129.00, '高性能无线鼠标,适合办公和游戏')
    create_product_card('机械键盘', 399.00, '青轴机械键盘,打字手感极佳')
    create_product_card('蓝牙耳机', 259.00, '降噪蓝牙耳机,续航时间长')

ui.run()

效果示例:

Python Web 应用开发:NiceGUI 页面布局详解

3.2 纵向布局 (Column)

纵向布局容器将子元素垂直排列,适用于表单项、列表等场景。

语法定义

ui.column(wrap: bool = False, align_items: Optional[str] = None) -> Column

参数说明

  • wrap:是否允许换行(默认 False)
  • align_items:对齐方式(”start”, “end”, “center”, “baseline”, “stretch”)

应用示例

from nicegui import ui

with ui.column().classes('gap-2 p-4 border rounded'):
    ui.label('项目 1')
    ui.label('项目 2')
    ui.label('项目 3')

# 带对齐的列
with ui.column(align_items="center").classes('gap-2 p-4 border rounded'):
    ui.label('居中项目 1')
    ui.label('居中项目 2')
    ui.button('居中按钮')

ui.run()

效果示例:

Python Web 应用开发:NiceGUI 页面布局详解

3.3 横向布局 (Row)

横向布局容器将子元素水平排列,适用于工具栏、按钮组等场景。

语法定义

ui.row(wrap: bool = True, align_items: Optional[str] = None) -> Row

参数说明

  • wrap:是否允许换行(默认 True)
  • align_items:对齐方式

应用示例

from nicegui import ui

with ui.row().classes('gap-2 p-4 border rounded'):
    ui.label('标签 1')
    ui.label('标签 2')
    ui.label('标签 3')

# 不允许换行的行
with ui.row(wrap=False).classes('gap-2 p-4 border rounded'):
    for i in range(10):
        ui.button(f'按钮 {i+1}')

# 综合布局示例:用户资料
def create_user_profile():
    with ui.row().classes('w-full gap-8 p-6'):
        # 左侧 - 头像和信息
        with ui.column().classes('items-center w-1/4'):
            ui.avatar('张三', size='120px').classes('mb-4')
            ui.label('张三').classes('text-h5 font-bold')
            ui.label('高级用户').classes('text-caption text-grey')
            ui.rating(4).classes('q-mt-sm')
        
        # 右侧 - 详细信息
        with ui.column().classes('flex-1 gap-4'):
            # 基本信息行
            with ui.row().classes('items-center gap-8'):
                ui.label('邮箱: zhangsan@example.com')
                ui.label('电话: 138-0013-8000')
                ui.label('注册时间: 2023-01-15')
            
            # 技能标签
            with ui.column():
                ui.label('技能标签').classes('text-h6')
                with ui.row().classes('gap-2 wrap'):
                    tags = ['Python', 'JavaScript', 'Vue.js', 'Django', 'Docker']
                    for tag in tags:
                        ui.chip(tag).props('outline')
            
            # 操作按钮
            with ui.row().classes('gap-2'):
                ui.button('编辑资料', icon='edit')
                ui.button('消息', icon='message')
                ui.button('关注', icon='person_add')

create_user_profile()
ui.run()

效果示例:

Python Web 应用开发:NiceGUI 页面布局详解

3.4 网格布局 (Grid)

网格布局提供二维网格系统来排列元素,适用于复杂布局场景。

语法定义

ui.grid(rows: Optional[Union[int, str]] = None, 
        columns: Optional[Union[int, str]] = None) -> Grid

参数说明

  • rows:行数或 CSS grid-template-rows 值
  • columns:列数或 CSS grid-template-columns 值

响应式断点

断点

屏幕宽度

适用设备

xs

< 600px

手机

sm

600px-1024px

平板

md

1024px-1440px

小桌面

lg

1440px-1920px

桌面

xl

> 1920px

大屏幕

应用示例

from nicegui import ui

# 基本网格
with ui.grid(columns=2).classes('gap-2 p-4 border rounded'):
    ui.label('名称:')
    ui.label('张三')
    ui.label('年龄:')
    ui.label('25')
    ui.label('职业:')
    ui.label('工程师')

# 复杂网格布局
with ui.grid(columns='1fr 2fr', rows='auto 1fr').classes('gap-2 p-4 border rounded h-64'):
    ui.label('标题').classes('col-span-2 text-center bg-blue-100 p-2')
    ui.label('侧边栏').classes('bg-green-100 p-2')
    ui.label('主内容').classes('bg-yellow-100 p-2')

# 响应式仪表盘布局
def create_dashboard_layout():
    with ui.grid(columns='1fr').classes('''
        xs:grid-cols-1 
        sm:grid-cols-2 
        md:grid-cols-3 
        lg:grid-cols-4 
        xl:grid-cols-6
        gap-4 p-4
    '''):
        # 统计卡片
        metrics = [
            ('总用户', '12,345', 'people', 'blue'),
            ('今日活跃', '2,567', 'flash_on', 'green'),
            ('新增订单', '189', 'shopping_cart', 'orange'),
            ('总收入', '¥45,678', 'attach_money', 'purple'),
            ('转化率', '12.5%', 'trending_up', 'cyan'),
            ('满意度', '94.2%', 'favorite', 'pink')
        ]
        
        for title, value, icon, color in metrics:
            with ui.card().classes(f'bg-{color}-50 border-{color}'):
                with ui.column().classes('items-center text-center p-4'):
                    ui.icon(icon).classes(f'text-{color} text-h3')
                    ui.label(value).classes('text-h5 font-bold')
                    ui.label(title).classes('text-caption')

create_dashboard_layout()
ui.run()

效果示例:

Python Web 应用开发:NiceGUI 页面布局详解

3.5 列表 (List)

列表组件用于显示项目集合,基于 Quasar 的 QList 组件。

语法定义

ui.list(**kwargs) -> List

应用示例

from nicegui import ui

# 基本列表
with ui.list().props("bordered separator").classes("w-64"):
    ui.item("苹果")
    ui.item("香蕉")
    ui.item("橙子")
    ui.item("葡萄")

# 带图标的列表
with ui.list().props("bordered separator").classes("w-64"):
    # 列表项 1
    with ui.item().props("clickable"):
        with ui.item_section().props("avatar"):
            ui.icon("person")
        with ui.item_section():
            ui.label("用户管理").classes("font-bold")
            ui.label("管理用户账户和权限").classes("text-gray-500 text-sm")

    # 列表项 2
    with ui.item().props("clickable"):
        with ui.item_section().props("avatar"):
            ui.icon("settings")
        with ui.item_section():
            ui.label("系统设置").classes("font-bold")
            ui.label("配置系统参数").classes("text-gray-500 text-sm")

# 可交互列表
def handle_item_click(item_name: str):
    ui.notify(f"点击了: {item_name}")

with ui.list().props("bordered").classes("w-64"):
    items = ["项目A", "项目B", "项目C", "项目D"]
    for item in items:
        with ui.item().props("clickable").on(
            "click", lambda _, name=item: handle_item_click(name)
        ):
            ui.item_label(item)

ui.run()

效果示例:

Python Web 应用开发:NiceGUI 页面布局详解

3.6 滑动项 (Slide Item)

滑动项提供侧滑操作功能,常用于移动端交互场景。

语法定义

ui.slide_item(text: str = "", on_slide: Optional[Callable] = None) -> SlideItem

应用示例

from nicegui import ui

with ui.list().props("bordered separator"):
    with ui.slide_item("Slide me left or right") as slide_item_1:
        slide_item_1.left("Left", color="green")
        slide_item_1.right("Right", color="red")
    with ui.slide_item("Slide me up or down") as slide_item_2:
        slide_item_2.top("Top", color="blue")
        slide_item_2.bottom("Bottom", color="purple")

ui.run()

效果示例:

Python Web 应用开发:NiceGUI 页面布局详解

3.7 清空容器 (Clear Containers)

动态管理容器内容,支持添加、删除和清空操作。

应用示例

from nicegui import ui

# 动态列表管理
container = ui.column().classes('border rounded p-4 gap-2')

def add_item():
    with container:
        item_id = len(list(container)) + 1
        with ui.card().classes('w-full').props('flat bordered') as card:
            with ui.row().classes('items-center justify-between w-full'):
                ui.label(f'项目 {item_id}')
                ui.button(icon='delete', on_click=lambda: card.delete()).props('flat color=red')

def remove_first():
    if list(container):
        container.remove(0)

def clear_all():
    container.clear()

# 控制按钮
with ui.row().classes('gap-2 mb-4'):
    ui.button('添加项目', on_click=add_item, icon='add')
    ui.button('删除第一个', on_click=remove_first, icon='remove')
    ui.button('清空所有', on_click=clear_all, icon='clear')

# 初始化一些项目
for i in range(3):
    add_item()

ui.run()

效果示例:

Python Web 应用开发:NiceGUI 页面布局详解

3.8 传送门 (Teleport)

将内容动态传送到页面其他位置,实现灵活的布局控制。

语法定义

ui.teleport(to: Union[Element, str]) -> Teleport

应用示例

from nicegui import ui

# 创建目标容器
target_card = ui.card().classes('w-64 p-4 bg-blue-50')
with target_card:
    ui.label('目标区域').classes('text-h6')
    target_content = ui.column()

# 源内容区域
source_card = ui.card().classes('w-full p-4')
with source_card:
    ui.label('源内容区域').classes('text-h6')
    
    def teleport_content():
        # 清空目标区域
        target_content.clear()
        
        # 传送内容到目标区域
        with ui.teleport(target_content):
            ui.label('这是通过传送门传送的内容')
            ui.button('测试按钮', icon='check')
            ui.slider(min=0, max=100, value=50)
    
    def teleport_to_selector():
        # 传送到CSS选择器指定的位置
        with ui.teleport('.bg-blue-50 .q-card__section'):
            ui.label('传送到特定选择器位置').classes('text-green')
    
    ui.button('传送内容', on_click=teleport_content)
    ui.button('传送到选择器', on_click=teleport_to_selector)

ui.run()

效果示例:

Python Web 应用开发:NiceGUI 页面布局详解

3.9 扩展元素 (Expansion Element)

可折叠的内容区域,节省空间的同时提供更多信息。

语法定义

ui.expansion(text: str, 
             caption: Optional[str] = None,
             icon: Optional[str] = None,
             group: Optional[str] = None,
             value: bool = False,
             on_value_change: Optional[Callable] = None) -> Expansion

应用示例

from nicegui import ui

# 基本扩展面板
with ui.expansion('基本信息', icon='person').classes('w-full'):
    with ui.grid(columns=2).classes('w-full gap-4'):
        ui.input('姓名').classes('w-full')
        ui.input('邮箱').classes('w-full')
        ui.input('电话').classes('w-full')
        ui.input('地址').classes('w-full')

# 手风琴模式(互斥展开)
faq_group = 'faq-group'

faq_items = [
    {'question': '如何开始使用?', 'answer': '请参考我们的入门指南...'},
    {'question': '支持哪些浏览器?', 'answer': '支持所有现代浏览器...'},
    {'question': '如何获取协助?', 'answer': '请联系客服或查看文档...'},
]

for i, item in enumerate(faq_items):
    with ui.expansion(
        item['question'],
        caption='点击查看答案',
        group=faq_group,
        icon='help'
    ).classes('w-full'):
        ui.label(item['answer']).classes('q-pt-md')

# 编程控制扩展面板
advanced_expansion = ui.expansion('高级设置', icon='settings').classes('w-full')

def toggle_expansion():
    advanced_expansion.value = not advanced_expansion.value

with advanced_expansion:
    with ui.column().classes('gap-2'):
        ui.toggle(['选项1', '选项2', '选项3'])
        ui.slider(min=0, max=100, value=25)
        ui.button('重置设置', icon='refresh')

# 控制按钮
ui.button('切换高级设置', on_click=toggle_expansion)

ui.run()

效果示例:

Python Web 应用开发:NiceGUI 页面布局详解

3.10 滚动区 (Scroll Area)

自定义滚动区域,提供更好的滚动体验。

语法定义

ui.scroll_area(on_scroll: Optional[Callable] = None) -> ScrollArea

应用示例

from nicegui import ui

# 基本滚动区域
with ui.row().classes('w-full h-64'):
    # 带滚动条的区域
    with ui.scroll_area().classes('w-1/2 h-full border rounded'):
        with ui.column():
            for i in range(50):
                ui.label(f'滚动项目 {i+1}').classes('p-2 border-b')

# 自定义滚动行为
def handle_scroll(position: dict):
    ui.notify(f'滚动位置: {position}')

with ui.scroll_area(on_scroll=handle_scroll).classes('w-full h-32 border'):
    with ui.column():
        for i in range(20):
            ui.label(f'可监控滚动的项目 {i+1}').classes('p-2')

# 水平滚动区域
with ui.scroll_area().classes('w-full h-20 border').props('horizontal'):
    with ui.row().classes('nowrap'):
        for i in range(20):
            with ui.card().classes('w-32 h-16 inline-block m-2'):
                ui.label(f'卡片 {i+1}').classes('text-center')

ui.run()

效果示例:

Python Web 应用开发:NiceGUI 页面布局详解

3.11 空间 (Space)

填充可用空间的占位组件,用于布局对齐。

应用示例

from nicegui import ui

# 空间组件的基本使用
with ui.row().classes('w-full border p-4 items-center'):
    ui.label('左侧内容')
    ui.space()  # 填充中间空间
    ui.label('右侧内容')

# 复杂布局中的空间应用
with ui.card().classes('w-full p-4'):
    # 标题行
    with ui.row().classes('w-full items-center'):
        ui.label('项目列表').classes('text-h6')
        ui.space()
        ui.button('新增', icon='add')
        ui.button('刷新', icon='refresh')
    
    ui.separator()
    
    # 内容区域
    with ui.column().classes('w-full'):
        for i in range(5):
            with ui.row().classes('w-full items-center'):
                ui.label(f'项目 {i+1}')
                ui.space()
                ui.button('编辑', icon='edit').props('flat dense')
                ui.button('删除', icon='delete').props('flat dense color=red')

# 垂直空间应用
with ui.column().classes('h-64 border w-64'):
    ui.label('顶部内容')
    ui.space()  # 垂直填充
    ui.label('底部内容')

ui.run()

效果示例:

Python Web 应用开发:NiceGUI 页面布局详解

3.12 骨架屏 (Skeleton)

加载状态占位符,提升用户体验。

语法定义

ui.skeleton(type: str = "rect",
            tag: str = "div",
            animation: str = "wave", 
            animation_speed: float = 1.5,
            square: bool = False,
            bordered: bool = False,
            size: Optional[str] = None,
            width: Optional[str] = None,
            height: Optional[str] = None) -> Skeleton

应用示例

from nicegui import ui
import asyncio

# 不同类型骨架屏
skeleton_types = ['rect', 'circle', 'text', 'QBtn', 'QCard']

with ui.grid(columns=3).classes('w-full gap-4'):
    for skeleton_type in skeleton_types:
        with ui.card():
            ui.label(f'类型: {skeleton_type}').classes('text-caption')
            ui.skeleton(type=skeleton_type).classes('w-full')

# 内容加载示例
content_container = ui.column()

async def load_content():
    # 显示骨架屏
    content_container.clear()
    with content_container:
        # 模拟内容骨架
        with ui.card().classes('w-full'):
            ui.skeleton(type='text', width='100%', height='20px')
            ui.skeleton(type='rect', width='100%', height='100px')
            with ui.row().classes('w-full'):
                ui.skeleton(type='QBtn', width='80px')
                ui.space()
                ui.skeleton(type='QBtn', width='80px')
    
    # 模拟加载延迟
    await asyncio.sleep(2)
    
    # 显示实际内容
    content_container.clear()
    with content_container:
        with ui.card().classes('w-full'):
            ui.label('实际内容标题').classes('text-h6')
            ui.markdown('这里是加载完成的实际内容...')
            with ui.row().classes('w-full'):
                ui.button('操作一')
                ui.space()
                ui.button('操作二')

# 加载控制
ui.button('加载内容', on_click=lambda: asyncio.create_task(load_content()))

ui.run()

效果示例:

Python Web 应用开发:NiceGUI 页面布局详解

3.13 时间线 (Timeline)

时间顺序展示内容,适合历史记录、进度跟踪等场景。

语法定义

ui.timeline(side: str = "left",
            layout: str = "dense", 
            color: Optional[str] = None) -> Timeline

应用示例

from nicegui import ui

# 基本时间线
with ui.timeline(side='right', layout='loose').classes('w-full'):
    ui.timeline_entry(
        '项目启动会议',
        title='项目开始',
        subtitle='2024-01-15',
        icon='rocket'
    )
    
    ui.timeline_entry(
        '完成需求分析阶段',
        title='需求分析',
        subtitle='2024-01-22',
        icon='assignment'
    )
    
    ui.timeline_entry(
        '开发阶段进行中',
        title='开发实施',
        subtitle='2024-02-01',
        icon='code'
    )
    
    ui.timeline_entry(
        '预计完成日期',
        title='项目交付',
        subtitle='2024-03-15', 
        icon='flag'
    )

# 复杂时间线示例
project_milestones = [
    {
        'title': '设计完成',
        'subtitle': '2024-01-10',
        'description': '完成UI/UX设计稿',
        'icon': 'design_services',
        'color': 'blue'
    },
    {
        'title': '前端开发',
        'subtitle': '2024-01-25', 
        'description': '完成前端页面开发',
        'icon': 'web',
        'color': 'green'
    },
    {
        'title': '后端集成',
        'subtitle': '2024-02-10',
        'description': '前后端接口联调',
        'icon': 'storage',
        'color': 'orange'
    },
    {
        'title': '测试验收',
        'subtitle': '2024-02-25',
        'description': '系统测试和用户验收',
        'icon': 'check_circle',
        'color': 'purple'
    }
]

with ui.timeline().classes('w-full'):
    for milestone in project_milestones:
        ui.timeline_entry(
            milestone['description'],
            title=milestone['title'],
            subtitle=milestone['subtitle'],
            icon=milestone['icon'],
            color=milestone['color']
        )

ui.run()

效果示例:

Python Web 应用开发:NiceGUI 页面布局详解

3.14 幻灯片灯箱 (Carousel)

轮播展示多张图片或内容。

语法定义

ui.carousel(value: Optional[Union[CarouselSlide, str]] = None,
            on_value_change: Optional[Callable] = None,
            animated: bool = False,
            arrows: bool = False, 
            navigation: bool = False) -> Carousel

应用示例

from nicegui import ui

# 【1】基本轮播图(图片轮播)
with ui.carousel(animated=True, arrows=True, navigation=True).props(
    "height=300px"
).classes("w-full"):
    images = [
        "https://picsum.photos/id/237/800/400",
        "https://picsum.photos/id/238/800/400",
        "https://picsum.photos/id/239/800/400",
        "https://picsum.photos/id/240/800/400",
    ]
    for i, img_url in enumerate(images):
        with ui.carousel_slide().classes("p-0"):
            ui.image(img_url).classes("w-full h-full")
            with ui.column().classes(
                "absolute bottom-0 left-0 right-0 bg-black bg-opacity-50 p-4"
            ):
                ui.label(f"图片 {i+1}").classes("text-white text-h5")

# 【2】内容轮播
with ui.carousel(arrows=True, navigation=True).props(
    "height=400px autoplay=3000"
).classes("w-full"):

    slides = [
        {
            "title": "特性一",
            "content": "这是第一个特性的详细介绍,功能超级强劲...",
            "icon": "flash_on",
            "color": "blue",
        },
        {
            "title": "特性二",
            "content": "这是第二个特性的详细介绍,安全可靠...",
            "icon": "security",
            "color": "green",
        },
        {
            "title": "特性三",
            "content": "这是第三个特性的详细介绍,速度极快...",
            "icon": "speed",
            "color": "orange",
        },
    ]

    for slide in slides:
        with ui.carousel_slide():
            with ui.column().classes(
                "items-center text-center p-8 h-full justify-center"
            ):
                ui.icon(slide["icon"]).classes(f'text-{slide["color"]}-500 text-6xl')
                ui.label(slide["title"]).classes("text-2xl font-bold q-mt-md")
                ui.label(slide["content"]).classes("text-lg q-mt-md max-w-lg")

ui.run()

效果示例:

Python Web 应用开发:NiceGUI 页面布局详解

3.15 分页 (Pagination)

数据分页显示控件。

语法定义

ui.pagination(min: int,
              max: int,
              direction_links: bool = False,
              value: Optional[int] = None,
              on_change: Optional[Callable] = None) -> Pagination

应用示例

from nicegui import ui

# 基本分页
pagination = ui.pagination(1, 10, direction_links=True)
current_page = ui.label().bind_text_from(pagination, 'value', lambda v: f'当前页码: {v}')

# 数据分页示例
class DataPaginator:
    def __init__(self):
        self.data = [f'数据项 {i+1}' for i in range(100)]
        self.page_size = 10
        self.current_page = 1
        
    def get_page_data(self, page: int):
        start = (page - 1) * self.page_size
        end = start + self.page_size
        return self.data[start:end]

paginator = DataPaginator()
data_container = ui.column()

def update_data_display(page: int):
    data_container.clear()
    with data_container:
        page_data = paginator.get_page_data(page)
        for item in page_data:
            ui.label(item).classes('p-2 border-b')

# 绑定分页事件
def handle_page_change(e):
    update_data_display(e.value)

pagination.on('update:model-value', handle_page_change)

# 初始化显示
update_data_display(1)

ui.run()

效果示例:

Python Web 应用开发:NiceGUI 页面布局详解

3.16 菜单组件

3.16.1 下拉菜单 (Menu)

下拉菜单组件,提供层级化的操作选项。

应用示例

from nicegui import ui

# 基本下拉菜单
with ui.row().classes('items-center gap-4'):
    result = ui.label('请选择操作').classes('mr-auto')
    
    with ui.button('文件菜单', icon='menu'):
        with ui.menu() as file_menu:
            ui.menu_item('新建文件', lambda: result.set_text('新建文件'))
            ui.menu_item('打开文件', lambda: result.set_text('打开文件'))
            ui.separator()
            ui.menu_item('保存', lambda: result.set_text('保存'))
            ui.menu_item('另存为', lambda: result.set_text('另存为'))
            ui.separator()
            ui.menu_item('退出', lambda: result.set_text('退出'))

# 嵌套菜单
with ui.button('编辑菜单', icon='edit'):
    with ui.menu():
        ui.menu_item('撤销', lambda: result.set_text('撤销'))
        ui.menu_item('重做', lambda: result.set_text('重做'))
        ui.separator()
        
        with ui.menu_item('查找和替换'):
            with ui.menu():
                ui.menu_item('查找', lambda: result.set_text('查找'))
                ui.menu_item('替换', lambda: result.set_text('替换'))
        
        ui.menu_item('全选', lambda: result.set_text('全选'))

ui.run()

效果示例:

Python Web 应用开发:NiceGUI 页面布局详解

3.16.2 上下文菜单 (Context Menu)

右键菜单组件,提供上下文相关操作选项。

应用示例

from nicegui import ui

# 图片上下文菜单
with ui.image("https://picsum.photos/id/237/400/300").classes("cursor-context-menu"):
    with ui.context_menu():
        ui.menu_item("查看原图", lambda: ui.notify("查看原图"))
        ui.menu_item("下载图片", lambda: ui.notify("下载图片"))
        ui.separator()
        ui.menu_item("设为壁纸", lambda: ui.notify("设为壁纸"))
        ui.menu_item("分享图片", lambda: ui.notify("分享图片"))

# 文本上下文菜单
with ui.card().classes("w-full p-4 cursor-context-menu"):
    ui.label("右键点击此区域").classes("text-h6")
    ui.label("这是一个支持右键菜单的文本区域。您可以尝试右键点击查看上下文菜单选项。")

    with ui.context_menu():
        ui.menu_item("复制", lambda: ui.notify("复制内容"))
        ui.menu_item("剪切", lambda: ui.notify("剪切内容"))
        ui.menu_item("粘贴", lambda: ui.notify("粘贴内容"))
        ui.separator()
        ui.menu_item("全选", lambda: ui.notify("全选内容"))
        ui.menu_item("格式化", lambda: ui.notify("格式化内容"))

ui.run()

效果示例:

Python Web 应用开发:NiceGUI 页面布局详解

Python Web 应用开发:NiceGUI 页面布局详解

3.17 气泡提示 (Tooltip)

鼠标悬停提示信息,提供额外的上下文说明。

语法定义

ui.tooltip(text: str = "") -> Tooltip

应用示例

from nicegui import ui

# 基本提示
with ui.row().classes('gap-4 p-4'):
    with ui.button(icon='info'):
        ui.tooltip('这是一个信息提示')
    
    with ui.button(icon='warning', color='orange'):
        ui.tooltip('警告操作,请谨慎使用').classes('bg-orange')
    
    with ui.button(icon='error', color='red'):
        ui.tooltip('危险操作,可能导致数据丢失').classes('bg-red text-white')

# 复杂提示内容
with ui.button('复杂提示', icon='help', color='primary'):
    with ui.tooltip().classes('max-w-64'):
        ui.label('详细说明').classes('text-weight-bold')
        ui.markdown('''
            这是一个包含丰富内容的提示框:
            - 支持多行文本
            - 可以包含格式化内容  
            - 提供详细的操作说明
        ''')
        ui.button('了解更多', icon='launch').props('dense').classes('q-mt-sm')

ui.run()

效果示例:

Python Web 应用开发:NiceGUI 页面布局详解

3.18 通知 (Notification)

临时消息提示,用于反馈操作结果。

应用示例

from nicegui import ui

# 基本通知
def show_basic_notifications():
    ui.notify('普通通知消息')
    ui.notify('成功操作', type='positive')
    ui.notify('警告信息', type='warning') 
    ui.notify('错误提示', type='negative')
    ui.notify('信息通知', type='info')

# 不同位置的通知
def show_positioned_notifications():
    positions = ['top-left', 'top-right', 'bottom-left', 'bottom-right', 'top', 'bottom']
    for position in positions:
        ui.notify(f'{position}位置通知', position=position)

# 带按钮的通知
def show_actions_notification():
    ui.notify(
        '文件已成功上传',
        close_button='确定',
        type='positive',
        timeout=5000
    )

# 控制按钮
with ui.row().classes('gap-2 wrap'):
    ui.button('基本通知', on_click=show_basic_notifications)
    ui.button('位置演示', on_click=show_positioned_notifications) 
    ui.button('带操作', on_click=show_actions_notification)

ui.run()

效果示例:

Python Web 应用开发:NiceGUI 页面布局详解

Python Web 应用开发:NiceGUI 页面布局详解

Python Web 应用开发:NiceGUI 页面布局详解

3.19 对话框 (Dialog)

模态对话框组件,用于需要用户确认或输入的场景。

应用示例

from nicegui import ui

# 基本对话框
basic_dialog = ui.dialog()
with basic_dialog, ui.card().classes('p-4 w-80'):
    ui.label('基本对话框').classes('text-h6')
    ui.label('这是一个简单的对话框示例。')
    ui.button('关闭', on_click=basic_dialog.close)

# 确认对话框  
confirm_dialog = ui.dialog()
delete_target = None

def show_confirm_dialog(target):
    global delete_target
    delete_target = target
    confirm_dialog.open()

with confirm_dialog, ui.card().classes('p-4 w-80'):
    ui.label('确认删除').classes('text-h6 text-red')
    ui.label().bind_text_from(globals(), 'delete_target', lambda t: f'确定要删除 "{t}" 吗?')
    
    with ui.row().classes('justify-end gap-2'):
        ui.button('撤销', on_click=confirm_dialog.close).props('flat')
        ui.button('删除', on_click=lambda: (ui.notify(f'已删除 {delete_target}'), confirm_dialog.close)).props('flat color=red')

# 表单对话框
form_dialog = ui.dialog()
with form_dialog, ui.card().classes('p-4 w-96'):
    ui.label('用户信息').classes('text-h6')
    
    name = ui.input('姓名').classes('w-full')
    email = ui.input('邮箱').classes('w-full')
    role = ui.select(['用户', '管理员', '编辑']).classes('w-full')
    
    with ui.row().classes('justify-end gap-2'):
        ui.button('撤销', on_click=form_dialog.close).props('flat')
        ui.button('保存', on_click=lambda: (
            ui.notify(f'保存用户: {name.value}'),
            form_dialog.close()
        ))

# 打开对话框的按钮
with ui.row().classes('gap-2 p-4'):
    ui.button('打开基本对话框', on_click=basic_dialog.open)
    ui.button('打开确认对话框', on_click=lambda: show_confirm_dialog('示例项目'))
    ui.button('打开表单对话框', on_click=form_dialog.open)

ui.run()

效果示例:

Python Web 应用开发:NiceGUI 页面布局详解

Python Web 应用开发:NiceGUI 页面布局详解

Python Web 应用开发:NiceGUI 页面布局详解

4. 布局容器对比

容器类型

排列方式

主要用途

特点

Card

自由布局

内容分组

带边框和阴影的视觉容器

Column

垂直排列

表单项、列表

自动垂直排列子元素

Row

水平排列

工具栏、按钮组

自动水平排列子元素

Grid

网格排列

复杂布局

二维网格系统,支持响应式

List

列表排列

导航菜单、选项列表

提供统一样式的列表项

Scroll Area

滚动布局

长内容展示

提供自定义滚动体验

Expansion

可折叠布局

详情展示、手风琴

节省空间,支持折叠/展开

通过灵活组合这些布局组件,开发者可以构建出各种复杂且美观的用户界面,满足不同场景的需求。NiceGUI 的布局系统既简单易用,又具备足够的灵活性,使得 Python 开发者能够快速创建专业的 Web 应用界面。


未完待续…


#编程# #学习# #python#

© 版权声明

相关文章

暂无评论

none
暂无评论...