first commit
This commit is contained in:
189
mainwindow.py
Normal file
189
mainwindow.py
Normal file
@@ -0,0 +1,189 @@
|
||||
# mainwindow.py
|
||||
import sys
|
||||
import logging # 导入 logging 模块
|
||||
|
||||
from PySide6.QtWidgets import (QApplication, QMainWindow, QTreeWidgetItem,
|
||||
QMessageBox, QHeaderView, QMenu, QInputDialog)
|
||||
from PySide6.QtCore import Qt, QPoint
|
||||
|
||||
# 导入自动生成的 UI 文件
|
||||
from ui_form import Ui_MainWindow
|
||||
# 导入我们自己编写的系统信息管理模块
|
||||
from system_info import SystemInfoManager
|
||||
# 导入日志配置
|
||||
from logger_config import setup_logging, logger # 导入日志配置函数和 logger 实例
|
||||
# 导入磁盘操作模块
|
||||
from disk_operations import DiskOperations
|
||||
|
||||
class MainWindow(QMainWindow):
|
||||
def __init__(self, parent=None):
|
||||
super().__init__(parent)
|
||||
self.ui = Ui_MainWindow()
|
||||
self.ui.setupUi(self)
|
||||
|
||||
# 设置日志输出到 QTextEdit
|
||||
setup_logging(self.ui.logOutputTextEdit)
|
||||
logger.info("应用程序启动。")
|
||||
|
||||
# 初始化系统信息管理器和磁盘操作管理器
|
||||
self.system_manager = SystemInfoManager()
|
||||
self.disk_ops = DiskOperations()
|
||||
|
||||
# 连接刷新按钮的信号到槽函数
|
||||
if hasattr(self.ui, 'refreshButton'):
|
||||
self.ui.refreshButton.clicked.connect(self.refresh_block_devices_info)
|
||||
else:
|
||||
logger.warning("Warning: refreshButton not found in UI. Please add it in form.ui and regenerate ui_form.py.")
|
||||
|
||||
# 启用 treeWidget 的自定义上下文菜单
|
||||
self.ui.treeWidget_block_devices.setContextMenuPolicy(Qt.CustomContextMenu)
|
||||
self.ui.treeWidget_block_devices.customContextMenuRequested.connect(self.show_block_device_context_menu)
|
||||
|
||||
# 初始化时刷新一次数据
|
||||
self.refresh_block_devices_info()
|
||||
logger.info("块设备信息已初始化加载。")
|
||||
|
||||
def refresh_block_devices_info(self):
|
||||
"""
|
||||
刷新块设备信息并显示在 QTreeWidget 中。
|
||||
"""
|
||||
self.ui.treeWidget_block_devices.clear() # 清空现有内容
|
||||
|
||||
# 定义所有要显示的列头和对应的 lsblk 字段名
|
||||
columns = [
|
||||
("设备名", 'name'),
|
||||
("类型", 'type'),
|
||||
("大小", 'size'),
|
||||
("挂载点", 'mountpoint'),
|
||||
("文件系统", 'fstype'),
|
||||
("只读", 'ro'),
|
||||
("UUID", 'uuid'),
|
||||
("PARTUUID", 'partuuid'),
|
||||
("厂商", 'vendor'),
|
||||
("型号", 'model'),
|
||||
("序列号", 'serial'),
|
||||
("主次号", 'maj:min'),
|
||||
("父设备名", 'pkname'),
|
||||
]
|
||||
|
||||
headers = [col[0] for col in columns]
|
||||
self.field_keys = [col[1] for col in columns] # 保存字段键,供后续使用
|
||||
|
||||
self.ui.treeWidget_block_devices.setColumnCount(len(headers)) # 确保列数正确
|
||||
self.ui.treeWidget_block_devices.setHeaderLabels(headers)
|
||||
|
||||
# 调整列宽以适应内容
|
||||
for i in range(len(headers)):
|
||||
self.ui.treeWidget_block_devices.header().setSectionResizeMode(i, QHeaderView.ResizeToContents)
|
||||
|
||||
try:
|
||||
devices = self.system_manager.get_block_devices()
|
||||
for dev in devices:
|
||||
self._add_device_to_tree(self.ui.treeWidget_block_devices, dev)
|
||||
|
||||
# 自动调整列宽
|
||||
for i in range(len(headers)):
|
||||
self.ui.treeWidget_block_devices.resizeColumnToContents(i)
|
||||
logger.info("块设备信息刷新成功。")
|
||||
|
||||
except Exception as e:
|
||||
QMessageBox.critical(self, "错误", f"刷新块设备信息失败: {e}")
|
||||
logger.error(f"刷新块设备信息失败: {e}")
|
||||
|
||||
def _add_device_to_tree(self, parent_item, dev_data):
|
||||
"""
|
||||
辅助函数,将单个设备及其子设备添加到 QTreeWidget。
|
||||
parent_item 可以是 QTreeWidget 本身,也可以是另一个 QTreeWidgetItem。
|
||||
"""
|
||||
item = QTreeWidgetItem(parent_item)
|
||||
for i, key in enumerate(self.field_keys):
|
||||
value = dev_data.get(key)
|
||||
if key == 'ro': # 特殊处理布尔值
|
||||
item.setText(i, "是" if value else "否")
|
||||
elif value is None: # None 值显示为空字符串
|
||||
item.setText(i, "")
|
||||
else:
|
||||
item.setText(i, str(value))
|
||||
|
||||
# 将原始设备数据存储在 item 的 data 属性中,方便后续操作时获取
|
||||
item.setData(0, Qt.UserRole, dev_data)
|
||||
|
||||
# 如果有子设备(分区),也显示出来
|
||||
if 'children' in dev_data:
|
||||
for child in dev_data['children']:
|
||||
self._add_device_to_tree(item, child)
|
||||
item.setExpanded(True) # 默认展开父节点,以便看到分区
|
||||
|
||||
def show_block_device_context_menu(self, pos: QPoint):
|
||||
"""
|
||||
显示块设备列表的右键上下文菜单。
|
||||
"""
|
||||
item = self.ui.treeWidget_block_devices.itemAt(pos)
|
||||
if item:
|
||||
dev_data = item.data(0, Qt.UserRole) # 获取存储的原始设备数据
|
||||
if not dev_data:
|
||||
logger.warning(f"无法获取设备 {item.text(0)} 的详细数据。")
|
||||
return
|
||||
|
||||
device_name = dev_data.get('name')
|
||||
device_type = dev_data.get('type')
|
||||
mount_point = dev_data.get('mountpoint')
|
||||
|
||||
menu = QMenu(self)
|
||||
|
||||
# 挂载/卸载操作
|
||||
# 只有 'part' (分区) 和 'disk' (整个磁盘,但通常只挂载分区) 可以被挂载/卸载
|
||||
if device_type in ['part', 'disk']:
|
||||
if not mount_point or mount_point == '' or mount_point == 'N/A': # 未挂载
|
||||
mount_action = menu.addAction(f"挂载 {device_name}...")
|
||||
mount_action.triggered.connect(lambda: self._handle_mount(device_name))
|
||||
elif mount_point != '[SWAP]': # 已挂载且不是SWAP
|
||||
unmount_action = menu.addAction(f"卸载 {device_name}")
|
||||
unmount_action.triggered.connect(lambda: self._handle_unmount(device_name))
|
||||
|
||||
# 分隔符,用于区分操作
|
||||
if menu.actions():
|
||||
menu.addSeparator()
|
||||
|
||||
# 删除分区和格式化操作
|
||||
# 这些操作通常只针对 'part' (分区)
|
||||
if device_type == 'part':
|
||||
delete_action = menu.addAction(f"删除分区 {device_name}")
|
||||
delete_action.triggered.connect(lambda: self._handle_delete_partition(device_name))
|
||||
|
||||
format_action = menu.addAction(f"格式化分区 {device_name}...")
|
||||
format_action.triggered.connect(lambda: self._handle_format_partition(device_name))
|
||||
|
||||
if menu.actions(): # 只有当菜单中有动作时才显示
|
||||
menu.exec(self.ui.treeWidget_block_devices.mapToGlobal(pos))
|
||||
else:
|
||||
logger.info(f"设备 {device_name} 没有可用的操作。")
|
||||
else:
|
||||
logger.info("右键点击了空白区域。")
|
||||
|
||||
def _handle_mount(self, device_name):
|
||||
"""处理挂载操作,并刷新UI。"""
|
||||
if self.disk_ops.mount_partition(device_name):
|
||||
self.refresh_block_devices_info() # 操作成功后刷新UI
|
||||
|
||||
def _handle_unmount(self, device_name):
|
||||
"""处理卸载操作,并刷新UI。"""
|
||||
if self.disk_ops.unmount_partition(device_name):
|
||||
self.refresh_block_devices_info() # 操作成功后刷新UI
|
||||
|
||||
def _handle_delete_partition(self, device_name):
|
||||
"""处理删除分区操作,并刷新UI。"""
|
||||
if self.disk_ops.delete_partition(device_name):
|
||||
self.refresh_block_devices_info() # 操作成功后刷新UI
|
||||
|
||||
def _handle_format_partition(self, device_name):
|
||||
"""处理格式化分区操作,并刷新UI。"""
|
||||
if self.disk_ops.format_partition(device_name):
|
||||
self.refresh_block_devices_info() # 操作成功后刷新UI
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
app = QApplication(sys.argv)
|
||||
widget = MainWindow()
|
||||
widget.show()
|
||||
sys.exit(app.exec())
|
||||
Reference in New Issue
Block a user