diff --git a/README.en.md b/README.en.md index ec34e626e510823bfbccec4b49f4b0f2041b8713..0cc08f759504ca8d0e287274ced29cbdc5c591af 100644 --- a/README.en.md +++ b/README.en.md @@ -1,38 +1,70 @@ -# 硬件查看器 - -#### Description -本工具专为Linux系统设计,提供硬件及驱动信息的可视化查看功能。 -支持系统概览、CPU、内存、磁盘、网卡、PCI设备、USB设备 -和显卡等硬件信息的展示,并提供明暗主题切换功能。 - -#### Software Architecture -Software architecture description - -#### Installation - -1. xxxx -2. xxxx -3. xxxx - -#### Instructions - -1. xxxx -2. xxxx -3. xxxx - -#### Contribution - -1. Fork the repository -2. Create Feat_xxx branch -3. Commit your code -4. Create Pull Request - - -#### Gitee Feature - -1. You can use Readme\_XXX.md to support different languages, such as Readme\_en.md, Readme\_zh.md -2. Gitee blog [blog.gitee.com](https://blog.gitee.com) -3. Explore open source project [https://gitee.com/explore](https://gitee.com/explore) -4. The most valuable open source project [GVP](https://gitee.com/gvp) -5. The manual of Gitee [https://gitee.com/help](https://gitee.com/help) -6. The most popular members [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/) +### GXDE Hardware Viewer +![输入图片说明](hardware-manager-icon.png) + + **Overview 🔍** + +GXDE Hardware Manager is a lightweight hardware information viewer specifically designed for the GXDE desktop environment. It provides comprehensive system information monitoring with a clean and intuitive interface. ✨ + + **Features 🚀** + +- 1. System Information 🖥️: Operating system details, kernel version, architecture, boot time + +- 2. CPU Monitoring 🔢: Real-time CPU usage, frequency, core information, and driver details + +- 3. Memory Tracking 🧠: RAM and swap usage with detailed statistics + +- 4. Storage Analysis 💾: Disk partitions, storage devices, and I/O statistics + +- 5. Network Overview 🌐: Interface information, device drivers, and traffic monitoring + +- 6. Display Information 🖼️: Graphics card details, resolution, color depth, and refresh rate + +- 7. Audio Devices 🔊: Input/output audio devices and driver information + +- 8. Input Devices ⌨️🖱️: Keyboard, mouse, and other input device detection + +- 9. Multi-language Support 🌍: English and Chinese interface + +- 10. Data Export 📤: Export all hardware information to JSON format on desktop + + **Usage Instructions 📖** + +The application features a sidebar navigation with the following sections: + +- 1. System 🖥️: Basic system and hardware overview + +- 2. CPU 🔢: Processor details and real-time usage monitoring + +- 3. Memory 🧠: RAM and swap memory statistics + +- 4. Storage 💾: Disk partitions and storage device information + +- 5. Network 🌐: Network interfaces and traffic data + +- 6. Display 🖼️: Graphics card and display settings + +- 7. Sound 🔊: Audio input/output devices + +- 8. Input Devices ⌨️🖱️: Keyboard, mouse, and other input devices + +- 9. Data Export 📤: Click the menu button (☰) in the top-right corner and select "Export all information to desktop" to save a comprehensive JSON file with all hardware information. 📄 + + **Contribution Guidelines 🤝** + +Contributions are welcome! Please feel free to submit pull requests or open issues for bugs and feature requests. 💡 + + **License 📄** + +This project is licensed under the AGPL-3.0 License - see the LICENSE file for details. ⚖️ + + **Acknowledgments 🙏** + +Thanks to all the open source software we've used 🎉 + +Thanks to all users and contributors ❤️ + +Special Thanks ❤️: @zeqi, @gfdgd xi, and @shenmo - without them, this software wouldn't exist! + + **Official Website 🌐** : [www.gxde.top](http://www.gxde.top) + + diff --git a/README.md b/README.md index 19c1a61cfb8ea19c2b7ebcb8738a3bd22e94e332..845607411a3270ecd411ffadcd5e8e7456ed4203 100644 --- a/README.md +++ b/README.md @@ -1,38 +1,70 @@ -# 硬件查看器 +### GXDE硬件查看器 +![输入图片说明](hardware-manager-icon.png) -#### 介绍 -本工具专为Linux系统设计,提供硬件及驱动信息的可视化查看功能。 -支持系统概览、CPU、内存、磁盘、网卡、PCI设备、USB设备和显卡等硬件信息的展示,并提供明暗主题切换功能。 + **概述 🔍** -#### 使用说明 +GXDE 硬件管理器是一款专为 GXDE 桌面环境设计的轻量级硬件信息查看器。它提供全面的系统信息监控,界面简洁直观。✨ -1. 目前只支持 Debian 系列发行版 -2. 不是很完善,需要有一定🤏Linux基础的用户使用 + **功能特性 🚀** -#### 参与贡献 +- 1. 系统信息 🖥️: 操作系统详情、内核版本、架构、启动时间 -1. Fork 本仓库 -2. 提交代码 -3. 新建 Pull Request +- 2. CPU 监控 🔢: 实时 CPU 使用率、频率、核心信息和驱动详情 -#### 更新日志 +- 3. 内存跟踪 🧠: RAM 和交换分区使用情况,包含详细统计 -**1.1版本更新(2025年11月1日):** -1. 标注开源协议 -2. 标注仓库地址 +- 4. 存储分析 💾: 磁盘分区、存储设备和 I/O 统计 -**1.2版本更新(2025年11月1日):** -1. 🔧修复点击刷新只更新最后更新时间的问题 -2. 🔧修复cpu信息中文化失效 -3. 🆕新增防多次刷新功能,每次刷新后有等待时间,避免多次刷新 -4. 优化:使用多线程,使软件更流畅 -(今天连推两个更新累死我了,从早上10点弄到下午6点) +- 5. 网络概览 🌐: 接口信息、设备驱动和流量监控 -**1.2.1版本更新(2025年11月1日):** -1. 更改去除跟随系统设置主题功能(emmm不同发行版同样的桌面环境主题文件储存位置还不一样,我没招了,只能去掉这个功能了) +- 6. 显示信息 🖼️: 显卡详情、分辨率、色深和刷新率 -**2.0版本更新(2025年11月2日):** -1. 🆕代码重构,放弃使用tk库转而使用pyqt6,使软件适配高dpi,兼容低分辨率 -2. 🆕全新界面,比1.0系列更加像deepin15时期的系统应用 -3. 调整:1.0系列更新策略调整,🤔可能不会继续更新 -4. 调整:内容丰富度可能相比与1.0系列会下降📉,后续会继续优化打磨2.0系列版本 +- 7. 音频设备 🔊: 输入/输出音频设备和驱动信息 + +- 8. 输入设备 ⌨️🖱️: 键盘、鼠标和其他输入设备检测 + +- 9. 多语言支持 🌍: 英文和中文界面 + +- 10. 数据导出 📤: 将所有硬件信息导出为 JSON 格式到桌面 + + **使用说明 📖** + +应用程序具有侧边栏导航,包含以下部分: + +- 1. 系统 🖥️: 基本系统和硬件概览 + +- 2. CPU 🔢: 处理器详情和实时使用率监控 + +- 3. 内存 🧠: RAM 和交换分区统计 + +- 4. 存储 💾: 磁盘分区和存储设备信息 + +- 5. 网络 🌐: 网络接口和流量数据 + +- 6. 显示 🖼️: 显卡和显示设置 + +- 7. 声音 🔊: 音频输入/输出设备 + +- 8. 输入设备 ⌨️🖱️: 键盘、鼠标和其他输入设备。 + +- 9. 数据导出 📤:点击右上角的菜单按钮 (☰),选择"导出所有信息到桌面",即可将所有硬件信息保存为全面的 JSON 文件。📄 + + **贡献指南 🤝** + +欢迎贡献!请随时提交 pull request 或为 bug 和功能请求开启 issue。💡 + + **许可证 📄** + +本项目采用 AGPL-3.0 许可证 - 详见 LICENSE 文件。⚖️ + + **致谢 🙏** + +感谢我们使用的所有开源软件 🎉 + +感谢所有用户和贡献者 ❤️ + +特别感谢 ❤️: +@zeqi、@gfdgd xi 和 @shenmo,没有他们就没有这个软件! + + **系统官网 🌐:** +[www.gxde.top](http://www.gxde.top) \ No newline at end of file diff --git a/debian/changelog b/debian/changelog index 3183827b79d8fabe38bacb8c5e90af3de0b3f481..5a36dc2d9e578abdc253c2faf0451900a1eadaf9 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,4 +1,4 @@ -gxde-hardware-viewer (2.3.0) UNRELEASED; urgency=medium +gxde-hardware-viewer (2.4.0) UNRELEASED; urgency=medium [ gfdgd_xi ] * 新增英语支持 diff --git a/gxde-hardware-viewer.py b/gxde-hardware-viewer.py index 334d9f4d6a37e8ba273791639186e737a862567c..34dd34465e178d652e55f42b25e19733814da2c2 100644 --- a/gxde-hardware-viewer.py +++ b/gxde-hardware-viewer.py @@ -15,8 +15,10 @@ from PyQt6.QtWidgets import (QApplication, QMainWindow, QWidget, QVBoxLayout, QLabel, QGroupBox, QFormLayout, QGridLayout, QScrollArea, QTableWidget, QTableWidgetItem, QProgressBar, QFrame, QPushButton, QMenu, QMessageBox, QAbstractItemView, QDialog, QDialogButtonBox) -from PyQt6.QtCore import Qt, QTimer, QTranslator, QCoreApplication, QLocale -from PyQt6.QtGui import QIcon, QFont, QPixmap +from PyQt6.QtCore import Qt, QTimer, QTranslator, QCoreApplication, QLocale, QSize +from PyQt6.QtGui import QIcon, QFont, QPixmap, QMovie + +version = "2.4.0" class CacheManager: """缓存管理器""" @@ -52,9 +54,9 @@ class CacheManager: class HardwareManager(QMainWindow): def __init__(self): super().__init__() - # 初始化缓存管理器 + + # 初始化变量 self.cache = CacheManager() - # 保存需要实时更新的控件引用 self.translator = QTranslator(self) self.current_lang = "en" self.cpu_total_bar = None @@ -63,12 +65,19 @@ class HardwareManager(QMainWindow): self.swap_bar = None self.net_io_labels = {} self.disk_io_labels = {} - - # 初始化UI缩放因子 + + # 初始化缩放因子 self.init_scaling_factor() + + # 创建用户界面 self.initUI() - self.init_timer() - + + # 启动硬件监控 + self.monitor_timer = QTimer(self) + self.monitor_timer.setInterval(2000) + self.monitor_timer.timeout.connect(self.update_hardware_info) + self.monitor_timer.start() + def init_scaling_factor(self): """初始化缩放因子,用于适配不同分辨率""" try: @@ -78,7 +87,6 @@ class HardwareManager(QMainWindow): # 以96 DPI为基准计算缩放因子 self.scaling_factor = dpi / 96.0 except: - # 默认为1.0 self.scaling_factor = 1.0 def scaled(self, value): @@ -128,6 +136,24 @@ class HardwareManager(QMainWindow): # 创建主内容区域 self.stack = QStackedWidget() + # 添加加载中的提示页面 + self.loading_page = self.create_loading_page() + self.stack.addWidget(self.loading_page) + + # 连接侧边栏选择事件 + self.sidebar.currentRowChanged.connect(self.stack.setCurrentIndex) + + # 添加到主布局 + main_layout.addWidget(self.sidebar) + main_layout.addWidget(self.stack, 1) + + # 设置中心部件 + self.setCentralWidget(main_widget) + + # 默认显示加载页面,隐藏侧边栏 + self.sidebar.hide() + self.stack.setCurrentIndex(0) + # 添加各个页面 self.stack.addWidget(self.create_system_info_page()) self.stack.addWidget(self.create_cpu_page()) @@ -151,16 +177,120 @@ class HardwareManager(QMainWindow): # 默认选中第一个项目 self.sidebar.setCurrentRow(0) - - # 添加右上角菜单按钮 self.create_menu_button() - - # 应用字体缩放 self.apply_font_scaling() + + self.setup_text_selection() + + QTimer.singleShot(100, self.load_real_pages) + + def create_loading_page(self): + """创建加载页面""" + widget = QWidget() + + layout = QVBoxLayout(widget) + layout.setContentsMargins(self.scaled(15), self.scaled(15), self.scaled(15), self.scaled(15)) + layout.setSpacing(self.scaled(10)) + + layout.addStretch() + + # 创建GIF动画标签 + self.loading_gif_label = QLabel() + + gif_path = "/home/ocean/Downloads/loading.gif" + + self.loading_movie = QMovie(gif_path) + self.loading_gif_label.setMovie(self.loading_movie) + self.loading_movie.start() + + gif_size = self.scaled(150) + self.loading_gif_label.setFixedSize(gif_size, gif_size) + self.loading_movie.setScaledSize(QSize(gif_size, gif_size)) + + gif_layout = QHBoxLayout() + gif_layout.addStretch() + gif_layout.addWidget(self.loading_gif_label) + gif_layout.addStretch() + layout.addLayout(gif_layout) + + layout.addStretch() + return widget + + def load_real_pages(self): + """加载实际页面""" + QTimer.singleShot(1500, self.finish_loading) + + def finish_loading(self): + """完成加载并显示主界面""" + + if hasattr(self, 'loading_movie'): + self.loading_movie.stop() + + # 移除加载页面,显示实际内容 + self.stack.removeWidget(self.loading_page) + self.loading_page.deleteLater() + + # 显示侧边栏并选中第一个项目 + self.sidebar.show() + self.sidebar.setCurrentRow(0) + + def setup_text_selection(self): + """设置文本选中复制功能""" + for widget in self.findChildren(QLabel): + if not isinstance(widget, (QProgressBar, QPushButton)): + widget.setTextInteractionFlags(Qt.TextInteractionFlag.TextSelectableByMouse) + widget.setCursor(Qt.CursorShape.IBeamCursor) + + for table in self.findChildren(QTableWidget): + table.setSelectionBehavior(QAbstractItemView.SelectionBehavior.SelectItems) + table.setSelectionMode(QAbstractItemView.SelectionMode.ExtendedSelection) + table.setContextMenuPolicy(Qt.ContextMenuPolicy.CustomContextMenu) + table.customContextMenuRequested.connect(self.show_table_context_menu) # 改为连接到一个显示菜单的函数 + + def show_table_context_menu(self, pos): + """显示表格右键菜单""" + table = self.sender() + if not table: + return + + # 创建右键菜单 + menu = QMenu(self) + + # 添加复制选项 + copy_action = menu.addAction(self.tr("Copy")) + copy_action.triggered.connect(lambda: self.copy_table_content(table)) + # 只有在有选中内容时才显示菜单 + if table.selectedItems(): + menu.exec(table.viewport().mapToGlobal(pos)) + + def copy_table_content(self, table): + """复制表格选中内容""" + selected_items = table.selectedItems() + if not selected_items: + return + + # 获取选中的行和列范围 + rows = sorted(set(item.row() for item in selected_items)) + cols = sorted(set(item.column() for item in selected_items)) + + # 构建复制的文本 + text = "" + for row in rows: + row_data = [] + for col in cols: + item = table.item(row, col) + if item: + row_data.append(item.text()) + text += "\t".join(row_data) + "\n" + + # 复制到剪贴板 + clipboard = QApplication.clipboard() + clipboard.setText(text.strip()) + def switch_language(self, lang): """切换应用语言""" if self.current_lang == lang: @@ -272,6 +402,29 @@ class HardwareManager(QMainWindow): # 保存按钮引用,以便在窗口大小改变时调整位置 self.menu_button = menu_button + + QTimer.singleShot(100, self.update_menu_button_position) + + def update_menu_button_position(self): + """更新菜单按钮位置""" + if hasattr(self, 'menu_button') and self.menu_button: + # 计算正确的位置 + x_pos = self.width() - self.menu_button.width() - 10 + y_pos = 10 # 距离顶部10像素 + self.menu_button.move(x_pos, y_pos) + self.menu_button.raise_() # 确保按钮在最上层 + self.menu_button.show() # 确保按钮显示 + + def resizeEvent(self, event): + """重写窗口大小改变事件,确保菜单按钮始终在右上角""" + super().resizeEvent(event) + self.update_menu_button_position() + + def showEvent(self, event): + """重写窗口显示事件,确保菜单按钮正确显示""" + super().showEvent(event) + # 窗口显示后更新菜单按钮位置 + QTimer.singleShot(100, self.update_menu_button_position) def resizeEvent(self, event): """重写窗口大小改变事件,确保菜单按钮始终在右上角""" @@ -416,10 +569,10 @@ class HardwareManager(QMainWindow): def init_timer(self): """初始化定时器用于实时更新信息""" - self.timer = QTimer(self) - self.timer.setInterval(2000) # 2秒更新一次 - self.timer.timeout.connect(self.update_hardware_info) - self.timer.start() + self.monitor_timer = QTimer(self) + self.monitor_timer.setInterval(2000) # 2秒更新一次 + self.monitor_timer.timeout.connect(self.update_hardware_info) + self.monitor_timer.start() def update_hardware_info(self): """更新硬件信息""" @@ -1788,7 +1941,7 @@ class HardwareManager(QMainWindow): return devices class AboutDialog(QDialog): - version = "2.3.0" + """关于对话框""" def __init__(self, parent=None): @@ -1817,7 +1970,7 @@ class AboutDialog(QDialog): layout.addWidget(name_label) # 版本号 - version_label = QLabel(self.tr("Version: ") + self.version) + version_label = QLabel(self.tr("Version: ") + version) version_label.setAlignment(Qt.AlignmentFlag.AlignCenter) layout.addWidget(version_label) diff --git a/hardware-manager-icon.png b/hardware-manager-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..d2177d4d00947e0a69f1dc9671afb8d5e483a98e Binary files /dev/null and b/hardware-manager-icon.png differ diff --git a/loading.gif b/loading.gif new file mode 100644 index 0000000000000000000000000000000000000000..5105f3c8c8e04c06a985f2c8cef691e1c90a6f13 Binary files /dev/null and b/loading.gif differ