// ui/components/StudentTable.qml
pragma ComponentBehavior: Bound
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import QtQuick.Controls.Material
import "../dialogs"
import "../styles"
Item {
id: table
// 数据模型
property var model: []
// 信号定义
signal editRequested(var student)
signal deleteRequested(string studentId)
// 列定义
property var columnTitles: ["学号", "姓名", "性别", "学院", "系", "班级", "宿舍", "籍贯", "联系电话"]
property var columnRoles: ["id", "name", "gender", "college", "department", "className", "dormitory", "hometown", "phone"]
// 表格容器
Rectangle {
id: tableContainer
anchors.fill: parent
radius: 12
color: "transparent"
// 背景层
Rectangle {
anchors.fill: parent
color: "#252541"
opacity: 0.9
radius: parent.radius
border.color: "#4a4a7a"
border.width: 1
}
// 表格视图
ScrollView {
id: scrollView
anchors.fill: parent
anchors.margins: 1
clip: true
ScrollBar.horizontal.policy: ScrollBar.AlwaysOff
ScrollBar.vertical.policy: ScrollBar.AsNeeded
contentWidth: headerRow.width
contentHeight: headerRow.height + contentRepeater.height
// 表头
Row {
id: headerRow
spacing: 0
z: 2
Repeater {
model: table.columnTitles.length
delegate: Rectangle {
required property int index
width: columnWidth(model.index)
height: 48
color: "#3a3a6a"
Label {
anchors.centerIn: parent
text: table.columnTitles[index]
font.bold: true
font.pixelSize: 14
color: "#e0e0ff"
}
// 列分隔线
Rectangle {
anchors.right: parent.right
width: 1
height: parent.height
color: "#4a4a7a"
}
}
}
}
// 表格内容
Column {
id: contentColumn
anchors.top: headerRow.bottom
spacing: 1
Repeater {
id: contentRepeater
model: table.model
// 行容器
delegate: Rectangle {
id: rowContainer
required property int index
required property var modelData
width: headerRow.width
height: 56
color: index % 2 === 0 ? "#2a2a4a" : "#252541"
// 行悬停效果
states: [
State {
when: rowMouseArea.containsMouse
PropertyChanges { target: rowContainer; color: "#3a3a7a" }
}
]
transitions: [
Transition {
ColorAnimation { duration: 200 }
}
]
MouseArea {
id: rowMouseArea
anchors.fill: parent
hoverEnabled: true
}
// 行内容
Row {
spacing: 0
anchors.fill: parent
// 数据单元格
Repeater {
model: table.columnRoles.length - 1 // 排除操作列
delegate: Rectangle {
required property int index
width: columnWidth(model.index)
height: parent.height
color: "transparent"
Label {
anchors {
verticalCenter: parent.verticalCenter
left: parent.left
leftMargin: 16
}
text: {
const role = table.columnRoles[index];
// 使用 rowContainer.modelData 访问当前行数据
return rowContainer.modelData[role] || "";
}
font.pixelSize: 14
color: "#e0e0ff"
elide: Text.ElideRight
width: parent.width - 32
}
// 列分隔线
Rectangle {
anchors.right: parent.right
width: 1
height: parent.height
color: "#4a4a7a"
}
}
}
// 操作列
Rectangle {
width: columnWidth(table.columnRoles.length - 1)
height: parent.height
color: "transparent"
RowLayout {
anchors.centerIn: parent
spacing: 12
// 编辑按钮
Button {
id: editButton
width: 36
height: 36
flat: true
background: Rectangle {
radius: 18
color: parent.hovered ? "#6a5acd" : "transparent"
}
contentItem: Text {
text: "✏️"
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
font.pixelSize: 16
}
onClicked: table.editRequested(rowContainer.modelData)
}
// 删除按钮
Button {
id: deleteButton
width: 36
height: 36
flat: true
background: Rectangle {
radius: 18
color: parent.hovered ? "#e53935" : "transparent"
}
contentItem: Text {
text: "🗑️"
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
font.pixelSize: 16
}
onClicked: table.deleteRequested(rowContainer.modelData.id)
}
}
}
}
}
}
}
}
}
// 计算列宽
function columnWidth(columnIndex) {
const totalWidth = table.width;
const columnCount = table.columnTitles.length;
// 操作列固定宽度
if (columnIndex === columnCount - 1) return 120;
// 其他列平均分配剩余空间
return (totalWidth - 120) / (columnCount - 1);
}
}