310 lines
13 KiB
Python
310 lines
13 KiB
Python
from pathlib import Path
|
||
|
||
from PySide6.QtWidgets import QMainWindow, QMessageBox, QFileDialog
|
||
from PySide6.QtGui import QGuiApplication
|
||
from matplotlib import use
|
||
from yaml import dump, load, FullLoader
|
||
|
||
from func.utils.PublicFunc import PublicFunc
|
||
from ui.MainWindow.MainWindow_menu import Ui_Signal_Label
|
||
|
||
from func.Module_approximately_align import MainWindow_approximately_align
|
||
from func.Module_preprocess import MainWindow_preprocess
|
||
from func.Module_detect_Jpeak import MainWindow_detect_Jpeak
|
||
from func.Module_detect_Rpeak import MainWindow_detect_Rpeak
|
||
from func.Module_label_check import MainWindow_label_check
|
||
from func.Module_precisely_align import MainWindow_precisely_align
|
||
from func.Module_cut_PSG import MainWindow_cut_PSG
|
||
from func.Module_artifact_label import MainWindow_artifact_label
|
||
from func.Module_bcg_quality_label import MainWindow_bcg_quality_label
|
||
from func.Module_resp_quality_label import MainWindow_resp_quality_label
|
||
from func.Module_SA_label import MainWindow_SA_label
|
||
|
||
from func.utils.ConfigParams import Filename, Params
|
||
from func.utils.Constants import Constants
|
||
|
||
|
||
use("QtAgg")
|
||
|
||
|
||
Config = {
|
||
|
||
}
|
||
|
||
|
||
class MainWindow(QMainWindow, Ui_Signal_Label):
|
||
|
||
def __init__(self):
|
||
super(MainWindow, self).__init__()
|
||
self.ui = Ui_Signal_Label()
|
||
self.ui.setupUi(self)
|
||
|
||
# self.setFixedSize(720, 1080) # 设置固定大小,禁止缩放
|
||
# 获得屏幕分辨率,以3:4比例设置窗口大小,
|
||
screen = QGuiApplication.primaryScreen()
|
||
size = screen.availableGeometry()
|
||
screen_height = size.height()
|
||
|
||
window_height = int(screen_height * 0.75)
|
||
window_width = int(window_height * 1 / 2)
|
||
self.resize(window_width, window_height)
|
||
|
||
# 消息弹窗初始化
|
||
self.msgBox = QMessageBox()
|
||
self.msgBox.setWindowTitle(Constants.MAINWINDOW_MSGBOX_TITLE)
|
||
|
||
self.__read_config__()
|
||
self.ui.plainTextEdit_root_path.setPlainText(Config["Path"]["Root"])
|
||
self.seek_sampID(Path(Config["Path"]["Root"]) / Path(Filename.PATH_ORGBCG_TEXT))
|
||
|
||
self.approximately_align = None
|
||
self.preprocess = None
|
||
self.detect_Jpeak = None
|
||
self.detect_Rpeak = None
|
||
self.label_check = None
|
||
self.precisely_align = None
|
||
self.cut_PSG = None
|
||
self.artifact_label = None
|
||
self.bcg_quality_label = None
|
||
self.resp_quality_label = None
|
||
self.SA_label = None
|
||
|
||
# 绑定槽函数
|
||
self.ui.pushButton_open.clicked.connect(self.__slot_btn_open__)
|
||
self.ui.pushButton_approximately_align.clicked.connect(self.__slot_btn_approximately_align__)
|
||
self.ui.pushButton_preprocess_BCG.clicked.connect(self.__slot_btn_preprocess__)
|
||
self.ui.pushButton_preprocess_ECG.clicked.connect(self.__slot_btn_preprocess__)
|
||
self.ui.pushButton_detect_Jpeak.clicked.connect(self.__slot_btn_detect_Jpeak__)
|
||
self.ui.pushButton_detect_Rpeak.clicked.connect(self.__slot_btn_detect_Rpeak__)
|
||
self.ui.pushButton_label_check_BCG.clicked.connect(self.__slot_btn_label_check__)
|
||
self.ui.pushButton_label_check_ECG.clicked.connect(self.__slot_btn_label_check__)
|
||
self.ui.pushButton_precisely_align.clicked.connect(self.__slot_btn_precisely_align__)
|
||
self.ui.pushButton_cut_PSG.clicked.connect(self.__slot_btn_cut_PSG__)
|
||
self.ui.pushButton_artifact_label.clicked.connect(self.__slot_btn_artifact_label__)
|
||
self.ui.pushButton_bcg_quality_label.clicked.connect(self.__slot_btn_bcg_quality_label__)
|
||
self.ui.pushButton_resp_quality_label.clicked.connect(self.__slot_btn_resp_quality_label__)
|
||
self.ui.pushButton_SA_label.clicked.connect(self.__slot_btn_SA_label__)
|
||
|
||
@staticmethod
|
||
def __read_config__():
|
||
if not Path(Params.PUBLIC_CONFIG_FILE_PATH).exists():
|
||
Path(Params.PUBLIC_CONFIG_FILE_PATH).parent.mkdir(parents=True, exist_ok=True)
|
||
with open(Params.PUBLIC_CONFIG_FILE_PATH, "w") as f:
|
||
dump(Params.PUBLIC_CONFIG_NEW_CONTENT, f)
|
||
|
||
with open(Params.PUBLIC_CONFIG_FILE_PATH, "r") as f:
|
||
file_config = load(f.read(), Loader=FullLoader)
|
||
Config.update(file_config)
|
||
|
||
@staticmethod
|
||
def __write_config__():
|
||
with open(Path(Params.PUBLIC_CONFIG_FILE_PATH), "w") as f:
|
||
dump(Config, f)
|
||
|
||
def __slot_btn_open__(self):
|
||
file_dialog = QFileDialog()
|
||
file_dialog.setFileMode(QFileDialog.Directory)
|
||
file_dialog.setOption(QFileDialog.ShowDirsOnly, True)
|
||
if file_dialog.exec_() == QFileDialog.Accepted:
|
||
self.seek_sampID(Path(file_dialog.selectedFiles()[0]) / Filename.PATH_ORGBCG_TEXT)
|
||
self.ui.plainTextEdit_root_path.setPlainText(file_dialog.selectedFiles()[0])
|
||
|
||
# 修改配置
|
||
Config["Path"]["Root"] = str(file_dialog.selectedFiles()[0])
|
||
self.__write_config__()
|
||
else:
|
||
PublicFunc.msgbox_output(self, Constants.OPERATION_CANCELED, Constants.MSGBOX_TYPE_INFO)
|
||
|
||
def __slot_btn_approximately_align__(self):
|
||
self.approximately_align = MainWindow_approximately_align()
|
||
root_path = self.ui.plainTextEdit_root_path.toPlainText()
|
||
sampID = self.ui.comboBox_sampID.currentText()
|
||
if not self.check_root_path():
|
||
return
|
||
if not self.check_sampID():
|
||
return
|
||
self.approximately_align.show(root_path, int(sampID))
|
||
# 默认最大化显示而非固定分辨率
|
||
self.approximately_align.showMaximized()
|
||
self.check_save_path_and_mkdir(root_path, sampID)
|
||
|
||
def __slot_btn_preprocess__(self):
|
||
self.preprocess = MainWindow_preprocess()
|
||
|
||
sender = self.sender()
|
||
root_path = self.ui.plainTextEdit_root_path.toPlainText()
|
||
sampID = self.ui.comboBox_sampID.currentText()
|
||
if sender == self.ui.pushButton_preprocess_BCG:
|
||
mode = "BCG"
|
||
elif sender == self.ui.pushButton_preprocess_ECG:
|
||
mode = "ECG"
|
||
else:
|
||
raise ValueError("模式不存在")
|
||
if not self.check_root_path():
|
||
return
|
||
if not self.check_sampID():
|
||
return
|
||
self.preprocess.show(mode, root_path, int(sampID))
|
||
# 默认最大化显示而非固定分辨率
|
||
self.preprocess.showMaximized()
|
||
self.check_save_path_and_mkdir(root_path, sampID)
|
||
|
||
def __slot_btn_detect_Jpeak__(self):
|
||
self.detect_Jpeak = MainWindow_detect_Jpeak()
|
||
root_path = self.ui.plainTextEdit_root_path.toPlainText()
|
||
sampID = self.ui.comboBox_sampID.currentText()
|
||
if not self.check_root_path():
|
||
return
|
||
if not self.check_sampID():
|
||
return
|
||
self.detect_Jpeak.show(root_path, int(sampID))
|
||
# 默认最大化显示而非固定分辨率
|
||
self.detect_Jpeak.showMaximized()
|
||
self.check_save_path_and_mkdir(root_path, sampID)
|
||
|
||
def __slot_btn_detect_Rpeak__(self):
|
||
self.detect_Rpeak = MainWindow_detect_Rpeak()
|
||
root_path = self.ui.plainTextEdit_root_path.toPlainText()
|
||
sampID = self.ui.comboBox_sampID.currentText()
|
||
if not self.check_root_path():
|
||
return
|
||
if not self.check_sampID():
|
||
return
|
||
self.detect_Rpeak.show(root_path, int(sampID))
|
||
# 默认最大化显示而非固定分辨率
|
||
self.detect_Rpeak.showMaximized()
|
||
self.check_save_path_and_mkdir(root_path, sampID)
|
||
|
||
def __slot_btn_label_check__(self):
|
||
self.label_check = MainWindow_label_check()
|
||
|
||
sender = self.sender()
|
||
root_path = self.ui.plainTextEdit_root_path.toPlainText()
|
||
sampID = self.ui.comboBox_sampID.currentText()
|
||
|
||
if not self.check_root_path():
|
||
return
|
||
if not self.check_sampID():
|
||
return
|
||
|
||
if sender == self.ui.pushButton_label_check_BCG:
|
||
mode = "BCG"
|
||
elif sender == self.ui.pushButton_label_check_ECG:
|
||
mode = "ECG"
|
||
else:
|
||
raise ValueError("模式不存在")
|
||
self.label_check.show(mode, root_path, int(sampID))
|
||
# 默认最大化显示而非固定分辨率
|
||
self.label_check.showMaximized()
|
||
self.check_save_path_and_mkdir(root_path, sampID)
|
||
|
||
def __slot_btn_precisely_align__(self):
|
||
self.precisely_align = MainWindow_precisely_align()
|
||
root_path = self.ui.plainTextEdit_root_path.toPlainText()
|
||
sampID = self.ui.comboBox_sampID.currentText()
|
||
if not self.check_root_path():
|
||
return
|
||
if not self.check_sampID():
|
||
return
|
||
self.precisely_align.show(root_path, int(sampID))
|
||
# 默认最大化显示而非固定分辨率
|
||
self.precisely_align.showMaximized()
|
||
self.check_save_path_and_mkdir(root_path, sampID)
|
||
|
||
def __slot_btn_cut_PSG__(self):
|
||
self.cut_PSG = MainWindow_cut_PSG()
|
||
root_path = self.ui.plainTextEdit_root_path.toPlainText()
|
||
sampID = self.ui.comboBox_sampID.currentText()
|
||
if not self.check_root_path():
|
||
return
|
||
if not self.check_sampID():
|
||
return
|
||
self.cut_PSG.show(root_path, int(sampID))
|
||
self.check_save_path_and_mkdir(root_path, sampID)
|
||
|
||
def __slot_btn_artifact_label__(self):
|
||
self.artifact_label = MainWindow_artifact_label()
|
||
root_path = self.ui.plainTextEdit_root_path.toPlainText()
|
||
sampID = self.ui.comboBox_sampID.currentText()
|
||
if not self.check_root_path():
|
||
return
|
||
if not self.check_sampID():
|
||
return
|
||
self.artifact_label.show(root_path, int(sampID))
|
||
# 默认最大化显示而非固定分辨率
|
||
self.artifact_label.showMaximized()
|
||
self.check_save_path_and_mkdir(root_path, sampID)
|
||
|
||
def __slot_btn_bcg_quality_label__(self):
|
||
self.bcg_quality_label = MainWindow_bcg_quality_label()
|
||
root_path = self.ui.plainTextEdit_root_path.toPlainText()
|
||
sampID = self.ui.comboBox_sampID.currentText()
|
||
if not self.check_root_path():
|
||
return
|
||
if not self.check_sampID():
|
||
return
|
||
self.bcg_quality_label.show(root_path, int(sampID))
|
||
# 默认最大化显示而非固定分辨率
|
||
self.bcg_quality_label.showMaximized()
|
||
self.check_save_path_and_mkdir(root_path, sampID)
|
||
|
||
def __slot_btn_resp_quality_label__(self):
|
||
self.resp_quality_label = MainWindow_resp_quality_label()
|
||
root_path = self.ui.plainTextEdit_root_path.toPlainText()
|
||
sampID = self.ui.comboBox_sampID.currentText()
|
||
if not self.check_root_path():
|
||
return
|
||
if not self.check_sampID():
|
||
return
|
||
self.resp_quality_label.show(root_path, int(sampID))
|
||
# 默认最大化显示而非固定分辨率
|
||
self.resp_quality_label.showMaximized()
|
||
self.check_save_path_and_mkdir(root_path, sampID)
|
||
|
||
def __slot_btn_SA_label__(self):
|
||
self.SA_label = MainWindow_SA_label()
|
||
root_path = self.ui.plainTextEdit_root_path.toPlainText()
|
||
sampID = self.ui.comboBox_sampID.currentText()
|
||
if not self.check_root_path():
|
||
return
|
||
if not self.check_sampID():
|
||
return
|
||
self.SA_label.show(root_path, int(sampID))
|
||
# 默认最大化显示而非固定分辨率
|
||
self.SA_label.showMaximized()
|
||
self.check_save_path_and_mkdir(root_path, sampID)
|
||
|
||
def seek_sampID(self, path):
|
||
if not Path(path).exists():
|
||
PublicFunc.msgbox_output(self, Constants.MAINWINDOW_ROOT_PATH_NOT_EXIST, Constants.MSGBOX_TYPE_ERROR)
|
||
self.ui.comboBox_sampID.clear()
|
||
return
|
||
|
||
sub_folders = [item.name for item in Path(path).iterdir() if item.is_dir()]
|
||
self.ui.comboBox_sampID.clear()
|
||
self.ui.comboBox_sampID.addItems(sub_folders)
|
||
|
||
def check_root_path(self):
|
||
if self.ui.plainTextEdit_root_path.toPlainText() == Constants.STRING_IS_EMPTY:
|
||
PublicFunc.msgbox_output(self, Constants.MAINWINDOW_ROOT_PATH_NOT_EXIST, Constants.MSGBOX_TYPE_ERROR)
|
||
return False
|
||
return True
|
||
|
||
def check_sampID(self):
|
||
if self.ui.comboBox_sampID.currentText() == Constants.STRING_IS_EMPTY:
|
||
PublicFunc.msgbox_output(self, Constants.MAINWINDOW_SAMPID_EMPTY, Constants.MSGBOX_TYPE_ERROR)
|
||
return False
|
||
return True
|
||
|
||
def check_save_path_and_mkdir(self, root_path, sampID):
|
||
path_Label = Path(root_path) / Path(Filename.PATH_LABEL) / Path(str(sampID))
|
||
path_OrgBCG_Aligned = Path(root_path) / Path(Filename.PATH_ORGBCG_ALIGNED) / Path(str(sampID))
|
||
path_PSG_Aligned = Path(root_path) / Path(Filename.PATH_PSG_ALIGNED) / Path(str(sampID))
|
||
path_OrgBCG_Text = Path(root_path) / Path(Filename.PATH_ORGBCG_TEXT) / Path(str(sampID))
|
||
path_PSG_Text = Path(root_path) / Path(Filename.PATH_PSG_TEXT) / Path(str(sampID))
|
||
|
||
path_list = [path_Label, path_OrgBCG_Aligned, path_PSG_Aligned, path_OrgBCG_Text, path_PSG_Text]
|
||
|
||
for path in path_list:
|
||
if not path.exists():
|
||
path.mkdir(parents=True, exist_ok=True) |