从CSS到QML布局

📖 QML 布局功能点与 CSS Flexbox 对比实现


1. flex-direction: row / column

CSS:

.container {
    display: flex;
    flex-direction: row;  /* 横向布局 */
    flex-direction: column;  /* 纵向布局 */
}

QML:

  • Row:QML 中的 RowRowLayout 等效于 flex-direction: row,子元素按水平排列。
  • Column:QML 中的 ColumnColumnLayout 等效于 flex-direction: column,子元素按垂直排列。
Row {
    spacing: 10
    Rectangle { width: 50; height: 50; color: "red" }
    Rectangle { width: 50; height: 50; color: "blue" }
}

Column {
    spacing: 10
    Rectangle { width: 50; height: 50; color: "green" }
    Rectangle { width: 50; height: 50; color: "yellow" }
}

2. flex-wrap: wrap

CSS:

.container {
    display: flex;
    flex-wrap: wrap;  /* 让子项超出容器宽度时自动换行 */
}

QML:

  • FlowFlow 容器允许子项超出宽度时自动换行,类似于 flex-wrap: wrap
Flow {
    spacing: 8
    width: parent.width  // 给定父容器宽度,让子项超出时自动换行
    Repeater {
        model: 15
        Rectangle {
            width: 100
            height: 40
            color: Qt.rgba(Math.random(), Math.random(), Math.random(), 1)
        }
    }
}

3. flex-grow: 1

CSS:

.item {
    flex-grow: 1;  /* 占满剩余空间 */
}

QML:

  • Layout.fillWidth / Layout.fillHeight:当子项的 Layout.fillWidthLayout.fillHeight 设置为 true 时,子项会占据剩余的可用空间。
RowLayout {
    spacing: 10
    Rectangle { width: 50; height: 40; color: "red" }
    Rectangle { Layout.fillWidth: true; height: 40; color: "green" }  // 等效 flex-grow: 1
    Rectangle { width: 50; height: 40; color: "blue" }
}

4. justify-content: flex-start / center / flex-end

CSS:

.container {
    display: flex;
    justify-content: flex-start;  /* 左对齐 */
    justify-content: center;  /* 居中 */
    justify-content: flex-end;  /* 右对齐 */
}

QML:

  • Layout.alignment:通过设置 Layout.alignment 来控制子项的对齐方式。
RowLayout {
    spacing: 10
    Rectangle { width: 50; height: 40; color: "red"; Layout.alignment: Qt.AlignLeft }  // 左对齐
    Rectangle { width: 50; height: 40; color: "green"; Layout.alignment: Qt.AlignHCenter }  // 居中
    Rectangle { width: 50; height: 40; color: "blue"; Layout.alignment: Qt.AlignRight }  // 右对齐
}

5. justify-content: space-between

CSS:

.container {
    display: flex;
    justify-content: space-between;  /* 子项之间的空隙自动分配 */
}

QML:

  • Spacer:在 RowLayoutColumnLayout 中,使用 Item { Layout.fillWidth: true } 作为间隔项来实现 space-between 效果。
RowLayout {
    spacing: 10
    Rectangle { width: 50; height: 40; color: "red" }
    Item { Layout.fillWidth: true }  // 占满中间的空白,等效 space-between
    Rectangle { width: 50; height: 40; color: "green" }
}

6. min-width / max-width / preferredWidth

CSS:

.item {
    min-width: 100px;
    max-width: 200px;
    flex-basis: 150px;  /* 默认宽度 */
}

QML:

  • Layout.minimumWidth / Layout.maximumWidth:可以设置子项的最小和最大宽度。
  • Layout.preferredWidth:设置默认宽度(类似 flex-basis)。
Rectangle {
    Layout.minimumWidth: 100  // 最小宽度
    Layout.maximumWidth: 200  // 最大宽度
    Layout.preferredWidth: 150  // 默认宽度
    height: 40
    color: "red"
}

7. 内容撑开父容器

CSS:

.container {
    display: flex;
    width: 100%;  /* 父容器宽度由子项撑开 */
}

QML:

  • implicitWidth / implicitHeight:父容器会根据子项的 implicitWidthimplicitHeight 自动调整大小。
Column {
    spacing: 10
    Rectangle { width: 100; height: 40; color: "red" }
    Rectangle { width: 200; height: 40; color: "green" }
    Rectangle { width: 300; height: 40; color: "blue" }
}

