根据上面的解释,修改下面的qml,并给出完整的代码//DataLogShow.qml
import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Layouts 1.15
import CsvLogger 1.0
import QtCharts 2.15
Item {
// 基准分辨率(设计稿尺寸)
property real baseWidth: 1024
property real baseHeight: 600
// 动态计算缩放比例
property real scaleX: width / baseWidth
property real scaleY: height / baseHeight
property real unifiedScale: Math.max(Math.min(scaleX, scaleY),1)
property string mountPath: ""
property string curFileName: ""
// 文件列表模型
property ListModel fileListModel: ListModel {}
CsvLogger {
id: csvLogger
}
CustomVirKeyboard {
id: keyboard
x: (parent.width - width) / 2
y: Math.max(0, parent.height - height - 20)
onAccepted: (text) => {
if (target) target.text = text
keyVisible = false
}
}
MouseArea {
anchors.fill: parent
propagateComposedEvents: true
onClicked: function(mouse) {
var keyboardPos = mapToItem(keyboard, mouse.x, mouse.y)
var isOnKeyboard = keyboardPos.x >= 0 &&
keyboardPos.y >= 0 &&
keyboardPos.x <= keyboard.width &&
keyboardPos.y <= keyboard.height
var isOnTarget = false
if (keyboard.target) {
var targetPos = mapToItem(keyboard.target, mouse.x, mouse.y)
isOnTarget = targetPos.x >= 0 && targetPos.y >= 0 &&
targetPos.x <= keyboard.target.width &&
targetPos.y <= keyboard.target.height
}
if (!isOnKeyboard && !isOnTarget) keyboard.keyVisible = false
else keyboard.keyVisible = true
mouse.accepted = false
}
}
Connections {
target: csvLogger
function onDownloadFile(status, err) {
if (status) {
usbCompletePopup.labText = "文件已拷贝到" + err;
usbCompletePopup.open()
}
else {
usbErrorPopup.labelText = err
usbErrorPopup.open()
}
}
function onFilesInfoCompleted(filefullData, fileMaxminData) {
var chartData = {
channelData: filefullData,
channelMaxmin: fileMaxminData
}
chartPopup.chartData = chartData
chartPopup.open()
}
}
function loadCsvFiles() {
var csvFiles = csvLogger.getCsvFiles();
fileListModel.clear();
for (var i = 0; i < csvFiles.length; i++) {
var fileInfo = csvLogger.getCvsFileInfo(csvFiles[i]);
if (!fileInfo.isEmpty && fileInfo.startTime !== "") {
fileListModel.append({
filePath: fileInfo.fullName,
fileName: fileInfo.fileName,
startTime: fileInfo.startTime,
endTime: fileInfo.endTime,
fileSize: fileInfo.fileSize,
lineNumber: fileListModel.count + 1
});
}
}
}
function handleDownloadRequest(fileName) {
csvLogger.copyFile(fileName)
}
function handleRenameFile(filePath, newName) {
csvLogger.renameFile(filePath, newName)
}
function analyzeCsvFile(filePath) {
console.log("[analyzeCsvFile] 开始分析文件:", filePath)
csvLogger.readChannelDataFromFile(filePath)
}
Popup {
id: chartPopup
width: 800
height: 500
anchors.centerIn: parent
closePolicy: Popup.CloseOnEscape
modal: true
property bool isLarge: false
property bool isTable: false
property var chartData: ({})
property var channelDataList: []
property var channelDataMinMax: []
property bool hasValidData: false
property real chartLeftMargin: 60
property real chartRightMargin: 20
property real chartTopMargin: 40
property real chartBottomMargin: 40
property int horizontalGridLines: 6
background: Rectangle {
anchors.fill: parent
color: "#212529"
radius: 5
border.color: "#555555"
border.width: 1
}
onChartDataChanged: {
if (chartData.channelData && chartData.channelMaxmin) {
channelDataList = chartData.channelData
channelDataMinMax = chartData.channelMaxmin
validateData()
Qt.callLater(chartView.updateChart)
}
}
function validateData() {
var valid = (channelDataList.length > 0 &&
channelDataMinMax.length > 0 &&
channelDataList.length === channelDataMinMax.length)
hasValidData = valid
}
function getSeriesColor(index) {
const colors = [
"#FF0000", "#00FF00", "#0000FF", "#FFFF00",
"#FF00FF", "#00FFFF", "#FFA500", "#800080",
"#008000", "#000080", "#808000", "#800000",
"#008080", "#9370DB", "#20B2AA", "#1E90FF"
]
return colors[index % colors.length]
}
Row {
id: changeAera
anchors.top: parent.top
anchors.horizontalCenter: parent.horizontalCenter
spacing: 10
Button {
id: curveButton
text: "曲线视图"
width: 120
height: 40
background: Rectangle {
color: parent.pressed ? "#404040" : (parent.hovered ? "#353535" : "#4169E1")
radius: 4
}
onClicked: {
chartPopup.isTable = false
}
contentItem: Text {
text: parent.text
color: "white"
font.pixelSize: 16
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
}
}
Button {
id: tableButton
text: "数据表格"
width: 120
height: 40
background: Rectangle {
color: parent.pressed ? "#404040" : (parent.hovered ? "#353535" : "#4169E1")
radius: 4
}
onClicked: {
chartPopup.isTable = true
}
contentItem: Text {
text: parent.text
color: "white"
font.pixelSize: 16
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
}
}
Button {
text: "关闭"
width: 100
height: 40
background: Rectangle {
color: parent.pressed ? "#404040" : (parent.hovered ? "#353535" : "#4169E1")
radius: 4
}
onClicked: {
chartPopup.close()
}
contentItem: Text {
text: parent.text
color: "white"
font.pixelSize: 16
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
}
}
}
//显示区域
Rectangle {
id: dataAera
width: parent.width - 20
height: parent.height - changeAera.height - 20
color: "#191919"
anchors {
top: changeAera.bottom
left: parent.left
margins: 10
}
ChartView {
id: chartView
width: parent.width - 120
height: parent.height
anchors.left: parent.left
anchors.top: parent.top
visible: !chartPopup.isTable
antialiasing: true
backgroundColor: "#000000"
legend.visible: false
animationOptions: ChartView.NoAnimation
property real yAxisMin: -5
property real yAxisMax: 105
// 变换控制属性
property real zoomFactor: 1.0
property point panOffset: Qt.point(0, 0)
property real zoomStep: 0.01
property real panStep: 30
property int animationDuration: 300
property real xZoomFactor: 1.0
property real zoomInFactor: 1.05
property real zoomOutFactor: 0.95
// 交互式图例和垂直线
Rectangle {
id: verticalLine
width: 1
height: parent.height - chartPopup.chartTopMargin - chartPopup.chartBottomMargin
color: "white"
visible: false
z: 10
x: chartPopup.chartLeftMargin
y: chartPopup.chartTopMargin
property real currentX: 0
property var closestPoints: ({})
}
Rectangle {
id: legendContainer
width: 200
height: Math.min((chartPopup.channelDataList.length + 1) * 18 , chartView.height - 20)
color: "#333333"
border.color: "#555555"
border.width: 1
radius: 5
visible: false
z: 10
anchors.top: parent.top
anchors.topMargin: 30
Column {
anchors.fill: parent
anchors.margins: 2
spacing: 2
Text {
id: timeLabel
width: parent.width
color: "white"
font { pixelSize: 14; bold: true }
horizontalAlignment: Text.AlignHCenter
elide: Text.ElideRight
}
Rectangle {
width: parent.width
height: 1
color: "#555555"
}
Repeater {
model: Object.keys(verticalLine.closestPoints)
Row {
spacing: 3
Rectangle {
width: 14
height: 14
radius: 7
color: chartPopup.getSeriesColor(parseInt(modelData))
//border.color: "white"
//border.width: 2
}
Row {
spacing: 2
Text {
text: chartPopup.channelDataList[modelData].channelName
color: "white"
font.pixelSize: 12
}
Text {
text: verticalLine.closestPoints[modelData].value.toFixed(2)
color: "#AAAAAA"
font.pixelSize: 12
}
}
}
}
}
}
Repeater {
model: Object.keys(verticalLine.closestPoints)
Rectangle {
id: pointMarker
width: 10
height: 10
radius: 5
color: chartPopup.getSeriesColor(parseInt(modelData))
visible: verticalLine.visible
x: {
var closestPoint = verticalLine.closestPoints[modelData];
if (!closestPoint) return 0;
var seriesIndex = parseInt(modelData);
var series = chartView.seriesAt(seriesIndex);
if (!series || series.count === 0) return 0;
var point = Qt.point(
closestPoint.x,
closestPoint.y
);
var pos = chartView.mapToPosition(point, series);
return pos.x - width / 2;
}
y: {
var closestPoint = verticalLine.closestPoints[modelData];
if (!closestPoint) return 0;
var seriesIndex = parseInt(modelData);
var series = chartView.seriesAt(seriesIndex);
if (!series || series.count === 0) return 0;
var point = Qt.point(
closestPoint.x,
closest.y
);
var pos = chartView.mapToPosition(point, series);
return pos.y - height / 2; // 中心对齐
}
}
}
MouseArea {
anchors.fill: parent
hoverEnabled: true
propagateComposedEvents: true
onPositionChanged: function(mouse) {
if (!chartPopup.hasValidData) return;
verticalLine.currentX = mouse.x;
verticalLine.x = mouse.x;
verticalLine.visible = true;
var timeRange = axisX.max.getTime() - axisX.min.getTime();
var relX = (mouse.x - chartPopup.chartLeftMargin) /
(width - chartPopup.chartLeftMargin - chartPopup.chartRightMargin);
var currentTime = axisX.min.getTime() + relX * timeRange;
timeLabel.text = Qt.formatDateTime(new Date(currentTime), "yyyy-MM-dd hh:mm:ss.zzz");
var closestPoints = {};
for (var i = 0; i < chartPopup.channelDataList.length; i++) {
var channel = chartPopup.channelDataList[i];
var range = chartPopup.channelDataMinMax[i];
if (!channel.points || !range) continue;
var closestPoint = findClosestPoint(channel.points, currentTime);
if (closestPoint) {
closestPoints[i] = {
x: closestPoint.timestamp,
y: ((closestPoint.value - range.minValue) /
(range.maxValue - range.minValue)) * 100,
value: closestPoint.value
};
}
}
verticalLine.closestPoints = closestPoints;
updateLegendPosition(mouse.x);
}
/*
onPositionChanged: function(mouse) {
if (!chartPopup.hasValidData) return;
// 更新垂直线位置
verticalLine.currentX = mouse.x;
verticalLine.x = mouse.x;
verticalLine.visible = true;
// 将鼠标坐标转换为图表值
var mouseValue = chartView.mapToValue(Qt.point(mouse.x, 0));
var currentTime = mouseValue.x;
// 更新图例时间显示
timeLabel.text = Qt.formatDateTime(new Date(currentTime), "yyyy-MM-dd hh:mm:ss.zzz");
// 查找每条曲线上最近的点
var closestPoints = {};
var seriesList = chartView.series();
for (var i = 0; i < seriesList.length; i++) {
var series = seriesList[i];
var closestPoint = findClosestPoint(series, currentTime);
if (closestPoint) {
closestPoints[i] = closestPoint;
}
}
verticalLine.closestPoints = closestPoints;
updateLegendPosition(mouse.x);
}
*/
onExited: {
verticalLine.visible = false;
legendContainer.visible = false;
}
onPressed: function(mouse) {
mouse.accepted = false;
}
onReleased: function(mouse) {
mouse.accepted = false;
}
function findClosestPoint(points, targetTime) {
if (!points || points.length === 0) return null;
var low = 0;
var high = points.length - 1;
var closest = null;
var minDiff = Infinity;
while (low <= high) {
var mid = Math.floor((low + high) / 2);
var point = points[mid];
var diff = Math.abs(point.timestamp - targetTime);
if (diff < minDiff) {
minDiff = diff;
closest = point;
}
if (point.timestamp < targetTime) {
low = mid + 1;
} else {
high = mid - 1;
}
}
return closest;
}
// 更新图例位置
function updateLegendPosition(mouseX) {
legendContainer.visible = true;
if (mouseX < width / 2) {
legendContainer.anchors.left = undefined;
legendContainer.anchors.right = parent.right;
legendContainer.anchors.rightMargin = 10;
} else {
legendContainer.anchors.right = undefined;
legendContainer.anchors.left = parent.left;
legendContainer.anchors.leftMargin = 10;
}
}
}
transform: [
Scale {
id: scaleTransform
origin.x: width/2
origin.y: height/2
xScale: chartView.zoomFactor
yScale: chartView.zoomFactor
},
Translate {
id: translateTransform
x: chartView.panOffset.x
y: chartView.panOffset.y
}
]
Behavior on xZoomFactor {
NumberAnimation {
duration: chartView.animationDuration
easing.type: Easing.InOutQuad
}
}
Behavior on panOffset {
PropertyAnimation {
duration: chartView.animationDuration
easing.type: Easing.InOutQuad
}
}
function resetView() {
zoomFactor = 1.0
panOffset = Qt.point(0, 0)
if (chartPopup.channelDataMinMax.length > 0) {
var range = chartPopup.channelDataMinMax[0]
axisX.min = new Date(range.minTimestamp)
axisX.max = new Date(range.maxTimestamp)
axisY.min = chartView.yAxisMin
axisY.max = chartView.yAxisMax
}
}
function msToDateTime(ms) {
return new Date(ms)
}
function formatFullDateTimeWithMs(timestamp) {
if (!timestamp) return "N/A"
var date = new Date(timestamp)
return Qt.formatDateTime(date, "yyyy-MM-dd hh:mm:ss.zzz")
}
function xZoomIn() {
xZoomFactor = Math.max(0.05, xZoomFactor - zoomStep)
updateXAxisRange()
}
function xZoomOut() {
xZoomFactor = Math.min(10.0, xZoomFactor + zoomStep)
updateXAxisRange()
}
function updateXAxisRange() {
if (!axisX || chartPopup.channelDataMinMax.length === 0) return
var centerTimeMs = (axisX.max.getTime() + axisX.min.getTime()) / 2
var totalRangeMs = chartPopup.channelDataMinMax[0].maxTimestamp -
chartPopup.channelDataMinMax[0].minTimestamp
var visibleRangeMs = totalRangeMs * xZoomFactor
axisX.min = msToDateTime(centerTimeMs - visibleRangeMs/2)
axisX.max = msToDateTime(centerTimeMs + visibleRangeMs/2)
}
function adjustXAxisRange(pixelDelta) {
if (!axisX) return
var timeRangeMs = axisX.max.getTime() - axisX.min.getTime()
var msPerPixel = timeRangeMs / width
var msDelta = pixelDelta * msPerPixel
var newMinMs = axisX.min.getTime() + msDelta
var newMaxMs = axisX.max.getTime() + msDelta
if (chartPopup.channelDataMinMax.length > 0) {
var dataMinMs = chartPopup.channelDataMinMax[0].minTimestamp
var dataMaxMs = chartPopup.channelDataMinMax[0].maxTimestamp
if (newMinMs < dataMinMs) {
newMinMs = dataMinMs
newMaxMs = newMinMs + timeRangeMs
}
if (newMaxMs > dataMaxMs) {
newMaxMs = dataMaxMs
newMinMs = newMaxMs - timeRangeMs
}
}
axisX.min = msToDateTime(newMinMs)
axisX.max = msToDateTime(newMaxMs)
}
function updateChart() {
removeAllSeries()
if (!chartPopup.hasValidData) return
for (var i = 0; i < chartPopup.channelDataList.length; i++) {
var channel = chartPopup.channelDataList[i]
var range = chartPopup.channelDataMinMax[i]
if (!channel.points || !range) continue
var series = createSeries(ChartView.SeriesTypeLine,
channel.channelName || `通道 ${i+1}`,
axisX, axisY)
series.color = chartPopup.getSeriesColor(i)
series.width = 2
axisX.min = new Date(range.minTimestamp)
axisX.max = new Date(range.maxTimestamp)
//var maxPoints = 2000
//var step = Math.max(1, Math.floor(channel.points.length / maxPoints))
//var step =
for (var j = 0; j < channel.points.length; j++) {
var point = channel.points[j]
if (typeof point.value === "number") {
var xValue = point.timestamp
var yValue = ((point.value - range.minValue) /
(range.maxValue - range.minValue)) * 100
series.append(xValue, yValue)
}
}
}
}
// 设置X轴
DateTimeAxis {
id: axisX
format: "hh:mm:ss.zzz"
gridVisible: true
labelsBrush: Qt.rgba(1, 1, 1, 1)
gridLineColor: Qt.rgba(1, 1, 1, 0.1)
tickCount: 5
//onMinChanged: console.log("X轴最小值更新:", chartView.formatFullDateTimeWithMs(axisX.min))
//onMaxChanged: console.log("X轴最大值更新:", chartView.formatFullDateTimeWithMs(axisX.max))
}
// 设置Y轴(百分比)
ValueAxis {
id: axisY
min: chartView.yAxisMin
max: chartView.yAxisMax
titleText: "百分比(%)"
titleBrush: Qt.rgba(1, 1, 1, 1)
labelsBrush: Qt.rgba(1, 1, 1, 1)
gridLineColor: Qt.rgba(1, 1, 1, 0.1)
tickCount: chartPopup.horizontalGridLines
minorTickCount: 0
}
MultiPointTouchArea {
anchors.fill: parent
minimumTouchPoints: 1
maximumTouchPoints: 2
//property real lastX1: 0
//property real lastX2: 0
//property real baseRange: 0
property point touchPoint1
property point touchPoint2
property real initialDistance: 0
property real initialZoom: 1.0
property real initialXZoom: 1.0
property bool isZoomingX: false
onPressed: (touchPoints) => {
if (touchPoints.length === 1) {
touchPoint1 = Qt.point(touchPoints[0].x, touchPoints[0].y)
} else if (touchPoints.length === 2) {
touchPoint1 = Qt.point(touchPoints[0].x, touchPoints[0].y)
touchPoint2 = Qt.point(touchPoints[1].x, touchPoints[1].y)
initialDistance = Math.sqrt(
Math.pow(touchPoint1.x - touchPoint2.x, 2) +
Math.pow(touchPoint1.y - touchPoint2.y, 2)
)
var angle = Math.atan2(
Math.abs(touchPoint1.y - touchPoint2.y),
Math.abs(touchPoint1.x - touchPoint2.x)
) * (180/Math.PI)
isZoomingX = (angle < 30)
if (isZoomingX) {
initialXZoom = xZoomFactor
} else {
initialZoom = zoomFactor
}
}
}
onUpdated: (touchPoints) => {
// 单指拖动 - 平移
if (touchPoints.length === 1) {
var dx = touchPoints[0].x - touchPoint1.x
chartView.adjustXAxisRange(-dx * 0.5)
touchPoint1 = Qt.point(touchPoints[0].x, touchPoints[0].y)
}
// 双指缩放
else if (touchPoints.length === 2) {
var currentDistance = Math.sqrt(
Math.pow(touchPoints[0].x - touchPoints[1].x, 2) +
Math.pow(touchPoints[0].y - touchPoints[1].y, 2)
)
if (isZoomingX) {
xZoomFactor = initialXZoom *
(currentDistance / initialDistance)
} else {
zoomFactor = initialZoom *
(currentDistance / initialDistance)
}
}
}
onReleased: (touchPoints) => {
// 单击处理(可选)
if (touchPoints.length === 1 && !touchPoint1.pressed) {
// 可以添加单击事件处理
}
}
}
}
Column {
id: imagesAera
width: 100
height: 175
anchors.right: parent.right
anchors.rightMargin: 10
anchors.top: parent.top
anchors.topMargin: 10
spacing: 5
Row {
width: parent.width
spacing: 5
Rectangle {
width: 40
height: 40
color: "#333333"
radius: 4
border.color: "#555555"
border.width: 1
Image {
id: zoomInImg
source: "qrc:/images/zoomIn.svg"
width: 36
height: 36
anchors.centerIn: parent
cache: true
MouseArea {
anchors.fill: parent
onClicked: {
chartView.zoom(chartView.zoomInFactor)
}
}
}
}
Rectangle {
width: 40
height: 40
color: "#333333"
radius: 4
border.color: "#555555"
border.width: 1
Image {
id: zoomOutImg
source: "qrc:/images/zoomOut.svg"
width: 36 * scaleX
height: 36 * scaleY
cache: true
anchors.centerIn: parent
MouseArea {
anchors.fill: parent
onClicked: {
chartView.zoom(chartView.zoomOutFactor)
}
}
}
}
}
Row {
spacing: 5
Rectangle {
width: 40
height: 40
color: "#333333"
radius: 4
border.color: "#555555"
border.width: 1
Image {
id: moveLeftImg
source: "qrc:/images/moveRight.svg"
width: 36 * scaleX
height: 36 * scaleY
rotation: 180
cache: true
anchors.centerIn: parent
MouseArea {
anchors.fill: parent
onClicked: chartView.scrollLeft(10)
}
}
}
Rectangle {
width: 40
height: 40
color: "#333333"
radius: 4
border.color: "#555555"
border.width: 1
Image {
id: moveRightImg
source: "qrc:/images/moveRight.svg"
width: 36 * scaleX
height: 36 * scaleY
cache: true
anchors.centerIn: parent
MouseArea {
anchors.fill: parent
onClicked: chartView.scrollRight(10)
}
}
}
}
Row {
width: parent.width
spacing: 5
Rectangle {
width: 40
height: 40
color: "#333333"
radius: 4
border.color: "#555555"
border.width: 1
Image {
id: xZoomInImg
source: "qrc:/images/xZoomIn.svg"
width: 36 * scaleX
height: 36 * scaleY
cache: true
anchors.centerIn: parent
MouseArea {
anchors.fill: parent
onClicked: chartView.xZoomIn()
}
}
}
Rectangle {
width: 40
height: 40
color: "#333333"
radius: 4
border.color: "#555555"
border.width: 1
Image {
id: xZoomOutImg
source: "qrc:/images/xZoomOut.svg"
width: 36 * scaleX
height: 36 * scaleY
cache: true
anchors.centerIn: parent
MouseArea {
anchors.fill: parent
onClicked: chartView.xZoomOut()
}
}
}
}
Button {
id: resetButton
text: "X-Y复位"
width: 85
height: 40
background: Rectangle {
color: "#1296db"
radius: 4
}
onClicked: {
chartView.resetView()
//chartView.zoomReset()
}
contentItem: Text {
text: parent.text
color: "white"
font.pixelSize: 16
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
anchors.fill: parent
}
}
}
}
Component {
id: chartPage
Rectangle {
color: "#2E2E2E"
anchors.fill: parent
Text {
text: "📊 图表/表格页面"
color: "white"
font.pixelSize: 18
anchors.centerIn: parent
}
}
}
}
Component.onCompleted: {
loadCsvFiles();
}
// 背景层
Rectangle {
id: background
anchors.fill: parent
color: "#000000"
}
// 顶部菜单栏
Rectangle {
id: menuBar
height: 50 * scaleY
anchors {
top: parent.top
left: parent.left
right: parent.right
}
color: "#212529"
Image {
id: homeButton
source: "qrc:/images/backHomePage.svg"
width: 36 * scaleX
height: 36 * scaleY
anchors {
top: parent.top
topMargin: 7 * scaleY
left: parent.left
leftMargin: 20 * scaleX
}
cache: true
MouseArea {
anchors.fill: parent
onClicked: {
mainLoader.source = "qml/StoragePage.qml"
}
}
}
Text {
width: 60 * scaleX
height: 40 * scaleY
color: "#ffffffff"
text: "监测记录"
font {
family: "TOPRIE-WR-YaHei"
pixelSize: 28 * unifiedScale
}
anchors {
verticalCenter: parent.verticalCenter
horizontalCenter: parent.horizontalCenter
}
}
Image {
id: imageLayout
source: "qrc:/images/layout.svg"
width: 30 * scaleX
height: 30 * scaleY
anchors {
top: parent.top
topMargin: 10 * scaleY
right: parent.right
rightMargin: 20 * scaleX
}
cache: true
MouseArea {
anchors.fill: parent
onClicked: {
mainLoader.source = "qml/DataLogShowList.qml"
}
}
}
}
// 主内容区
Rectangle {
id: contentArea
width: 984 * scaleX
height: 521 * scaleY
color: "transparent"
anchors {
top: menuBar.bottom
bottom: parent.bottom
left: parent.left
right: parent.right
rightMargin: 20 * scaleX
topMargin: 14 * scaleY
leftMargin: 20 * scaleX
bottomMargin: 15 * scaleY
}
// 数据表格
Flickable {
id: flickable
anchors.fill: parent
contentWidth: parent.width
contentHeight: dataTable.height
clip: true
boundsBehavior: Flickable.StopAtBounds
flickableDirection: Flickable.VerticalFlick
Column {
id: dataTable
width: parent.width
anchors {
top: parent.top
topMargin: 10 * scaleY
}
spacing: 20 * scaleY
Repeater {
model: fileListModel
delegate: MonitorRecordItem {
id: recordDelegate
width: parent.width
startTime: model.startTime
endTime: model.endTime
lineNumber: model.lineNumber
customName: model.fileName
fileSize: model.fileSize
filePath: model.filePath
vkeyboard: keyboard
onDownloadRequested: handleDownloadRequest
onAnalyzeRequested: analyzeCsvFile
onRenameRequested: handleRenameFile
}
}
}
}
}
Popup { //导出完成提示
id: usbCompletePopup
width: parent.width * 0.6
height: 120
anchors.centerIn: parent
closePolicy: Popup.NoAutoClose
background: Rectangle {
color: "#212529"
radius: 5
border.color: "#555555"
border.width: 1
}
property string labText: ""
Column {
width: parent.width * 0.8
anchors.horizontalCenter: parent.horizontalCenter
spacing: 20
Label {
width: parent.width
text: usbCompletePopup.labText
font.pixelSize: 20
color: "white"
wrapMode: Text.WordWrap
horizontalAlignment: Text.AlignHCenter
}
Label {
width: parent.width
text: "下载成功!"
font.pixelSize: 22
color: "green"
horizontalAlignment: Text.AlignHCenter
}
}
Timer {
id: closeTimer
interval: 1500
running: usbCompletePopup.visible
onTriggered: {
usbCompletePopup.close()
}
}
onOpened: closeTimer.restart()
}
Popup { //导出失败提示
id: usbErrorPopup
width: parent.width * 0.6
height: 100
anchors.centerIn: parent
closePolicy: Popup.NoAutoClose
background: Rectangle {
color: "#212529"
radius: 5
border.color: "#555555"
border.width: 1
}
property string labelText: ""
Label {
anchors.centerIn: parent
text: usbErrorPopup.labelText
font.pixelSize: 22
color: "red"
}
Timer {
id: errorTimer
interval: 2000
running: usbErrorPopup.visible
onTriggered: {
usbErrorPopup.close()
}
}
onOpened: errorTimer.restart()
}
}