""" 分区选择对话框 """ 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