import traceback import json import os import sys from PyQt6.QtWidgets import ( QMainWindow, QWidget, QVBoxLayout, QTabWidget, QTextEdit, QLabel, QPushButton, QHBoxLayout, ) from PyQt6.QtCore import pyqtSignal, QThreadPool from PyQt6.QtGui import QTextCursor from .tabs.export_layout_tab import ExportImageTab from .tabs.raster_tab import RasterTab from .tabs.export_map_tab import ExportMapTab from .tabs.area_stat_tab import XlsxToJpgTab from .tabs.acid_stat_tab import AcidStatsTab # 酸化专题图表格统计 from .tabs.soil_prop_stat_tab import SoilPropStatsTab class MainWindow(QMainWindow): log_signal = pyqtSignal(str) # 定义日志信号 """主窗口""" def __init__(self): super().__init__() self.setWindowTitle("ArcGIS工具集") self.resize(600, 800) self.settings_file = os.path.join( os.path.dirname(__file__), "config", "settings.json" ) print(self.settings_file) self.ensure_settings_file() self.settings = self.load_settings() self.init_ui() # 在创建UI后加载设置 self.load_ui_settings() def init_ui(self): central_widget = QWidget() self.setCentralWidget(central_widget) main_layout = QVBoxLayout(central_widget) # 添加选项卡 tabs = QTabWidget() self.export_map_tab = ExportMapTab(self) self.export_map_tab.log_signal.connect(self.log_signal) # 连接日志信号 self.export_image_tab = ExportImageTab(self) self.raster_tab = RasterTab(self) self.area_stat_tab = XlsxToJpgTab(self) self.acid_stat_tab = AcidStatsTab(self) self.soil_prop_stat_tab = SoilPropStatsTab(self) tabs.addTab(self.raster_tab, "栅格重分类") tabs.addTab(self.area_stat_tab, "面积统计表制作") tabs.addTab(self.export_map_tab, "导出工程文件") tabs.addTab(self.export_image_tab, "导出成果图") tabs.addTab(self.acid_stat_tab, "酸化专题图表格统计") tabs.addTab(self.soil_prop_stat_tab, "土壤属性表制作") main_layout.addWidget(tabs) # 添加日志区域 self.log_area = QTextEdit() self.log_area.setReadOnly(True) self.log_area.setFixedHeight(120) self.log_signal.connect(self.append_log) # 日志信号连接 main_layout.addWidget(QLabel("日志输出")) main_layout.addWidget(self.log_area) # 添加清除日志按钮 log_control_layout = QHBoxLayout() clear_log_btn = QPushButton("清空日志") clear_log_btn.clicked.connect(self.clear_log) log_control_layout.addStretch() log_control_layout.addWidget(clear_log_btn) main_layout.addLayout(log_control_layout) # 连接信号与槽 self.raster_tab.value_changed.connect(self.export_map_tab.update_config_file) self.raster_tab.value_changed.connect(self.area_stat_tab.update_config_file) self.raster_tab.value_changed.connect(self.soil_prop_stat_tab.update_config_file) def ensure_settings_file(self): """确保配置文件存在,如不存在则创建""" if not os.path.exists(self.settings_file): default_settings = self.get_default_settings() try: os.makedirs(os.path.dirname(self.settings_file), exist_ok=True) with open(self.settings_file, "w", encoding="utf-8") as f: json.dump(default_settings, f, indent=4, ensure_ascii=False) except Exception as e: print(f"创建配置文件失败: {str(e)}") def load_settings(self): """加载设置""" try: if os.path.exists(self.settings_file): with open(self.settings_file, "r", encoding="utf-8") as f: return json.load(f) return self.get_default_settings() except Exception as e: print(f"加载设置失败: {str(e)}") return self.get_default_settings() def save_settings(self): """保存设置""" try: config_dir = os.path.dirname(self.settings_file) if not os.path.exists(config_dir): os.makedirs(config_dir, exist_ok=True) with open(self.settings_file, "w", encoding="utf-8") as f: json.dump(self.settings, f, indent=4, ensure_ascii=False) print("配置已更新") except Exception as e: print(f"保存设置失败: {str(e)}") def get_default_settings(self): """获取默认设置""" return { "export_map_settings": { "template_aprx_file": "D:/工作/ArcGisPro/模板/工程模板.aprx", "output_path": "D:/工作/ArcGisPro/输出文件夹", "data_source_path": "D:/工作/ArcGisPro/数据源/土壤属性图矢量数据.gdb", "config_file": "D:/arcpystudy/ArcGisPro/tools/ui/raster_test_config.json", "county_name": "港南区", "symbol_path": "D:/工作/ArcGisPro/模板/符号系统", }, "export_image_settings": { "input_aprx_path": "D:/工作/ArcGisPro/输出文件夹/港南区_工作空间", "output_image_path": "D:/工作/ArcGisPro/输出文件夹", "default_format": "PDF", "resolution": 300, 'force_regenerate': True, 'use_multiprocessing': True, 'process_count': 3 }, "raster_settings": { "input_folder": "D:/工作/三普成果编制/港南区土壤属性图成果最终", "batch_output_folder": "D:/工作/ArcGisPro/输出文件夹/港南区_工作空间", "config_file_path": "D:/arcpystudy/ArcGisPro/tools/ui/raster_test_config.json", "simplify": True, "min_area": 10000, "area_unit": "平方米", }, "area_stat_settings": { "input_folder": "D:/工作/三普成果编制/港南区土壤属性图成果最终", "batch_output_folder": "D:/工作/ArcGisPro/输出文件夹/港南区_工作空间", "config_file_path": "D:/arcpystudy/ArcGisPro/tools/ui/raster_test_config.json", "dltb_polygon": "D:/工作/三普成果编制/港南区土壤属性图成果最终/港南区_地类图_2021-09-01.shp", "xzq_polygon": "D:/工作/三普成果编制/港南区土壤属性图成果最终/港南区_区县图_2021-09-01.shp", }, } def closeEvent(self, event): """窗口关闭处理""" thread_pool = QThreadPool.globalInstance() if thread_pool is not None: thread_pool.waitForDone(2000) self.update_settings() self.save_settings() super().closeEvent(event) def update_settings(self): """更新设置""" try: # 更新导出工程设置 if hasattr(self.export_map_tab, "get_settings"): export_map_settings = self.export_map_tab.get_settings() if export_map_settings: self.settings["export_map_settings"] = export_map_settings # 更新导出成果图设置 if hasattr(self.export_image_tab, "get_layout_settings"): raster_settings = self.export_image_tab.get_layout_settings() if raster_settings: self.settings["export_image_settings"]= raster_settings # 更新栅格处理设置 if hasattr(self.raster_tab, "get_raster_settings"): raster_settings = self.raster_tab.get_raster_settings() if raster_settings: self.settings["raster_settings"]= raster_settings # 更新面积统计设置 if hasattr(self.area_stat_tab, "get_area_stat_settings"): area_stat_settings = self.area_stat_tab.get_area_stat_settings() if area_stat_settings: self.settings["area_stat_settings"]= area_stat_settings # 更新酸化统计设置 if hasattr(self.acid_stat_tab, "get_acid_stat_settings"): acid_stat_settings = self.acid_stat_tab.get_acid_stat_settings() if acid_stat_settings: self.settings["acid_stat_settings"]= acid_stat_settings # 更新土壤属性统计设置 if hasattr(self.soil_prop_stat_tab, "get_soil_prop_stat_settings"): soil_prop_stat_settings = self.soil_prop_stat_tab.get_soil_prop_stat_settings() if soil_prop_stat_settings: self.settings["soil_prop_stat_settings"]= soil_prop_stat_settings except Exception as e: print(f"更新设置失败: {str(e)}") # 回溯 traceback.print_exc() def load_ui_settings(self): """加载UI设置到各个组件""" try: # 加载成果图导出标签页设置 if hasattr(self.export_image_tab, "load_settings"): self.export_image_tab.load_settings() # 加载栅格处理标签页设置 if hasattr(self.raster_tab, "load_settings"): self.raster_tab.load_settings(self.settings["raster_settings"]) # 加载面积统计标签页设置 if hasattr(self.area_stat_tab, "load_settings"): self.area_stat_tab.load_settings(self.settings["area_stat_settings"]) # 加载酸化专题统计标签页设置 if hasattr(self.acid_stat_tab, "load_settings"): self.acid_stat_tab.load_settings(self.settings["acid_stat_settings"]) # 加载土壤属性统计标签页设置 if hasattr(self.soil_prop_stat_tab, "load_settings"): self.soil_prop_stat_tab.load_settings(self.settings["soil_prop_stat_settings"]) except Exception as e: print(f"加载UI设置失败: {str(e)}") def append_log(self, message): """在日志区域追加信息""" try: from datetime import datetime timestamp = datetime.now().strftime("%H:%M:%S") # 如果传入字符串中已存在时间戳,则不添加时间戳 if "[" in message and "]" in message: formatted_message = message else: formatted_message = f"[{timestamp}] {message}" # 根据消息类型设置不同颜色 if "错误" in message or "失败" in message or "出错" in message: formatted_message = f'{formatted_message}' elif "警告" in message: formatted_message = f'{formatted_message}' elif "成功" in message or "完成" in message: formatted_message = f'{formatted_message}' else: formatted_message = f'{formatted_message}' self.log_area.append(formatted_message) self.log_area.verticalScrollBar().setValue( self.log_area.verticalScrollBar().maximum() ) # 如果消息太多,清除旧消息 if self.log_area.document().lineCount() > 500: cursor = self.log_area.textCursor() cursor.movePosition(QTextCursor.MoveOperation.Start) cursor.movePosition( QTextCursor.MoveOperation.Down, QTextCursor.MoveMode.KeepAnchor, 100 ) cursor.removeSelectedText() except Exception as e: print(f"追加日志失败: {str(e)}") def clear_log(self): """清空日志区域""" self.log_area.clear() # 如果直接运行该模块 if __name__ == "__main__": from PyQt6.QtWidgets import QApplication app = QApplication(sys.argv) window = MainWindow() window.show() sys.exit(app.exec())