8. align-items: flex-start / center / flex-end / stretch

CSS:

.container {
    display: flex;
    align-items: flex-start;  /* 顶部对齐 */
    align-items: center;      /* 垂直居中 */
    align-items: flex-end;    /* 底部对齐 */
    align-items: stretch;     /* 拉伸 */
}

QML:

  • Layout.alignment:通过 Layout.alignment 来控制子项的垂直对齐方式。
  • Layout.fillHeight:通过设置 fillHeight: true 来拉伸子项填满父容器的高度。
ColumnLayout {
    Rectangle { color: "red"; Layout.preferredHeight: 40; Layout.alignment: Qt.AlignTop }  // 顶部对齐
    Rectangle { color: "green"; Layout.preferredHeight: 40; Layout.alignment: Qt.AlignVCenter }  // 垂直居中
    Rectangle { color: "blue"; Layout.preferredHeight: 40; Layout.alignment: Qt.AlignBottom }  // 底部对齐
    Rectangle { color: "yellow"; Layout.fillHeight: true; Layout.preferredHeight: 40; }  // 拉伸
}

✅ 总结对比

CSS Flexbox 功能 QML 等效实现方式 说明
flex-direction: row Row / RowLayout 横向布局
flex-direction: column Column / ColumnLayout 纵向布局
flex-wrap: wrap Flow 自动换行
justify-content: center Layout.alignment: Qt.AlignHCenter 居中对齐
justify-content: space-between Item { Layout.fillWidth: true } 两端对齐
min-width / max-width Layout.minimumWidth / maximumWidth 控制最小/最大宽度
align-items: stretch Layout.fillHeight: true 子项拉伸以适配父容器高度
flex-grow Layout.fillWidth: true 占满剩余空间
内容撑开父容器 implicitWidth / implicitHeight 父容器由子项撑开

⚠️ QML 难以直接做到的(需要手写 FlowLayout 或 hack)

  1. flex-basis

    • CSS 可以设置子元素的“初始大小” (flex-basis),再配合 flex-grow 动态分配剩余空间。
    • QML 没有直接属性,只能用 implicitWidth + fillWidth 手工模拟。
  2. justify-content: space-around / space-evenly

    • QML RowLayout 只能靠 Spacer 实现部分效果(space-between 可以,space-around / evenly 需要自己算间距)。
  3. 子元素按比例分配空间

    • CSS flex: 2 / flex: 3 这种比例伸缩,QML 没有原生支持。
    • 需要手写 onWidthChanged 根据比例手动调整。
  4. 自动换行时保持整齐对齐

    • CSS Flex 可以保证换行后每一行的 间距和对齐
    • QML 自带 Flow 只能“往右排满就换行”,无法控制每行等间距。
    • 必须自写 FlowLayout,在计算时手动调整每行的 spacing。
  5. order(排序)

    • CSS order 可以控制子元素在布局中的顺序。
    • QML 只能通过 zvisible 控制,或者在 Repeater 里改 model 顺序。
  6. flex-shrink

    • CSS 可以指定元素在缩小时按比例收缩。
    • QML 只有 min/maxWidth,无法做到“按比例 shrink”。
  7. 跨行/跨列(类似 grid 的特性)

    • CSS Grid 可以让某个 item 占两列。
    • QML Flow/RowLayout 都不支持,需要用 GridLayout,但 Grid 又不支持 wrap。
      👌 明白了,你不需要我写个完整实现,
      只要我帮你 对照 CSS Flexbox ↔ QML 自带布局,再指出 QML 做不到的地方

✅ QML 自带布局 vs CSS Flexbox

