在工业数据采集和存储中,HIS
和 DAT
文件是非常常见的二进制数据格式。然而,解析这些固定块大小的二进制文件并将其转换为易读的 CSV
格式并非易事。本文将深入讲解如何使用 Python 和 PyQt5 打造一款图形化工具,轻松解析和转换这些文件,为你扫清数据处理的障碍。
功能概述
这款工具支持:
- HIS 和 DAT 单个文件转换:将二进制数据解析成 CSV 格式。
- 批量文件夹转换:支持一次性解析文件夹下所有目标文件。
- 结果过滤与去重:自动去除全0行和重复数据。
- 图形用户界面 (GUI):通过 PyQt5 打造直观的操作界面。
- 日志与进度条:动态显示转换过程的日志信息和进度。
实现步骤
1. 文件解析核心逻辑
我们首先实现了解析固定块大小二进制文件的功能。
def parse_fixed_block_size(file_path, block_size=64, header_size=32):results = []with open(file_path, 'rb') as file:file.seek(header_size) # 跳过文件头部32字节while True:position = file.tell()chunk = file.read(block_size)if not chunk or len(chunk) < block_size:breaktry:field_count = block_size // 4record = struct.unpack(f'{field_count}I', chunk)results.append((position, block_size, record))except struct.error:continuereturn results
解释:
block_size
定义每个块的大小(64字节)。- 使用
struct.unpack
将二进制数据转换成整型列表。 - 文件头的偏移量可以通过
seek
跳过。
2. 数据处理与CSV导出
解析结果需要去除多余数据后再导出为CSV:
def process_and_save_to_csv(results, output_path):rows = []for position, size, record in results:row = {"Position": position, "Block Size": size}for i, val in enumerate(record):row[f"Field{i+1}"] = valrows.append(row)df = pd.DataFrame(rows)if not df.empty:valid_df = df.loc[~(df.iloc[:, 2:] == 0).all(axis=1)].drop_duplicates()else:valid_df = dfvalid_df.to_csv(output_path, index=False, encoding='utf-8-sig')
亮点:
- 使用
pandas
进行数据处理,去除全零行 (all(axis=1) == 0
)。 - 使用
drop_duplicates
删除重复数据,保证CSV干净整洁。
3. PyQt5用户界面设计
用户界面使用了 PyQt5,结合QFileDialog和QProgressBar等控件,打造了简洁友好的交互体验:
class ConverterUI(QtWidgets.QWidget):def __init__(self):super().__init__()self.init_ui()def init_ui(self):self.setWindowTitle('HIS 和 DAT 文件转换工具(固定块解析)')self.setGeometry(100, 100, 700, 600)main_layout = QVBoxLayout()self.title_label = QLabel('HIS & DAT -> CSV 转换工具', self)self.title_label.setAlignment(QtCore.Qt.AlignCenter)main_layout.addWidget(self.title_label)# 文件选择按钮self.select_his_btn = QtWidgets.QPushButton('选择HIS文件')self.select_his_btn.clicked.connect(self.select_his_file)main_layout.addWidget(self.select_his_btn)# 日志和进度条self.progress_bar = QProgressBar(self)self.log_text = QTextEdit(self)self.log_text.setReadOnly(True)main_layout.addWidget(self.progress_bar)main_layout.addWidget(self.log_text)self.setLayout(main_layout)
4. 线程处理与进度更新
为了不阻塞界面,我们使用了 QThread 来处理后台转换任务:
class ConverterThread(QtCore.QThread):progress = QtCore.pyqtSignal(int)log_message = QtCore.pyqtSignal(str)def run(self):# 模拟处理逻辑for i in range(100):self.log_message.emit(f"正在处理第 {i+1} 块数据...")self.progress.emit(i+1)QtCore.QThread.msleep(50)
通过信号与槽机制 (emit
),将进度条与日志动态更新到UI中。
5. 界面美化
为了提升用户体验,我们引入了随机渐变背景和按钮样式:
class UIStyler:def apply_styles(self):colors = ["#3498db", "#2ecc71", "#e74c3c", "#9b59b6", "#e67e22"]random_color = random.choice(colors)self.widget.setStyleSheet(f"""QWidget {{background-color: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:1, stop:0 {random_color}, stop:1 #ffffff);}}QPushButton {{background-color: {random_color};color: white;}}""")
成果展示
最终运行效果图:
- 主界面:功能清晰,操作简单。
- 日志显示:实时反馈处理状态。
- 进度条:让用户直观了解转换进度。
结语
这款工具结合了 Python 的强大数据处理能力和 PyQt5 的用户界面开发优势,实现了从二进制文件解析到可视化转换的完整流程。不仅可以大幅提高数据转换效率,还能让不熟悉编程的用户轻松上手。