主题
MatplotlibChart 继承自: ft.GestureDetector, LayoutControl, AdaptiveControl, Control, BaseControl
显示一张 Matplotlib 图表。
如需显示带有内置工具栏界面的 Matplotlib 图形,请使用 MatplotlibChartWithToolbar。
警告: 此控件需要安装 matplotlib 这个 Python 包。
更多说明请参见此安装指南。
示例
python
import os
import sys
# Load Matplotlib's `ft2font` extension with RTLD_DEEPBIND, so it binds to the
# FreeType and harfbuzz it was built against.
#
# A packaged Linux app embeds Python in the Flutter process, where GTK has
# already loaded the system libfreetype/libharfbuzz into the global symbol
# namespace. `ft2font` statically links its own copies but also exports their
# symbols, so its internal calls resolve to the system ones instead. The ABI
# mismatch corrupts glyph metrics - a 10pt "-40" measures millions of points
# wide - and every text draw then fails with
# "FT_Render_Glyph ... error 0x62: raster overflow".
#
# Must run before Matplotlib is imported: the extension is cached after its
# first load. No-op wherever the flag is absent (macOS, Windows, Android, iOS,
# Pyodide) - none of those resolve symbols through a flat global namespace.
if hasattr(os, "RTLD_DEEPBIND"):
_dlopenflags = sys.getdlopenflags()
sys.setdlopenflags(_dlopenflags | os.RTLD_DEEPBIND)
try:
from matplotlib import ft2font # noqa: F401
finally:
sys.setdlopenflags(_dlopenflags)
import matplotlib.pyplot as plt
import flet as ft
import flet_charts as fch
def main(page: ft.Page):
fig, ax = plt.subplots()
fruits = ["apple", "blueberry", "cherry", "orange"]
counts = [40, 100, 30, 55]
bar_labels = ["red", "blue", "_red", "orange"]
bar_colors = ["tab:red", "tab:blue", "tab:red", "tab:orange"]
ax.bar(fruits, counts, label=bar_labels, color=bar_colors)
ax.set_ylabel("fruit supply")
ax.set_title("Fruit supply by kind and color")
ax.legend(title="Fruit color")
page.add(
ft.SafeArea(
expand=True,
content=fch.MatplotlibChart(figure=fig, expand=True),
)
)
if __name__ == "__main__":
ft.run(main)
属性
| 名称 | 类型 | 默认值 | 说明 |
|---|---|---|---|
figure | Figure | metadata={'skip': True} | Matplotlib figure to draw - an instance of matplotlib.figure.Figure. |
content | Optional[Control] | None | A child Control contained by the gesture detector. |
mouse_cursor | Optional[MouseCursor] | None | The mouse cursor for mouse pointers that are hovering over the control. |
drag_interval | int | 0 | Throttling in milliseconds for horizontal drag, vertical drag and pan update events. When a user moves a pointer a lot of events are being generated to do precise tracking. drag_interval allows sending drag update events to a Flet program every X milliseconds, thus preserving the bandwidth (web and mobile apps). 0 means no throttling: all events are sent to a Flet program, resulting in very smooth tracking. |
hover_interval | int | 0 | Throttling in milliseconds for on_hover event. |
multi_tap_touches | int | 0 | The minimum number of pointers to trigger on_multi_tap event. |
exclude_from_semantics | bool | False | Whether the gestures of this detector should be excluded from the semantics tree. Set this to True when the wrapped content already exposes the appropriate semantic actions and you do not want this detector to add duplicate accessibility announcements. |
trackpad_scroll_causes_scale | bool | False | Whether trackpad scroll gestures should be interpreted as scale gestures. When enabled, compatible trackpad pinch/scroll input can trigger on_scale_start, on_scale_update, and on_scale_end. |
allowed_devices | Optional[list[PointerDeviceType]] | None | Restricts gesture recognition to the specified pointer device types. If None, gestures from any supported input device can be recognized. |
width | Optional[Number] | None | Imposed Control width in virtual pixels. |
height | Optional[Number] | None | Imposed Control height in virtual pixels. |
left | Optional[Number] | None | The distance that the child's left edge is inset from the left of the stack. Note: Effective only if this control is a descendant of one of the following: Stack control, overlay list. |
top | Optional[Number] | None | The distance that the child's top edge is inset from the top of the stack. Note: Effective only if this control is a descendant of one of the following: Stack control, overlay list. |
right | Optional[Number] | None | The distance that the child's right edge is inset from the right of the stack. Note: Effective only if this control is a descendant of one of the following: Stack control, overlay list. |
bottom | Optional[Number] | None | The distance that the child's bottom edge is inset from the bottom of the stack. Note: Effective only if this control is a descendant of one of the following: Stack control, overlay list. |
align | Optional[Alignment] | None | Alignment of the control within its parent. |
margin | Optional[MarginValue] | None | Sets the margin of the control. |
rotate | Optional[RotateValue] | None | Transforms this control using a rotation around its center. The value of rotate property could be one of the following types: * number - a rotation in clockwise radians. Full circle 360° is math.pi * 2 radians, 90° is pi / 2, 45° is pi / 4, etc. * Rotate - allows to specify rotation angle as well as alignment - the location of rotation center. Example: python ft.Image( src="https://picsum.photos/100/100", width=100, height=100, border_radius=5, rotate=Rotate(angle=0.25 * pi, alignment=ft.Alignment.CENTER_LEFT) ) |
scale | Optional[ScaleValue] | None | Scales this control along the 2D plane. Default scale factor is 1.0, meaning no-scale. Setting this property to 0.5, for example, makes this control twice smaller, while 2.0 makes it twice larger. Different scale multipliers can be specified for x and y axis, by setting Control.scale property to an instance of Scale class. Either scale or scale_x and scale_y could be specified, but not all of them. Example: python ft.Image( src="https://picsum.photos/100/100", width=100, height=100, border_radius=5, scale=ft.Scale(scale_x=2, scale_y=0.5) ) |
offset | Optional[OffsetValue] | None | Applies a translation transformation before painting the control. The translation is expressed as an Offset scaled to the control's size. So, Offset(x=0.25, y=0), for example, will result in a horizontal translation of one quarter the width of this control. Example The following example displays container at 0, 0 top left corner of a stack as transform applies -1 * 100, -1 * 100 (offset * control's size) horizontal and vertical translations to the control: python import flet as ft def main(page: ft.Page): page.add( ft.Stack( width=1000, height=1000, controls=[ ft.Container( bgcolor=ft.Colors.RED, width=100, height=100, left=100, top=100, offset=ft.Offset(-1, -1), ) ], ) ) ft.run(main) |
flip | Optional[Flip] | None | Flips this control horizontally and/or vertically. Set to an instance of Flip to mirror across x-axis, y-axis, or both. |
transform | Optional[Transform] | None | Applies a generic matrix transform to this control. Set to an instance of Transform with a recorded Matrix4 to describe arbitrary transform sequences. |
aspect_ratio | Optional[Number] | None | The aspect ratio of the control. It is defined as the ratio of width to height. Note: In current implementation, if aspect_ratio is set, width and height on the same control are ignored for final rendered size. |
animate_opacity | Optional[AnimationValue] | None | 启用 opacity 属性的隐式动画。 详见 此处. |
animate_size | Optional[AnimationValue] | None | 启用此控件尺寸的隐式动画。 If width or height is set, changes to those dimensions are animated. If neither dimension is set, changes to the control's natural size are animated instead. 详见 此处. |
animate_position | Optional[AnimationValue] | None | 启用定位属性(left、right、top、bottom)的隐式动画。 详见 此处. |
animate_align | Optional[AnimationValue] | None | 启用 align 属性的隐式动画。 详见 此处. |
animate_margin | Optional[AnimationValue] | None | 启用 margin 属性的隐式动画。 详见 此处. |
animate_rotation | Optional[AnimationValue] | None | 启用 rotate 属性的隐式动画。 详见 此处. |
animate_scale | Optional[AnimationValue] | None | 启用 scale 属性的隐式动画。 详见 此处. |
animate_offset | Optional[AnimationValue] | None | 启用 offset 属性的隐式动画。 详见 此处. |
size_change_interval | int | 10 | Sampling interval in milliseconds for on_size_change event. Setting to 0 calls on_size_change immediately on every change. |
expand | Annotated[Optional[Union[bool, int]], V.instance_of((bool, int))] | None | 指定此控件是否/如何扩展以填充父布局中的可用空间。 详见 此处. Note: Has effect only if the direct parent of this control is one of the following controls, or their subclasses: Column, Row, View, Page. Raises: ValueError: If it is not of type bool or int. |
expand_loose | bool | False | 允许控件在主轴方向上有可用空间时扩展,但不要求填满所有可用空间。 详见 此处. Note: 若 expand_loose 为 True,则仅当同时满足以下条件时生效: - expand 不为 None,且 - the direct parent of this control is one of the following controls, or their subclasses: Column, Row, View, Page. |
col | ResponsiveNumber | 12 | 若此控件的父控件是 ResponsiveRow,此属性用于决定该控件横跨多少个虚拟列。 可以是数字,也可以是为不同断点配置不同值的字典,例如 col={"sm": 6}。 0 表示在该断点下隐藏控件,不占用任何列。 默认横跨 12 个虚拟列。 \ |
opacity | Annotated[Number, V.between(0.0, 1.0)] | 1.0 | 定义控件的透明度,取值范围 0.0(完全透明)到 1.0(完全不透明)。 抛出异常:ValueError:若不在 0.0 到 1.0 的闭区间内。 |
tooltip | Optional[TooltipValue] | None | 鼠标悬停时显示的 tooltip。 |
badge | Optional[BadgeValue] | None | 显示在控件顶部的徽标。 |
visible | bool | True | Every control has visible property which is True by default - control is rendered on the page. Setting visible to False 完全阻止该控件(及其所有子控件)渲染到页面画布上. 隐藏的控件不能通过键盘或鼠标聚焦或选中,也不会触发任何事件。 |
disabled | bool | False | Every control has disabled property which is False by default - control and all its children are enabled. Note: The value of this property will be propagated down to all children controls recursively. Example: For example, if you have a form with multiple entry controls you can disable them all together by disabling container: python ft.Column( disabled = True, controls=[ ft.TextField(), ft.TextField() ] ) |
rtl | bool | False | 控件的文字方向是否为从右到左(RTL)。 |
data | Any | skip_ | 任意类型的自定义数据。 |
key | Optional['KeyValue'] | None | 用于在更新之间保持控件身份稳定的 key。 |
adaptive | Optional[bool] | None | Enables platform-specific rendering or inheritance of adaptiveness from parent controls. |
只读属性
| 名称 | 类型 | 默认值 | 说明 |
|---|---|---|---|
parent | Optional['BaseControl'] | — | The direct ancestor(parent) of this control. It defaults to None and will only have a value when this control is mounted (added to the page tree). Page 控件(树的根)为例外 —— 它始终 parent=None。 |
page | 'Page' | — | 此控件所属的页面。 |
事件
| 名称 | 类型 | 默认值 | 说明 |
|---|---|---|---|
on_message | Optional[ft.EventHandler[MatplotlibChartMessageEvent]] | None | The event is triggered on figure message update. |
on_toolbar_buttons_update | Optional[ft.EventHandler[MatplotlibChartToolbarButtonsUpdateEvent]] | None | Triggers when toolbar buttons status is updated. |
on_force_press_start | Optional[EventHandler[ForcePressEvent['GestureDetector']]] | None | Called when a pointer has pressed with a force exceeding the start pressure. |
on_force_press_peak | Optional[EventHandler[ForcePressEvent['GestureDetector']]] | None | Called when a pointer has pressed with a force exceeding the peak pressure. |
on_force_press_update | Optional[EventHandler[ForcePressEvent['GestureDetector']]] | None | Called for each update after a force press has started. |
on_force_press_end | Optional[EventHandler[ForcePressEvent['GestureDetector']]] | None | Called when the pointer that triggered a force press is no longer in contact with the screen. |
on_tap | Optional[EventHandler[TapEvent['GestureDetector']]] | None | Called when a tap with a primary button has occurred. |
on_tap_down | Optional[EventHandler[TapEvent['GestureDetector']]] | None | Called when a pointer that might cause a tap with a primary button has contacted the screen at a particular location. |
on_tap_up | Optional[EventHandler[TapEvent['GestureDetector']]] | None | Called when a pointer that will trigger a tap with a primary button has stopped contacting the screen at a particular location. |
on_tap_move | Optional[EventHandler[TapMoveEvent['GestureDetector']]] | None | Called when a pointer that triggered a tap has moved. |
on_tap_cancel | Optional[ControlEventHandler['GestureDetector']] | None | The pointer that previously triggered on_tap_down will not end up causing a tap. |
on_multi_tap | Optional[EventHandler[TapEvent['GestureDetector']]] | None | Called when multiple pointers contacted the screen. |
on_multi_long_press | Optional[EventHandler[LongPressEndEvent['GestureDetector']]] | None | Called when a long press gesture with multiple pointers has been recognized. |
on_secondary_tap | Optional[ControlEventHandler['GestureDetector']] | None | A tap with a secondary button has occurred. |
on_secondary_tap_down | Optional[EventHandler[TapEvent['GestureDetector']]] | None | Called when a pointer that might cause a tap with a secondary button has contacted the screen at a particular location. |
on_secondary_tap_up | Optional[EventHandler[TapEvent['GestureDetector']]] | None | Called when a pointer that will trigger a tap with a secondary button has stopped contacting the screen at a particular location. |
on_secondary_tap_cancel | Optional[ControlEventHandler['GestureDetector']] | None | The pointer that previously triggered on_secondary_tap_down will not end up causing a tap. |
on_tertiary_tap_down | Optional[EventHandler[TapEvent['GestureDetector']]] | None | Called when a pointer that might cause a tap with a tertiary button has contacted the screen at a particular location. |
on_tertiary_tap_up | Optional[EventHandler[TapEvent['GestureDetector']]] | None | Called when a pointer that will trigger a tap with a tertiary button has stopped contacting the screen at a particular location. |
on_tertiary_tap_cancel | Optional[ControlEventHandler['GestureDetector']] | None | The pointer that previously triggered on_tertiary_tap_down will not end up causing a tap. |
on_long_press_down | Optional[EventHandler[LongPressDownEvent['GestureDetector']]] | None | Called when a pointer that might cause a long press with a primary button has contacted the screen. |
on_long_press_cancel | Optional[ControlEventHandler['GestureDetector']] | None | The pointer that previously triggered on_long_press_down will not end up causing a long-press. |
on_long_press | Optional[ControlEventHandler['GestureDetector']] | None | Called when a long press gesture with a primary button has been recognized. |
on_long_press_start | Optional[EventHandler[LongPressStartEvent['GestureDetector']]] | None | Triggered when a pointer has remained in contact with the screen at the same location for a long period of time. |
on_long_press_move_update | Optional[EventHandler[LongPressMoveUpdateEvent['GestureDetector']]] | None | Called when, after a long press has been accepted, the pointer moves. |
on_long_press_up | Optional[ControlEventHandler['GestureDetector']] | None | Called when a pointer that has triggered a long press with a primary button is no longer in contact with the screen. |
on_long_press_end | Optional[EventHandler[LongPressEndEvent['GestureDetector']]] | None | Called when a pointer that has triggered a long-press with a primary button has stopped contacting the screen. |
on_secondary_long_press_down | Optional[EventHandler[LongPressDownEvent['GestureDetector']]] | None | Called when a pointer that might cause a long press with a secondary button has contacted the screen. |
on_secondary_long_press_cancel | Optional[ControlEventHandler['GestureDetector']] | None | The pointer that previously triggered on_secondary_long_press_down not end up causing a long-press. |
on_secondary_long_press | Optional[ControlEventHandler['GestureDetector']] | None | Called when a long press gesture with a secondary button has been recognized. |
on_secondary_long_press_start | Optional[EventHandler[LongPressStartEvent['GestureDetector']]] | None | Triggered when a pointer has remained in contact with the screen at the same location for a long period of time. |
on_secondary_long_press_move_update | Optional[EventHandler[LongPressMoveUpdateEvent['GestureDetector']]] | None | Called when, after a secondary long press has been accepted, the pointer moves. |
on_secondary_long_press_up | Optional[ControlEventHandler['GestureDetector']] | None | Called when a pointer that has triggered a long press with a secondary button is no longer in contact with the screen. |
on_secondary_long_press_end | Optional[EventHandler[LongPressEndEvent['GestureDetector']]] | None | Called when a pointer that has triggered a long-press with a secondary button has stopped contacting the screen. |
on_tertiary_long_press_down | Optional[EventHandler[LongPressDownEvent['GestureDetector']]] | None | Called when a pointer that might cause a long press with a tertiary button has contacted the screen. |
on_tertiary_long_press_cancel | Optional[ControlEventHandler['GestureDetector']] | None | The pointer that previously triggered on_tertiary_long_press_down will not end up causing a long-press. |
on_tertiary_long_press | Optional[ControlEventHandler['GestureDetector']] | None | Called when a long press gesture with a tertiary button has been recognized. |
on_tertiary_long_press_start | Optional[EventHandler[LongPressStartEvent['GestureDetector']]] | None | Triggered when a pointer has remained in contact with the screen at the same location for a long period of time. |
on_tertiary_long_press_move_update | Optional[EventHandler[LongPressMoveUpdateEvent['GestureDetector']]] | None | Called when, after a tertiary long press has been accepted, the pointer moves. |
on_tertiary_long_press_up | Optional[ControlEventHandler['GestureDetector']] | None | Called when a pointer that has triggered a long press with a tertiary button is no longer in contact with the screen. |
on_tertiary_long_press_end | Optional[EventHandler[LongPressEndEvent['GestureDetector']]] | None | Called when a pointer that has triggered a long-press with a tertiary button has stopped contacting the screen. |
on_double_tap | Optional[ControlEventHandler['GestureDetector']] | None | The user has tapped the screen with a primary button at the same location twice in quick succession. |
on_double_tap_down | Optional[EventHandler[TapEvent['GestureDetector']]] | None | Called when a pointer that might cause a double tap has contacted the screen at a particular location. Triggered immediately after the down event of the second tap. |
on_double_tap_cancel | Optional[ControlEventHandler['GestureDetector']] | None | The pointer sequence that was expected to cause a double tap will not do so. |
on_horizontal_drag_down | Optional[EventHandler[DragDownEvent['GestureDetector']]] | None | Called when a pointer has contacted the screen and might begin to move horizontally. |
on_horizontal_drag_start | Optional[EventHandler[DragStartEvent['GestureDetector']]] | None | Called when a pointer has contacted the screen with a primary button and has begun to move horizontally. |
on_horizontal_drag_update | Optional[EventHandler[DragUpdateEvent['GestureDetector']]] | None | Called when a pointer that is in contact with the screen and moving horizontally has moved in the horizontal direction. |
on_horizontal_drag_end | Optional[EventHandler[DragEndEvent['GestureDetector']]] | None | Called when a pointer moving horizontally is no longer in contact and was moving at a specific velocity. |
on_horizontal_drag_cancel | Optional[ControlEventHandler['GestureDetector']] | None | The pointer that previously triggered on_horizontal_drag_down will not end up causing a horizontal drag. |
on_vertical_drag_down | Optional[EventHandler[DragDownEvent['GestureDetector']]] | None | Called when a pointer has contacted the screen and might begin to move vertically. |
on_vertical_drag_start | Optional[EventHandler[DragStartEvent['GestureDetector']]] | None | Called when a pointer has contacted the screen and has begun to move vertically. |
on_vertical_drag_update | Optional[EventHandler[DragUpdateEvent['GestureDetector']]] | None | A pointer moving vertically has moved in the vertical direction. |
on_vertical_drag_end | Optional[EventHandler[DragEndEvent['GestureDetector']]] | None | Called when a pointer moving vertically is no longer in contact and was moving at a specific velocity. |
on_vertical_drag_cancel | Optional[ControlEventHandler['GestureDetector']] | None | The pointer that previously triggered on_vertical_drag_down will not end up causing a vertical drag. |
on_pan_down | Optional[EventHandler[DragDownEvent['GestureDetector']]] | None | Called when a pointer has contacted the screen and might begin to move. |
on_pan_start | Optional[EventHandler[DragStartEvent['GestureDetector']]] | None | Called when a pointer has contacted the screen and has begun to move. |
on_pan_update | Optional[EventHandler[DragUpdateEvent['GestureDetector']]] | None | Called when a pointer that is in contact with the screen and moving has moved again. |
on_pan_end | Optional[EventHandler[DragEndEvent['GestureDetector']]] | None | Called when a pointer is no longer in contact and was moving at a specific velocity. |
on_pan_cancel | Optional[ControlEventHandler['GestureDetector']] | None | The pointer that previously triggered on_pan_down will not end up causing a pan gesture. |
on_right_pan_start | Optional[EventHandler[PointerEvent['GestureDetector']]] | None | Pointer has contacted the screen while secondary button pressed and has begun to move. |
on_right_pan_update | Optional[EventHandler[PointerEvent['GestureDetector']]] | None | A pointer that is in contact with the screen, secondary button pressed and moving has moved again. |
on_right_pan_end | Optional[EventHandler[PointerEvent['GestureDetector']]] | None | A pointer with secondary button pressed is no longer in contact and was moving at a specific velocity. |
on_scale_start | Optional[EventHandler[ScaleStartEvent['GestureDetector']]] | None | Called when the pointers in contact with the screen have established a focal point and initial scale of 1.0. |
on_scale_update | Optional[EventHandler[ScaleUpdateEvent['GestureDetector']]] | None | Called when the focal point, scale factor, or rotation of an active scale gesture changes. |
on_scale_end | Optional[EventHandler[ScaleEndEvent['GestureDetector']]] | None | Called when an active scale gesture ends. |
on_hover | Optional[EventHandler[HoverEvent['GestureDetector']]] | None | Called when a mouse pointer has entered this control. |
on_enter | Optional[EventHandler[HoverEvent['GestureDetector']]] | None | Called when a mouse pointer has entered this control. |
on_exit | Optional[EventHandler[HoverEvent['GestureDetector']]] | None | Called when a mouse pointer has exited this control. |
on_scroll | Optional[EventHandler[ScrollEvent['GestureDetector']]] | None | Called when a pointer scroll event is received, such as a mouse wheel or trackpad scroll. |
on_size_change | Optional[EventHandler[LayoutSizeChangeEvent['LayoutControl']]] | None | Called when the size of this control changes. size_change_interval defines how often this event is called. |
on_animation_end | Optional[ControlEventHandler['LayoutControl']] | None | 动画结束时调用,可用于串联多个动画。 事件参数 data 属性包含动画的名称。 详见 此处. |
方法
| 名称 | 类型 | 默认值 | 说明 |
|---|---|---|---|
init | — | — | — |
build | — | — | — |
will_unmount | — | — | Called when the control is about to be removed from the page. |
home | — | — | Resets the view to the original state. |
back | — | — | Goes back to the previous view. |
forward | — | — | Goes forward to the next view. |
pan | — | — | Activates the pan tool. |
zoom | — | — | Activates the zoom tool. |
download | bytes | — | Downloads the current figure in the specified format. Args: format (str): The format to download the figure in (e.g., 'png', 'jpg', 'svg', etc.). Returns: bytes: The figure image in the specified format as a byte array. |
send_message | — | — | Sends a message to the figure's canvas manager. |
send_json | — | — | Sends a JSON message to the front end. |
send_binary | — | — | Sends a binary message to the front end. Receives PNG bytes from matplotlib's stock full/diff path, or a (width, height, rgba) tuple from FigureManagerFletAgg.refresh_all in raw mode. This method runs synchronously inside refresh_all() (same stack as draw()), which is the last safe moment to copy the raw buffer — it aliases the live Agg buffer that the next draw mutates in place. encode_raw_frame performs that one copy while assembling the wire packet. |
is_isolated | — | — | Return whether this control is marked as isolated. 被隔离的控件不会参与父级驱动的更新遍历,需要自行管理更新边界。 |
before_update | — | — | 每次控件即将更新时调用。 Note: 不要在此处调用 update()。 |
before_event | — | — | 在事件处理器执行前拦截事件。 返回 False 取消分发,返回 True 或 None 则继续正常的事件处理。 |
did_mount | — | — | 在控件挂载到页面树之后调用。 可重写以启动需要已挂载页面的资源,例如订阅、定时器或服务监听。 |
get_data_channel | — | — | Resolve the [DataChannel] allocated on the Dart side for this widget. Pattern: on_data_channel_open: Optional[ft.EventHandler[DataChannelOpenEvent]] = None def init(self): self.on_data_channel_open = self._on_open def _on_open(self, e): self._channel = self.get_data_channel(e.channel_id) Idempotent — the underlying Connection caches DataChannels by id, so repeated calls return the same instance. No error path: the id always comes from a framework-fired event, so by the time this runs the channel exists on both sides. |
update | None | — | 请求更新该控件的 UI。 在修改控件状态或属性后调用。 控件必须已挂载到页面,并且未被冻结。 |