一种高度封装gradio的调研方法

simon
1
2025-10-21
1. 普通封装
import gradio as gr

# ========================
# 1. 用户状态栏
# ========================
class UserBar:
    def __init__(self, username: str = "Simon"):
        self.username = username 
        with gr.Row():
            self.status_md = gr.Markdown("### 😄 幽默模式,请登录")
            self.login_btn = gr.Button("登录", visible=True)
            self.register_btn = gr.Button("注册", visible=True)
            self.logout_btn = gr.Button("登出", visible=False)

    def bind_events(self, login_state):
        self.login_btn.click(fn=lambda: True, outputs=login_state)
        self.register_btn.click(fn=lambda: True, outputs=login_state)
        self.logout_btn.click(fn=lambda: False, outputs=login_state)
        login_state.change(
            fn=self._update_ui,
            inputs=login_state,
            outputs=[self.status_md, self.login_btn, self.register_btn, self.logout_btn]
        )

    def _update_ui(self, is_logged_in: bool):
        if is_logged_in:
            return (
                gr.update(value=f"### {self.username}", visible=True),
                gr.update(visible=False),
                gr.update(visible=False),
                gr.update(visible=True)
            )
        else:
            return (
                gr.update(value="### 😄 幽默模式,请登录", visible=True),
                gr.update(visible=True),
                gr.update(visible=True),
                gr.update(visible=False)
            )

# ========================
# 2. 游客欢迎区(未登录时显示)
# ========================
class GuestWelcome:
    def __init__(self):
        with gr.Column(visible=True) as self.container:
            gr.Markdown("### 👋 欢迎!登录后解锁神奇功能")
            gr.Markdown("✨ 查看数据仪表盘\n\n🔒 管理你的内容\n\n🚀 体验完整模式")

    def get_container(self):
        return self.container

# ========================
# 3. 仪表盘(登录后显示)
# ========================
class DashboardPanel:
    def __init__(self):
        with gr.Column(visible=False) as self.container:
            gr.Markdown("### 📊 你的专属仪表盘")
            gr.Markdown("✅ 已登录用户可见\n\n📈 实时数据\n\n⚙️ 个性化设置")

    def get_container(self):
        return self.container

# ========================
# 主应用
# ========================
with gr.Blocks(title="模块化 + 动态显示") as demo:
    login_state = gr.State(False)

    # 创建所有模块
    user_bar = UserBar(username="Simon")
    guest_welcome = GuestWelcome()
    dashboard = DashboardPanel()

    # 绑定用户栏事件
    user_bar.bind_events(login_state)

    # 核心:根据登录状态切换欢迎区 / 仪表盘的可见性
    login_state.change(
        fn=lambda is_logged_in: (
            gr.update(visible=not is_logged_in),  # GuestWelcome 可见性
            gr.update(visible=is_logged_in)       # Dashboard 可见性
        ),
        inputs=login_state,
        outputs=[guest_welcome.get_container(), dashboard.get_container()]
    )

demo.launch()
2. 根据用户名封装是否可见
import gradio as gr

# ========================
# 1. 用户状态栏(保持不变)
# ========================
class UserBar:
    def __init__(self):
        with gr.Row():
            self.status_md = gr.Markdown("### 😄 幽默模式,请登录")
            self.login_btn = gr.Button("登录为 Simon", visible=True)
            self.login_admin_btn = gr.Button("登录为 Admin", visible=True)
            self.logout_btn = gr.Button("登出", visible=False)

    def bind_events(self, user_state):
        self.login_btn.click(fn=lambda: "Simon", outputs=user_state)
        self.login_admin_btn.click(fn=lambda: "admin", outputs=user_state)
        self.logout_btn.click(fn=lambda: None, outputs=user_state)
        user_state.change(
            fn=self._update_ui,
            inputs=user_state,
            outputs=[self.status_md, self.login_btn, self.login_admin_btn, self.logout_btn]
        )

    def _update_ui(self, username: str | None):
        if username:
            return (
                gr.update(value=f"### 当前用户: {username}", visible=True),
                gr.update(visible=False),
                gr.update(visible=False),
                gr.update(visible=True)
            )
        else:
            return (
                gr.update(value="### 😄 幽默模式,请登录", visible=True),
                gr.update(visible=True),
                gr.update(visible=True),
                gr.update(visible=False)
            )