CSS Flexbox 功能 QML 等效方式 说明
flex-direction: row Row / RowLayout 横向排列
flex-direction: column Column / ColumnLayout 纵向排列
flex-wrap: wrap Flow 子元素超过宽度自动换行
justify-content: flex-start RowLayout 默认 左对齐
justify-content: flex-end 在 RowLayout 里用 Item { Layout.fillWidth: true } 当 spacer 右对齐
justify-content: center RowLayout + Layout.alignment: Qt.AlignHCenter 居中
justify-content: space-between RowLayout + 中间放 Item { Layout.fillWidth: true } 两端对齐
justify-content: space-around / space-evenly 没有原生支持 需要手动 Spacer 或自定义布局
align-items: flex-start / flex-end / center Layout.alignment: Qt.AlignTop / AlignBottom / AlignVCenter 垂直方向对齐
align-items: stretch Layout.fillHeight: true 子元素拉伸填满高度
flex-grow Layout.fillWidth: trueLayout.fillHeight: true 占据剩余空间
flex-shrink 没有 shrink 概念 宽度不会自动压缩,只能手动指定 min/max
flex-basis Layout.preferredWidth / Layout.preferredHeight 默认尺寸
min-width / max-width Layout.minimumWidth / maximumWidth 控制约束
自动换行 (wrap) Flow 有,但 不支持最小/最大宽度计算
内容撑开父容器 implicitWidth/HeightLayout.preferredWidth 容器由子项撑大
order (重新排序) 不支持 QML 按声明顺序绘制,不能像 flex order 那样调换

⚠️ QML 做不到 / 不完善的地方

  1. flex-shrink

    • QML 没有压缩概念,子元素超过父容器不会自动缩小,只会溢出。
  2. justify-content: space-around / space-evenly

    • QML 没有现成的 API,只能靠手动 Spacer 或自定义 Repeater + Item 来模拟。
  3. Flow 布局的限制

    • Flow 可以自动换行,但 不能结合 minWidth/maxWidth 做更复杂的响应式布局。
    • 例如 CSS flex-wrap + min-width: 200px → 超过就换行,这在 QML Flow 里不行。
  4. 顺序控制 (order)

    • CSS Flex 可以随意调整子项显示顺序。
    • QML 子项绘制顺序只能靠 z(叠放顺序),布局顺序就是声明顺序,不能随便改。
  5. 弹性比例 (flex-grow 比例分配)

    • QML 的 Layout.fillWidth: true 只能 “平分” 剩余空间。
    • Flexbox 的 flex-grow: 2 vs 1 这种比例分配,QML 需要用 Layout.preferredWidth 辅助才能近似。
  6. 换行对齐

    • CSS Flex 的 align-content 可以控制多行之间的间距(stretch/space-between)。
    • QML Flow 只会一行行堆下去,没有对齐方式。

👉 总结:
QML 自带的 RowLayout / ColumnLayout / Flow 已经能覆盖 80% 的常见 Flex 功能
但在 比例分配、换行约束、复杂对齐 上不如 CSS Flexbox 强大。
要做复杂响应式 UI,一般需要 自定义 Layout 或写

目前在 Qt/QML 生态里,没有现成的、完全等同于 CSS Flexbox 的布局库(比如 display: flexalign-items: center 等全面特性)。不过,仍有一些库和框架可以帮助你在 QML 中更高效地实现类似 CSS Flexbox 的布局效果,或者简化 QML 布局系统的使用。

🚀 可供参考的 QML 布局框架/库


1. QtQuick.Controls (Qt 官方控件库)

