PythonIDE Docs
中文
简体中文

WebView 与系统分享

WebView URL/HTML 预览、TextEditor 编辑和 ShareLink 分享。

演示 WebView(URL 与本地 HTML)、TextEditor 编辑与 ShareLink 分享文本。

#预期效果

运行后会出现 WebView 预览与分享页,编辑文本、生成预览和系统分享入口保持同步。

#完整示例

python
import html

import appui
import haptics

state = appui.State(
    title="MiniApp 使用说明",
    body_text="这里可以放 Markdown 转换后的说明、报告摘要或接口返回的富文本预览。",
    preview_mode="本地 HTML",
    status="可预览",
)


def set_title(value):
    state.batch_update(title=value, status="内容已修改,预览会自动更新")


def set_body(value):
    state.batch_update(body_text=value, status="内容已修改,预览会自动更新")


def set_mode(value):
    state.batch_update(preview_mode=value, status=f"已切换到 {value}")


def html_preview():
    safe_title = html.escape(state.title)
    safe_body = html.escape(state.body_text).replace("\n", "<br>")
    return f"""
    <html>
    <head>
      <meta name="viewport" content="width=device-width, initial-scale=1">
      <style>
        body {{ font: -apple-system-body; padding: 22px; background: #f7f7f7; color: #111; }}
        article {{ background: white; border-radius: 16px; padding: 18px; }}
        h1 {{ font-size: 26px; margin: 0 0 12px; }}
        p {{ line-height: 1.45; }}
      </style>
    </head>
    <body>
      <article>
        <h1>{safe_title}</h1>
        <p>{safe_body}</p>
      </article>
    </body>
    </html>
    """


def mark_ready():
    state.status = "已生成预览"
    haptics.notification("success")


def native_file_export():
    return f"{state.title}\n\n{state.body_text}"


def preview_view():
    if state.preview_mode == "网页 URL":
        return appui.WebView(url="https://www.apple.com")
    return appui.WebView(html=html_preview())


def body():
    share_text = native_file_export()
    return appui.NavigationStack(
        appui.TabView(
            [
                appui.Tab(
                    "编辑",
                    system_image="square.and.pencil",
                    content=appui.Form(
                        [
                            appui.Section(
                                [
                                    appui.TextField("标题", text=state.title, on_change=set_title),
                                    appui.TextEditor(
                                        text=state.body_text,
                                        on_change=set_body,
                                    ).frame(height=160),
                                    appui.Picker(
                                        "预览来源",
                                        selection=state.preview_mode,
                                        options=["本地 HTML", "网页 URL"],
                                        on_change=set_mode,
                                    ),
                                ],
                                header="内容",
                            ),
                            appui.Section(
                                [
                                    appui.LabeledContent("状态", value=state.status),
                                    (
                                        appui.Button("生成预览", action=mark_ready)
                                        .button_style("bordered_prominent")
                                    ),
                                    appui.ShareLink(
                                        item=share_text,
                                        subject=state.title,
                                        message="来自 MiniApp",
                                    ),
                                ],
                                header="操作",
                            ),
                        ]
                    ),
                ),
                appui.Tab(
                    "预览",
                    system_image="safari",
                    content=preview_view(),
                ),
            ]
        ).navigation_title("网页预览")
    )


appui.run(body, state=state, presentation="sheet")

#关键技巧

  • WebView(url=...) 打开网页;WebView(html=...) 渲染本地 HTML 字符串。
  • HTML 放在普通 State 字段,不要把 WebView 实例放进状态。
  • MiniApp 内导出/分享优先 ShareLink(item=..., subject=..., message=...);设置类界面仍用原生 Form/List
  • 用户输入进入 HTML 前要用 html.escape,避免把正文当作原始 HTML 执行。