# ========================
# 2. 游客欢迎区(保持不变)
# ========================
class GuestWelcome:
    def __init__(self):
        with gr.Column(visible=True) as self.container:
            gr.Markdown("### 👋 欢迎!请选择登录身份")
            gr.Markdown("普通用户 or 管理员?")

    def get_container(self):
        return self.container

# ========================
# 3. 普通用户面板(✅ 新增交互控件 + 事件)
# ========================
class UserPanel:
    def __init__(self):
        with gr.Column(visible=False) as self.container:
            gr.Markdown("### 🧑‍💼 普通用户面板")
            self.bio_input = gr.Textbox(label="个人简介", placeholder="介绍一下你自己...")
            self.save_bio_btn = gr.Button("保存简介")
            self.bio_output = gr.Textbox(label="保存结果", interactive=False)

        # 绑定事件:保存简介
        self.save_bio_btn.click(
            fn=self._save_bio,
            inputs=[self.bio_input],
            outputs=self.bio_output
        )

    def get_container(self):
        return self.container

    def _save_bio(self, bio: str):
        if not bio.strip():
            return "⚠️ 简介不能为空!"
        return f"✅ 个人简介已保存:{bio[:50]}{'...' if len(bio) > 50 else ''}"

# ========================
# 4. 管理员面板(✅ 新增交互控件 + 事件)
# ========================
class AdminPanel:
    def __init__(self):
        with gr.Column(visible=False) as self.container:
            gr.Markdown("### 🔐 管理员控制台")
            self.user_to_ban = gr.Textbox(label="输入要封禁的用户名")
            self.ban_btn = gr.Button("封禁用户")
            self.ban_result = gr.Textbox(label="操作结果", interactive=False)

        # 绑定事件:封禁用户
        self.ban_btn.click(
            fn=self._ban_user,
            inputs=[self.user_to_ban],
            outputs=self.ban_result
        )

    def get_container(self):
        return self.container

    def _ban_user(self, username: str):
        if not username.strip():
            return "❌ 请输入有效的用户名"
        return f"🚫 用户 '{username}' 已被封禁!(模拟操作)"

# ========================
# 主应用(保持逻辑不变)
# ========================
with gr.Blocks(title="多用户角色控制 + 交互面板") as demo:
    user_state = gr.State(None)

    user_bar = UserBar()
    guest_welcome = GuestWelcome()
    user_panel = UserPanel()      # 现在包含交互
    admin_panel = AdminPanel()    # 现在包含交互

    user_bar.bind_events(user_state)

    user_state.change(
        fn=lambda username: (
            gr.update(visible=(username is None)),           # GuestWelcome
            gr.update(visible=(username == "Simon")),        # UserPanel
            gr.update(visible=(username == "admin")),        # AdminPanel
        ),
        inputs=user_state,
        outputs=[
            guest_welcome.get_container(),
            user_panel.get_container(),
            admin_panel.get_container(),
        ]
    )

demo.launch()
3. 多用户权限管理
import gradio as gr

# ========================
# 用户权限配置(blocks 控制功能模块)
# ========================
USERS = {
    "simon": {"blocks": ["user", "apk"]},
    "alice": {"blocks": ["user"]},
    "admin": {"blocks": ["user", "apk", "admin"]},
    "guest": {"blocks": []},
}