QtQuick.Controls 是 Qt 官方提供的控件库,虽然它不是一个纯粹的布局库,但它提供了多种 UI 控件和一些布局组件,能在大多数场景下帮助你快速实现类似 CSS 布局的效果。

  • 适用场景:常规 UI 布局、基础控件(按钮、文本框、菜单等)

  • 相关布局

    • RowLayout / ColumnLayout(类似 flex-direction: row/column
    • GridLayout(类似 grid 布局)
    • Flow(类似 flex-wrap

这些控件可以帮助你快速实现一些常见的布局需求,但像 flex-shrinkjustify-content: space-between/aroundorder 等进阶特性,可能需要自定义布局器。


2. Kirigami

KDE 的 Kirigami 框架 提供了许多响应式布局组件,适合跨平台开发(桌面和移动端)。它基于 QtQuick,能够实现动态、流畅的布局效果,并且非常注重响应式设计,类似 CSS 的 Flexbox 布局。

  • 适用场景:桌面与移动端跨平台布局,响应式设计

  • 亮点

    • 支持 PageRowPage,让你能够轻松实现页面切换和布局适配。
    • 自动适配大小、布局间距等。

虽然 Kirigami 主要针对桌面应用,但也能在移动端中提供非常良好的用户体验。它的布局和界面设计风格非常现代,适合构建与 CSS Flexbox 类似的界面。


3. QtQuick.Layouts

QtQuick.Layouts 也可以帮助你实现一些常见的布局效果,类似 CSS 的 flex,比如 RowLayoutColumnLayout,但它相较于 Flexbox 还有一些缺失。GridLayout 能让你使用网格布局,Flow 允许子项超出容器宽度自动换行。

  • 适用场景:传统 UI 布局,有限的响应式布局

  • 优点

    • 使用简单,适合常规的 UI 布局
    • 能根据需要调整 fillWidthfillHeight,支持自动调整宽高

但在更复杂的布局需求下,如复杂的 align-itemsjustify-content 以及子元素按比例分配空间的特性上,QtQuick.Layouts 可能不够灵活。


4. FlexBoxLayout (社区库)

FlexBoxLayout 是一个社区开发的 QML 库,目的是模拟 CSS Flexbox 布局。它提供了类似于 CSS Flexbox 的完整布局管理器,支持 flex-growflex-shrinkjustify-contentalign-items 等特性。

  • 适用场景:需要 全面支持 Flexbox 功能 的布局,尤其是复杂的响应式 UI

  • 优点

    • 完全模拟 Flexbox 布局的行为
    • 提供完整的功能,如 flex-grow, flex-shrink, align-items, justify-content 等
import FlexBoxLayout 1.0

FlexBoxLayout {
    width: parent.width
    spacing: 8

    Rectangle {
        color: "red"
        width: 100
        height: 40
        FlexBoxLayoutItem {
            flex: 1
        }
    }

    Rectangle {
        color: "green"
        width: 100
        height: 40
        FlexBoxLayoutItem {
            flex: 2
        }
    }

    Rectangle {
        color: "blue"
        width: 100
        height: 40
        FlexBoxLayoutItem {
            flex: 1
        }
    }
}

这个库可以让你在 QML 中使用非常接近 CSS 的布局方式,适合一些复杂的布局需求。


5. Material Design QML

Material Design QML 是另一个开源库,旨在帮助开发者实现 Google Material Design 规范。它提供了许多现代化、响应式的布局组件,可以用来实现 灵活的流式布局,但和 CSS Flexbox 的行为有些不同。

  • 适用场景:响应式设计,Material Design 风格的 UI

  • 亮点

    • 提供 MaterialRow, MaterialColumn,并支持自动换行、对齐等。

尽管它不是 Flexbox 的直接对标,但是可以通过提供现代化的布局和 UI 组件,达到类似的效果。


🚫 QML 在布局方面的局限性

尽管 QML 在布局方面非常强大,但它并不完美,有一些 Flexbox 特性难以直接实现,或者需要手动操作来达到目的:

  1. flex-shrink

    • QML 没有内置的 flex-shrink,如果宽度不足时,元素不会自动缩小。
  2. justify-content: space-around / space-evenly

    • 这两种对齐方式需要手动处理,QML 没有现成的 API。
  3. order

    • QML 不支持 CSS 中的 order 属性,控制元素显示顺序只能通过修改 Repeaterz 来完成。
  4. 响应式布局

    • QML 虽然支持响应式设计,但一些复杂的布局需求,如嵌套 Flexbox,可能需要自定义布局器来完全实现。

📚 总结

QML 库/框架推荐

  • QtQuick.Controls:适合常见的 UI 布局,简洁易用
  • Kirigami:适合跨平台响应式布局,现代化界面
  • FlexBoxLayout (社区库):如果你希望在 QML 中完全模拟 CSS Flexbox,这是最佳选择

QML 局限性

  • 自定义布局 可能是需要的:比如需要 flex-shrinkspace-evenly 时,QML 没有现成的解决方案。
  • 使用社区库(如 FlexBoxLayout)可能会有更高的自由度,但需要处理库的稳定性和性能。

如果你希望 快速搭建一个 Flexbox 风格的 QML 项目,我可以帮你整理一个简易的 Flexbox QML 示例代码,或者推荐相关库,帮你更高效地实现布局!

Grid

好的,关于 QML 的 Grid 布局CSS Grid 布局特性 的对比,我将列出 QML 自带的 GridLayout 以及 CSS Grid 能做的等效特性,并指出 QML 做不到的特性


📖 QML GridLayout vs CSS Grid 布局对比

1. 基本布局容器(Grid 布局容器)

CSS Grid 功能 QML GridLayout 对应功能 说明
display: grid GridLayout GridLayout 是 QML 中的网格布局容器,类似于 CSS 的 display: grid
grid-template-columns columnCount / columnSpacing QML 通过 columnCount 定义列数,columnSpacing 控制列间距
grid-template-rows rowCount / rowSpacing QML 通过 rowCount 定义行数,rowSpacing 控制行间距

QML GridLayout 默认不支持 grid-template-areas,即没有像 CSS Grid 那样通过布局区域来管理子项的位置。但可以通过 rowcolumn 属性在 QML 中定位子项。


2. 子项定位与跨行跨列

CSS Grid 功能 QML GridLayout 对应功能 说明
grid-column-start / grid-column-end GridLayout.column (start) QML 使用 GridLayout.columnGridLayout.row 来指定子项的位置。
grid-row-start / grid-row-end GridLayout.row (start) QML 使用 rowcolumn 指定行列索引。
grid-column-span / grid-row-span GridLayout.columnSpan / GridLayout.rowSpan 子项可以跨多列或多行,使用 columnSpanrowSpan

QMLGridLayout 支持 columnSpanrowSpan,可以实现子项跨多行列的效果,类似于 CSS Grid 的 grid-column-spangrid-row-span


3. 对齐与排列

CSS Grid 功能 QML GridLayout 对应功能 说明
`justify-items: start center end` GridLayout.horizontalAlignment QML 支持水平对齐,通过 horizontalAlignment 控制。
`align-items: start center end` GridLayout.verticalAlignment QML 支持垂直对齐,通过 verticalAlignment 控制。

QML 的 GridLayout 支持 子项的水平与垂直对齐,和 CSS Gridjustify-itemsalign-items 类似。


4. 自适应大小(自动填充)

CSS Grid 功能 QML GridLayout 对应功能 说明
auto-fill / auto-fit GridLayout.fillWidth / fillHeight QML 通过 fillWidthfillHeight 来填充剩余空间,类似于 CSS Grid 的 auto-fill

QML 中,GridLayout 没有直接支持 CSS Grid 的 auto-fillauto-fit,但是可以通过设置 fillWidth / fillHeight 来让单个子项扩展到剩余空间,模拟类似行为。


5. 布局顺序与显示顺序

CSS Grid 功能 QML GridLayout 对应功能 说明
grid-template-areas 不支持 QML GridLayout 不支持 grid-template-areas,需要通过明确的行和列来定位子项。

QML GridLayout 通过行和列的设置来定位控件,而不像 CSS Grid 那样通过 grid-template-areas 进行灵活的布局管理。QML 没有 grid-template-areas 的功能来通过名称区域定位控件。


6. 间距与间隙

CSS Grid 功能 QML GridLayout 对应功能 说明
grid-gap (行间距、列间距) rowSpacing / columnSpacing QML 支持行和列的间距设置,通过 rowSpacingcolumnSpacing 来控制。

QML GridLayout 支持通过 rowSpacingcolumnSpacing 来设置 行间距和列间距,类似于 CSS Grid 的 grid-gap


7. 层叠顺序

CSS Grid 功能 QML GridLayout 对应功能 说明
z-index z QML 子项的层叠顺序可以通过 z 属性进行控制,类似 CSS Grid 的 z-index

QML 和 CSS Grid 都支持通过 z 设置子项的 层级,从而控制它们的显示顺序。


🚫 QML GridLayout 做不到的功能

尽管 QML 的 GridLayout 提供了非常类似 CSS Grid 的布局能力,但也有一些 CSS Grid 特性 QML 做不到或者做得不完美:

  1. grid-template-areas

    • QML GridLayout 目前不支持 grid-template-areas,因此无法像 CSS Grid 那样使用 命名区域 来进行布局。
  2. auto-fillauto-fit

    • QML 的 GridLayout 不能像 CSS Grid 那样自动填充或自动适应,必须显式设置每一列和每一行的子项大小。
  3. place-itemsplace-content

    • place-itemsplace-content 是 CSS Grid 用来控制 对齐方式 的快捷方式,在 QML 中需要分别通过 horizontalAlignmentverticalAlignment 来控制。
  4. 响应式网格(minmax() 适配)

    • QML GridLayout 不支持 CSS Grid 的 minmax() 语法,不能在列宽度或行高度上设置 最小和最大值 范围。

📚 总结

QML 能做到的(类似 CSS Grid)

  • 使用 GridLayout,可以方便地做出类似 CSS Grid 的布局效果,包括行列管理、跨行跨列、对齐等。
  • 支持 列数/行数间距 设置,可以实现 响应式布局,但是对 复杂的区域命名、auto-fill 特性支持有限。

QML 做不到的(与 CSS Grid 不等效)

  • grid-template-areas:QML 不支持通过命名区域控制布局。
  • auto-fillauto-fit:这些行为需要通过手动设置布局项大小来模拟。
  • minmax():QML GridLayout 不支持 minmax(),也不能在列宽或行高上使用类似的限制。

🚀 建议

如果你需要 完全对标 CSS Grid 的功能,或者想使用 grid-template-areasauto-fill 等 CSS 特性,可以考虑使用 第三方 QML 库,如 FlexBoxLayout(用于模拟 Flexbox),或自己扩展 GridLayout 来满足更多布局需求。

你提到的代码:

Rectangle { 
    color: "green"; 
    Layout.preferredHeight: 40; 
    Layout.alignment: Qt.AlignVCenter 
}  // 垂直居中

为什么不直接使用 height 设置高度?

在 QML 的布局系统中,使用 Layout.preferredHeight(或 Layout.preferredWidth)和直接使用 height 设置高度是有区别的,具体区别在于:

  1. height 属性

    • 直接使用 height 属性时,QML 会将这个元素的高度固定为指定的数值,无论它所在的布局容器如何分配空间。这意味着,该元素的高度不会根据布局容器的大小自动调整,而是一个硬性设置的值

    • 用途:适用于你希望固定该元素尺寸的场景(即不参与布局引擎的空间分配)。

  2. Layout.preferredHeight 属性

    • Layout.preferredHeight 指定的是该元素的“首选高度”,而不是硬性设定的高度。这意味着,该元素的高度会根据布局引擎的空间分配机制来调整,但如果布局容器没有明确指定尺寸,QML 会优先使用 preferredHeight 作为该元素的高度。

    • 用途:适用于你希望在布局中为元素提供一个 推荐的尺寸,但又允许布局引擎根据需要调整的场景。布局引擎会尽量按照这个推荐尺寸来分配空间,但它也会尊重其他约束条件(例如父容器的大小和其他元素的大小)。


为什么使用 Layout.preferredHeight 来实现垂直居中?

当你在使用布局时(如 RowLayoutColumnLayout 等),布局系统需要知道每个元素的首选尺寸,这样它才能合理地分配空间和进行对齐操作。

  • Layout.preferredHeight 允许布局引擎根据 align-itemsLayout.alignment 来调整元素的位置。例如,Qt.AlignVCenter 会让元素在容器的垂直方向上居中对齐。

  • height 设置为固定高度时,不会有这样的动态对齐行为。QML 只会把元素放置在容器中,并使用该固定高度,无法进一步调整元素在布局容器中的对齐方式。

例子:

RowLayout {
    width: parent.width; height: 100

    Rectangle { color: "red"; Layout.fillHeight: true; width: 50 }  // 这个矩形充满了垂直空间
    Rectangle { 
        color: "green"; 
        Layout.preferredHeight: 40; 
        Layout.alignment: Qt.AlignVCenter  // 垂直居中
        width: 50 
    }
    Rectangle { color: "blue"; Layout.fillHeight: true; width: 50 }
}
  • 这里,绿色矩形 Layout.preferredHeight: 40 表示它的 首选高度 为 40,但由于 Layout.alignment: Qt.AlignVCenter,它会 RowLayout 容器的垂直方向居中
  • height 如果设置为 40,则直接设定该矩形的高度为 40,不会考虑 对齐剩余空间 的分配。

总结:

  • height 用于固定元素的高度,适合在你 不需要布局系统参与 控制时使用。
  • Layout.preferredHeight 用于给布局引擎提供一个 推荐的高度,并且可以配合 Layout.alignment 来调整对齐方式。在布局容器中使用时,preferredHeight 会让 QML 布局引擎根据容器的大小和对齐设置来动态决定元素的位置。
posted @ 2025-08-18 07:53  丘狸尾  阅读(73)  评论(0)    收藏  举报