Files
Linux_DEL_helper/gui/partition_dialog.py
T
2026-06-26 16:54:55 +08:00

247 lines
8.6 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""
分区选择对话框
"""
from PyQt5.QtWidgets import (
QDialog, QVBoxLayout, QHBoxLayout, QLabel,
QTableWidget, QTableWidgetItem, QPushButton,
QHeaderView, QMessageBox, QProgressBar
)
from PyQt5.QtCore import Qt, QThread, pyqtSignal
from PyQt5.QtGui import QFont, QColor
from disk_manager import DiskManager, Partition
from utils import format_size
class PartitionLoadThread(QThread):
"""分区加载线程"""
finished = pyqtSignal(list)
error = pyqtSignal(str)
def __init__(self, disk_manager: DiskManager):
super().__init__()
self.disk_manager = disk_manager
def run(self):
try:
partitions = self.disk_manager.get_partitions()
self.finished.emit(partitions)
except Exception as e:
self.error.emit(str(e))
class PartitionDialog(QDialog):
"""分区选择对话框"""
def __init__(self, disk_manager: DiskManager, parent=None):
super().__init__(parent)
self.disk_manager = disk_manager
self.selected_partition = None
self.partitions = []
self.init_ui()
self.load_partitions()
def init_ui(self):
"""初始化界面"""
self.setWindowTitle("选择要清理的分区")
self.setMinimumSize(700, 450)
self.setWindowFlags(self.windowFlags() & ~Qt.WindowContextHelpButtonHint)
# 主布局
layout = QVBoxLayout(self)
layout.setSpacing(15)
layout.setContentsMargins(20, 20, 20, 20)
# 标题
title_label = QLabel("请选择要清理的磁盘分区:")
font = QFont()
font.setPointSize(12)
font.setBold(True)
title_label.setFont(font)
layout.addWidget(title_label)
# 分区表格
self.table = QTableWidget()
self.table.setColumnCount(7)
self.table.setHorizontalHeaderLabels([
"设备", "挂载点", "文件系统", "总容量", "已用", "可用", "使用率"
])
# 设置表格属性
header = self.table.horizontalHeader()
header.setSectionResizeMode(0, QHeaderView.Stretch)
header.setSectionResizeMode(1, QHeaderView.Stretch)
header.setSectionResizeMode(2, QHeaderView.ResizeToContents)
header.setSectionResizeMode(3, QHeaderView.ResizeToContents)
header.setSectionResizeMode(4, QHeaderView.ResizeToContents)
header.setSectionResizeMode(5, QHeaderView.ResizeToContents)
header.setSectionResizeMode(6, QHeaderView.ResizeToContents)
self.table.setSelectionBehavior(QTableWidget.SelectRows)
self.table.setSelectionMode(QTableWidget.SingleSelection)
self.table.setEditTriggers(QTableWidget.NoEditTriggers)
self.table.doubleClicked.connect(self.on_table_double_clicked)
layout.addWidget(self.table)
# 加载进度条
self.progress_bar = QProgressBar()
self.progress_bar.setRange(0, 0) # 不确定进度
self.progress_bar.setTextVisible(False)
layout.addWidget(self.progress_bar)
# 状态标签
self.status_label = QLabel("正在检测磁盘分区...")
self.status_label.setAlignment(Qt.AlignCenter)
layout.addWidget(self.status_label)
# 按钮
button_layout = QHBoxLayout()
button_layout.addStretch()
self.refresh_button = QPushButton("🔄 刷新")
self.refresh_button.clicked.connect(self.load_partitions)
button_layout.addWidget(self.refresh_button)
self.cancel_button = QPushButton("取消")
self.cancel_button.clicked.connect(self.reject)
button_layout.addWidget(self.cancel_button)
self.ok_button = QPushButton("确定")
self.ok_button.setDefault(True)
self.ok_button.setEnabled(False)
self.ok_button.clicked.connect(self.on_ok_clicked)
button_layout.addWidget(self.ok_button)
layout.addLayout(button_layout)
def load_partitions(self):
"""加载分区列表"""
self.progress_bar.show()
self.status_label.setText("正在检测磁盘分区...")
self.ok_button.setEnabled(False)
self.refresh_button.setEnabled(False)
# 在后台线程加载分区
self.load_thread = PartitionLoadThread(self.disk_manager)
self.load_thread.finished.connect(self.on_partitions_loaded)
self.load_thread.error.connect(self.on_load_error)
self.load_thread.start()
def on_partitions_loaded(self, partitions):
"""分区加载完成"""
self.partitions = partitions
self.progress_bar.hide()
self.refresh_button.setEnabled(True)
if not partitions:
self.status_label.setText("未检测到可用的分区")
return
self.status_label.setText(f"检测到 {len(partitions)} 个可用分区")
self.update_table()
def on_load_error(self, error_message):
"""加载出错"""
self.progress_bar.hide()
self.refresh_button.setEnabled(True)
self.status_label.setText(f"加载失败:{error_message}")
QMessageBox.critical(
self,
"错误",
f"加载分区列表失败:\n{error_message}"
)
def update_table(self):
"""更新表格内容"""
self.table.setRowCount(len(self.partitions))
for row, partition in enumerate(self.partitions):
# 设备名
device_item = QTableWidgetItem(partition.device)
device_item.setData(Qt.UserRole, row) # 存储索引
self.table.setItem(row, 0, device_item)
# 挂载点
mount_point = partition.mount_point or "未挂载"
mount_item = QTableWidgetItem(mount_point)
self.table.setItem(row, 1, mount_item)
# 文件系统
fs_item = QTableWidgetItem(partition.fstype)
self.table.setItem(row, 2, fs_item)
# 总容量
size_item = QTableWidgetItem(partition.size_formatted)
size_item.setTextAlignment(Qt.AlignRight | Qt.AlignVCenter)
self.table.setItem(row, 3, size_item)
# 已用
used_item = QTableWidgetItem(partition.used_formatted)
used_item.setTextAlignment(Qt.AlignRight | Qt.AlignVCenter)
self.table.setItem(row, 4, used_item)
# 可用
available_item = QTableWidgetItem(partition.available_formatted)
available_item.setTextAlignment(Qt.AlignRight | Qt.AlignVCenter)
self.table.setItem(row, 5, available_item)
# 使用率
percent_item = QTableWidgetItem(partition.use_percent_formatted)
percent_item.setTextAlignment(Qt.AlignRight | Qt.AlignVCenter)
# 根据使用率设置颜色
if partition.use_percent >= 90:
percent_item.setForeground(QColor(255, 0, 0)) # 红色
elif partition.use_percent >= 80:
percent_item.setForeground(QColor(255, 165, 0)) # 橙色
elif partition.use_percent >= 70:
percent_item.setForeground(QColor(255, 255, 0)) # 黄色
self.table.setItem(row, 6, percent_item)
# 默认选中第一行
if self.partitions:
self.table.selectRow(0)
self.on_table_clicked(self.table.model().index(0, 0))
def on_table_clicked(self, index):
"""表格点击事件"""
row = index.row()
if 0 <= row < len(self.partitions):
self.selected_partition = self.partitions[row]
self.ok_button.setEnabled(True)
def on_table_double_clicked(self, index):
"""表格双击事件"""
row = index.row()
if 0 <= row < len(self.partitions):
self.selected_partition = self.partitions[row]
self.accept()
def on_ok_clicked(self):
"""确定按钮点击"""
if self.selected_partition:
# 如果使用率超过 90%,显示警告
if self.selected_partition.use_percent >= 90:
reply = QMessageBox.warning(
self,
"警告",
f"分区 {self.selected_partition.device} 使用率已达 "
f"{self.selected_partition.use_percent:.1f}%\n"
f"可用空间仅剩 {self.selected_partition.available_formatted}\n\n"
f"是否继续清理?",
QMessageBox.Yes | QMessageBox.No,
QMessageBox.Yes
)
if reply != QMessageBox.Yes:
return
self.accept()
def get_selected_partition(self) -> Partition:
"""获取选中的分区"""
return self.selected_partition