首次代码提交
This commit is contained in:
@@ -0,0 +1,246 @@
|
||||
"""
|
||||
分区选择对话框
|
||||
"""
|
||||
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
|
||||
Reference in New Issue
Block a user