# ========================
# 页眉(Header)—— 始终显示
# ========================
class Header:
    def __init__(self):
        with gr.Column():
            # 系统标题(始终显示)
            gr.Markdown("## 🚀 权限控制系统")
            
            # 欢迎语(登录后显示)
            self.welcome_md = gr.Markdown("", visible=False)
            
            # 登录控件(未登录时显示)
            with gr.Row(visible=True) as self.login_row:
                self.user_dropdown = gr.Dropdown(
                    choices=list(USERS.keys()),
                    label="选择用户",
                    value=None
                )
                self.login_btn = gr.Button("登录")
            
            # 登出按钮(登录后显示)
            self.logout_btn = gr.Button("登出", visible=False)

    def bind_events(self, user_state):
        self.login_btn.click(
            fn=lambda u: u if u in USERS else None,
            inputs=self.user_dropdown,
            outputs=user_state
        )
        self.logout_btn.click(lambda: None, outputs=user_state)
        user_state.change(
            fn=self._update_ui,
            inputs=user_state,
            outputs=[self.welcome_md, self.login_row, self.logout_btn]
        )

    def _update_ui(self, username):
        if username:
            return (
                gr.update(value=f"### 👋 欢迎,{username}!", visible=True),
                gr.update(visible=False),
                gr.update(visible=True)
            )
        else:
            return (
                gr.update(value="", visible=False),
                gr.update(visible=True),
                gr.update(visible=False)
            )

# ========================
# 页脚(Footer)—— 始终显示
# ========================
class Footer:
    def __init__(self):
        with gr.Column():
            gr.Markdown("---")
            gr.Markdown("© 2025 权限系统演示 · 所有权限由配置决定")

# ========================
# 功能模块基类
# ========================
class BaseBlock:
    name = "base"
    def get_name(self): return self.name
    def get_container(self): raise NotImplementedError

# ========================
# 功能模块
# ========================
class UserBlock(BaseBlock):
    name = "user"
    def __init__(self):
        with gr.Column(visible=False) as self.container:
            gr.Markdown("### 🧑‍💼 用户中心")
            bio = gr.Textbox(label="个人简介")
            save_btn = gr.Button("保存")
            result = gr.Textbox(label="结果", interactive=False)
            save_btn.click(lambda x: f"✅ 简介已保存: {x}", bio, result)
    def get_container(self): return self.container

class ApkBlock(BaseBlock):
    name = "apk"
    def __init__(self):
        with gr.Column(visible=False) as self.container:
            gr.Markdown("### 📦 APK 管理")
            version = gr.Textbox(label="版本")
            upload_btn = gr.Button("上传")
            log = gr.Textbox(label="日志", lines=3)
            upload_btn.click(lambda v: f"📤 {v}.apk 上传成功!", version, log)
    def get_container(self): return self.container

class AdminBlock(BaseBlock):
    name = "admin"
    def __init__(self):
        with gr.Column(visible=False) as self.container:
            gr.Markdown("### 🔐 管理控制台")
            cmd = gr.Textbox(label="命令")
            exec_btn = gr.Button("执行")
            out = gr.Textbox(label="输出", lines=4)
            exec_btn.click(lambda c: f"💻 执行: {c}\n✅ 完成。", cmd, out)
    def get_container(self): return self.container

# ========================
# 主应用
# ========================
with gr.Blocks(title="权限系统 - 页眉页脚 + 模块权限") as demo:
    user_state = gr.State(None)

    # === 页眉(始终在最顶)===
    header = Header()

    # === 功能模块区域 ===
    blocks = [UserBlock(), ApkBlock(), AdminBlock()]
    containers = [b.get_container() for b in blocks]
    block_names = [b.get_name() for b in blocks]

    # === 页脚(始终在最底)===
    footer = Footer()

    # 绑定事件
    header.bind_events(user_state)

    # 根据用户权限控制功能模块显隐
    def update_visibility(username):
        if not username:
            return [gr.update(visible=False) for _ in blocks]
        allowed = set(USERS[username]["blocks"])
        return [gr.update(visible=(name in allowed)) for name in block_names]

    user_state.change(
        fn=update_visibility,
        inputs=user_state,
        outputs=containers
    )

demo.launch()

动物装饰