Merge branch 'master' into cxh_dev

This commit is contained in:
marques
2025-06-16 18:42:43 +08:00
8 changed files with 116 additions and 134 deletions

View File

@ -3,7 +3,6 @@ from pathlib import Path
from traceback import format_exc from traceback import format_exc
import matplotlib.pyplot as plt import matplotlib.pyplot as plt
from PySide6.QtCore import QEvent
from PySide6.QtWidgets import QMessageBox, QMainWindow, QApplication from PySide6.QtWidgets import QMessageBox, QMainWindow, QApplication
from matplotlib.backends.backend_qt import NavigationToolbar2QT from matplotlib.backends.backend_qt import NavigationToolbar2QT
from matplotlib.backends.backend_qtagg import FigureCanvasQTAgg as FigureCanvas from matplotlib.backends.backend_qtagg import FigureCanvasQTAgg as FigureCanvas
@ -275,8 +274,6 @@ class MainWindow_approximately_align(QMainWindow):
PublicFunc.__resetAllButton__(self, ButtonState) PublicFunc.__resetAllButton__(self, ButtonState)
# self.ui.groupBox_align_position.setEnabled(False)
self.ui.pushButton_input.clicked.connect(self.__slot_btn_input__) self.ui.pushButton_input.clicked.connect(self.__slot_btn_input__)
self.ui.pushButton_input_setting.clicked.connect(self.setting.show) self.ui.pushButton_input_setting.clicked.connect(self.setting.show)
self.ui.pushButton_Standardize.clicked.connect(self.__slot_btn_Standardize__) self.ui.pushButton_Standardize.clicked.connect(self.__slot_btn_Standardize__)

View File

@ -9,7 +9,7 @@ from PySide6.QtWidgets import QMessageBox, QMainWindow, QApplication, QTableWidg
from matplotlib import gridspec, patches from matplotlib import gridspec, patches
from matplotlib.backends.backend_qt import NavigationToolbar2QT from matplotlib.backends.backend_qt import NavigationToolbar2QT
from matplotlib.backends.backend_qtagg import FigureCanvasQTAgg from matplotlib.backends.backend_qtagg import FigureCanvasQTAgg
from numpy import array, sum as np_sum, nonzero from numpy import array
from numpy.fft import fft, fftfreq from numpy.fft import fft, fftfreq
from overrides import overrides from overrides import overrides
from pandas import read_csv, DataFrame, concat from pandas import read_csv, DataFrame, concat

View File

@ -365,6 +365,21 @@ class MainWindow(QMainWindow, Ui_Signal_Label):
path.mkdir(parents=True, exist_ok=True) path.mkdir(parents=True, exist_ok=True)
def set_dark_mode_status(self): def set_dark_mode_status(self):
module_list = [
self,
self.approximately_align,
self.preprocess,
self.detect_Jpeak,
self.detect_Rpeak,
self.label_check,
self.precisely_align,
self.cut_PSG,
self.artifact_label,
self.bcg_quality_label,
self.resp_quality_label,
self.SA_label
]
try: try:
if self.ui.checkBox_darkmode.isChecked(): if self.ui.checkBox_darkmode.isChecked():
QApplication.styleHints().setColorScheme(Qt.ColorScheme.Dark) QApplication.styleHints().setColorScheme(Qt.ColorScheme.Dark)
@ -374,63 +389,10 @@ class MainWindow(QMainWindow, Ui_Signal_Label):
PublicFunc.msgbox_output(self, Constants.MAINWINDOW_DARKMODE_FAILURE + "" + format_exc(), Constants.MSGBOX_TYPE_ERROR) PublicFunc.msgbox_output(self, Constants.MAINWINDOW_DARKMODE_FAILURE + "" + format_exc(), Constants.MSGBOX_TYPE_ERROR)
return return
for module in module_list:
try: try:
MainWindow.update_widget_style(self) if module is not None:
except RuntimeError: MainWindow.update_widget_style(module)
pass
try:
if self.approximately_align is not None:
MainWindow.update_widget_style(self.approximately_align)
except RuntimeError:
pass
try:
if self.preprocess is not None:
MainWindow.update_widget_style(self.preprocess)
except RuntimeError:
pass
try:
if self.detect_Jpeak is not None:
MainWindow.update_widget_style(self.detect_Jpeak)
except RuntimeError:
pass
try:
if self.detect_Rpeak is not None:
MainWindow.update_widget_style(self.detect_Rpeak)
except RuntimeError:
pass
try:
if self.label_check is not None:
MainWindow.update_widget_style(self.label_check)
except RuntimeError:
pass
try:
if self.precisely_align is not None:
MainWindow.update_widget_style(self.precisely_align)
except RuntimeError:
pass
try:
if self.cut_PSG is not None:
MainWindow.update_widget_style(self.cut_PSG)
except RuntimeError:
pass
try:
if self.artifact_label is not None:
MainWindow.update_widget_style(self.artifact_label)
except RuntimeError:
pass
try:
if self.bcg_quality_label is not None:
MainWindow.update_widget_style(self.bcg_quality_label)
except RuntimeError:
pass
try:
if self.resp_quality_label is not None:
MainWindow.update_widget_style(self.resp_quality_label)
except RuntimeError:
pass
try:
if self.SA_label is not None:
MainWindow.update_widget_style(self.SA_label)
except RuntimeError: except RuntimeError:
pass pass

View File

@ -1645,9 +1645,6 @@ class Data:
self.correlation_align_point_match_ECG = array([]).astype(int) self.correlation_align_point_match_ECG = array([]).astype(int)
self.correlation_align_point_match_BCG = array([]).astype(int) self.correlation_align_point_match_BCG = array([]).astype(int)
self.argmax_BCG = None
self.argmax_ECG = None
def open_file(self): def open_file(self):
if Path(Config["Path"]["Input_OrgBCG"]).is_file(): if Path(Config["Path"]["Input_OrgBCG"]).is_file():
Config["Path"]["Input_OrgBCG"] = str(Path(Config["Path"]["Input_OrgBCG"]).parent) Config["Path"]["Input_OrgBCG"] = str(Path(Config["Path"]["Input_OrgBCG"]).parent)
@ -1740,8 +1737,6 @@ class Data:
self.Rpeak = read_csv(Config["Path"]["Input_Rpeak"], self.Rpeak = read_csv(Config["Path"]["Input_Rpeak"],
encoding=Params.UTF8_ENCODING, encoding=Params.UTF8_ENCODING,
header=None).to_numpy().reshape(-1) header=None).to_numpy().reshape(-1)
self.argmax_BCG = np_argmax(self.raw_BCG)
self.argmax_ECG = np_argmax(self.raw_ECG)
except Exception as e: except Exception as e:
return Result().failure(info=Constants.INPUT_FAILURE + return Result().failure(info=Constants.INPUT_FAILURE +
Constants.FAILURE_REASON["Open_Data_Exception"] + "\n" + format_exc()) Constants.FAILURE_REASON["Open_Data_Exception"] + "\n" + format_exc())
@ -1949,55 +1944,63 @@ class Data:
def correlation_align(self, mode): def correlation_align(self, mode):
try: try:
if mode == "init": if mode == "init":
anchor0 = [Config["front"]["anchor_R"], Config["front"]["anchor_J"]] Config["orgfs"] = ((int(Config["back"]["anchor_J"]) - int(Config["front"]["anchor_J"])) * Config["InputConfig"]["UseFreq"] /
anchor1 = [Config["back"]["anchor_R"], Config["back"]["anchor_J"]] (int(Config["back"]["anchor_R"]) - int(Config["front"]["anchor_R"])))
Config["orgfs"] = ((int(anchor1[1]) - int(anchor0[1])) * Config["InputConfig"]["UseFreq"] / Config["offset_anchor"] = Config["front"]["anchor_R"] - Config["front"]["anchor_J"]
(int(anchor1[0]) - int(anchor0[0])))
Config["offset_anchor"] = anchor0[0] - anchor0[1]
orgfs = Config["orgfs"]
off = Config["offset_anchor"]
self.res_orgBcg = self.raw_orgBcg.copy() self.res_orgBcg = self.raw_orgBcg.copy()
self.res_BCG = self.raw_BCG.copy() self.res_BCG = self.raw_BCG.copy()
self.cut_ECG = self.raw_ECG.copy() self.cut_ECG = self.raw_ECG.copy()
self.cut_Rpeak = self.Rpeak.copy() self.cut_Rpeak = self.Rpeak.copy()
if off > 0: Config["frontcut_index_BCG"], Config["frontcut_index_ECG"] = 0, 0
self.cut_ECG = self.cut_ECG[off:]
anchor0[0] = anchor0[0] - off if Config["offset_anchor"] > 0:
anchor1[0] = anchor1[0] - off self.cut_ECG = self.cut_ECG[Config["offset_anchor"]:]
idxs = where(self.cut_Rpeak > off)[0] Config["front"]["anchor_R"] = Config["front"]["anchor_R"] - Config["offset_anchor"]
self.cut_Rpeak = self.cut_Rpeak[idxs] - off Config["back"]["anchor_R"] = Config["back"]["anchor_R"] - Config["offset_anchor"]
idxs = where(self.cut_Rpeak > Config["offset_anchor"])[0]
self.cut_Rpeak = self.cut_Rpeak[idxs] - Config["offset_anchor"]
Config["frontcut_index_ECG"] += Config["offset_anchor"]
else: else:
self.res_BCG = self.res_BCG[-off:] self.res_BCG = self.res_BCG[-Config["offset_anchor"]:]
self.res_orgBcg = self.res_orgBcg[-off:] self.res_orgBcg = self.res_orgBcg[-Config["offset_anchor"]:]
anchor0[1] = anchor0[1] + off Config["front"]["anchor_J"] = Config["front"]["anchor_J"] + Config["offset_anchor"]
anchor1[1] = anchor1[1] + off Config["back"]["anchor_J"] = Config["back"]["anchor_J"] + Config["offset_anchor"]
Config["frontcut_index_BCG"] -= Config["offset_anchor"]
self.res_BCG = resample(self.res_BCG, orgfs, Config["InputConfig"]["UseFreq"]) self.res_BCG = resample(self.res_BCG, Config["orgfs"], Config["InputConfig"]["UseFreq"])
self.res_orgBcg = resample(self.res_orgBcg, orgfs, Config["InputConfig"]["UseFreq"]) self.res_orgBcg = resample(self.res_orgBcg, Config["orgfs"], Config["InputConfig"]["UseFreq"])
anchor0[1] = round(int(anchor0[1]) * Config["InputConfig"]["UseFreq"] / orgfs) Config["front"]["anchor_J"] = round(int(Config["front"]["anchor_J"]) * Config["InputConfig"]["UseFreq"] / Config["orgfs"])
anchor1[1] = round(int(anchor1[1]) * Config["InputConfig"]["UseFreq"] / orgfs) Config["back"]["anchor_J"] = round(int(Config["back"]["anchor_J"]) * Config["InputConfig"]["UseFreq"] / Config["orgfs"])
off = anchor1[0] - anchor1[1] Config["offset_anchor"] = Config["back"]["anchor_R"] - Config["back"]["anchor_J"]
if off > 0: if Config["offset_anchor"] > 0:
self.cut_ECG = self.cut_ECG[off:] self.cut_ECG = self.cut_ECG[Config["offset_anchor"]:]
anchor0[0] = anchor0[0] - off Config["front"]["anchor_R"] = Config["front"]["anchor_R"] - Config["offset_anchor"]
anchor1[0] = anchor1[0] - off Config["back"]["anchor_R"] = Config["back"]["anchor_R"] - Config["offset_anchor"]
idxs = where(self.cut_Rpeak > off)[0] idxs = where(self.cut_Rpeak > Config["offset_anchor"])[0]
self.cut_Rpeak = self.cut_Rpeak[idxs] - off self.cut_Rpeak = self.cut_Rpeak[idxs] - Config["offset_anchor"]
Config["frontcut_index_ECG"] += Config["offset_anchor"] * Config["orgfs"] / Config["InputConfig"]["UseFreq"]
else: else:
self.res_BCG = self.res_BCG[-off:] self.res_BCG = self.res_BCG[-Config["offset_anchor"]:]
self.res_orgBcg = self.res_orgBcg[-off:] self.res_orgBcg = self.res_orgBcg[-Config["offset_anchor"]:]
anchor0[1] = anchor0[1] + off Config["front"]["anchor_J"] = Config["front"]["anchor_J"] + Config["offset_anchor"]
anchor1[1] = anchor1[1] + off Config["back"]["anchor_J"] = Config["back"]["anchor_J"] + Config["offset_anchor"]
Config["frontcut_index_BCG"] -= Config["offset_anchor"] * Config["orgfs"] / Config["InputConfig"]["UseFreq"]
datalen = np_min([len(self.cut_ECG), len(self.res_BCG)]) datalen = np_min([len(self.cut_ECG), len(self.res_BCG)])
self.cut_ECG = self.cut_ECG[:datalen] self.cut_ECG = self.cut_ECG[:datalen]
self.res_BCG = self.res_BCG[:datalen] self.res_BCG = self.res_BCG[:datalen]
self.res_orgBcg = self.res_orgBcg[:datalen] self.res_orgBcg = self.res_orgBcg[:datalen]
Config["frontcut_index_BCG"] = int(Config["frontcut_index_BCG"])
Config["frontcut_index_ECG"] = int(Config["frontcut_index_ECG"])
Config["backcut_index_BCG"] = int(Config["frontcut_index_BCG"] + datalen)
Config["backcut_index_ECG"] = int(Config["frontcut_index_ECG"] + datalen)
a = np_max([np_max(self.cut_ECG), np_max(self.res_BCG)]) a = np_max([np_max(self.cut_ECG), np_max(self.res_BCG)])
b = np_min([np_min(self.cut_ECG), np_min(self.res_BCG)]) b = np_min([np_min(self.cut_ECG), np_min(self.res_BCG)])
peak_ECG, _ = find_peaks(self.cut_ECG) peak_ECG, _ = find_peaks(self.cut_ECG)
@ -2009,8 +2012,8 @@ class Data:
result = { result = {
"res_BCG": self.res_BCG, "res_BCG": self.res_BCG,
"cut_ECG": self.cut_ECG, "cut_ECG": self.cut_ECG,
"anchor00": anchor0[0], "anchor00": Config["front"]["anchor_R"],
"anchor10": anchor1[0], "anchor10": Config["back"]["anchor_R"],
"a": a, "a": a,
"b": b, "b": b,
"peak_ECG": peak_ECG, "peak_ECG": peak_ECG,
@ -2034,38 +2037,41 @@ class Data:
def data_postprocess(self): def data_postprocess(self):
try: try:
if len(self.correlation_align_point_match_ECG) != 2 and len(self.correlation_align_point_match_BCG) != 2: if len(self.correlation_align_point_match_ECG) != 2 and len(self.correlation_align_point_match_BCG) != 2:
off = 0 Config["offset_anchor"] = 0
else: else:
self.correlation_align_point_match_ECG.sort() self.correlation_align_point_match_ECG.sort()
self.correlation_align_point_match_BCG.sort() self.correlation_align_point_match_BCG.sort()
off = round(((int(self.correlation_align_point_match_ECG[1]) - int( Config["offset_anchor"] = round(((int(self.correlation_align_point_match_ECG[1]) - int(
self.correlation_align_point_match_BCG[1])) + (int(self.correlation_align_point_match_ECG[0]) - int( self.correlation_align_point_match_BCG[1])) + (int(self.correlation_align_point_match_ECG[0]) - int(
self.correlation_align_point_match_BCG[0]))) / 2) self.correlation_align_point_match_BCG[0]))) / 2)
anchor0 = [Config["front"]["anchor_R"], Config["front"]["anchor_J"]] if Config["offset_anchor"] > 0:
anchor1 = [Config["back"]["anchor_R"], Config["back"]["anchor_J"]] self.cut_ECG = self.cut_ECG[Config["offset_anchor"]:]
Config["front"]["anchor_R"] = Config["front"]["anchor_R"] - Config["offset_anchor"]
if off > 0: Config["back"]["anchor_R"] = Config["back"]["anchor_R"] - Config["offset_anchor"]
self.cut_ECG = self.cut_ECG[off:] self.cut_Rpeak = self.cut_Rpeak[where(self.cut_Rpeak > Config["offset_anchor"])[0]] - Config["offset_anchor"]
anchor0[0] = anchor0[0] - off Config["frontcut_index_ECG"] += Config["offset_anchor"] * Config["orgfs"] / Config["InputConfig"]["UseFreq"]
anchor1[0] = anchor1[0] - off
self.cut_Rpeak = self.cut_Rpeak[where(self.cut_Rpeak > off)[0]] - off
else: else:
self.res_BCG = self.res_BCG[-off:] self.res_BCG = self.res_BCG[-Config["offset_anchor"]:]
self.res_orgBcg = self.res_orgBcg[-off:] self.res_orgBcg = self.res_orgBcg[-Config["offset_anchor"]:]
anchor0[1] = anchor0[1] + off Config["front"]["anchor_J"] = Config["front"]["anchor_J"] + Config["offset_anchor"]
anchor1[1] = anchor1[1] + off Config["back"]["anchor_J"] = Config["back"]["anchor_J"] + Config["offset_anchor"]
Config["frontcut_index_BCG"] -= Config["offset_anchor"] * Config["orgfs"] / Config["InputConfig"]["UseFreq"]
datalen = np_min([len(self.cut_ECG), len(self.res_BCG)]) datalen = np_min([len(self.cut_ECG), len(self.res_BCG)])
self.cut_ECG = self.cut_ECG[:datalen] self.cut_ECG = self.cut_ECG[:datalen]
self.res_BCG = self.res_BCG[:datalen] self.res_BCG = self.res_BCG[:datalen]
self.res_orgBcg = self.res_orgBcg[:datalen] self.res_orgBcg = self.res_orgBcg[:datalen]
Config["frontcut_index_BCG"] = int(Config["frontcut_index_BCG"])
Config["frontcut_index_ECG"] = int(Config["frontcut_index_ECG"])
Config["backcut_index_BCG"] = int(Config["frontcut_index_BCG"] + datalen)
Config["backcut_index_ECG"] = int(Config["frontcut_index_ECG"] + datalen)
idxs = where(self.cut_Rpeak < datalen)[0] idxs = where(self.cut_Rpeak < datalen)[0]
self.cut_Rpeak = self.cut_Rpeak[idxs] self.cut_Rpeak = self.cut_Rpeak[idxs]
Config["offset_correct"] = off
self.cut_Jpeak = [] self.cut_Jpeak = []
peaks, _ = find_peaks(self.res_BCG) peaks, _ = find_peaks(self.res_BCG)
for i in self.cut_Rpeak: for i in self.cut_Rpeak:
@ -2074,22 +2080,11 @@ class Data:
self.cut_Jpeak.append(peaks[idx]) self.cut_Jpeak.append(peaks[idx])
self.cut_Jpeak = asarray(self.cut_Jpeak).astype(int) self.cut_Jpeak = asarray(self.cut_Jpeak).astype(int)
frontcut_index_BCG = int(
(self.argmax_BCG - np_argmax(self.res_BCG) / Config["InputConfig"]["UseFreq"] * Config["orgfs"]))
backcut_index_BCG = int(len(self.res_BCG) / Config["InputConfig"]["UseFreq"] * Config["orgfs"] + np_argmax(
self.raw_BCG) - np_argmax(self.res_BCG) / Config["InputConfig"]["UseFreq"] * Config["orgfs"])
frontcut_index_ECG = self.argmax_ECG - np_argmax(self.cut_ECG)
backcut_index_ECG = len(self.cut_ECG) + self.argmax_ECG - np_argmax(self.cut_ECG)
Config["frontcut_index_BCG"] = frontcut_index_BCG
Config["backcut_index_BCG"] = backcut_index_BCG
Config["frontcut_index_ECG"] = frontcut_index_ECG
Config["backcut_index_ECG"] = backcut_index_ECG
except Exception as e: except Exception as e:
return Result().failure(info=Constants.PRECISELY_ALIGN_POSTPROCESS_VIEW_FAILURE + return Result().failure(info=Constants.PRECISELY_ALIGN_POSTPROCESS_VIEW_FAILURE +
Constants.FAILURE_REASON["PostProcess_Align_Exception"] + "\n" + format_exc()) Constants.FAILURE_REASON["PostProcess_Align_Exception"] + "\n" + format_exc())
info = f"{Constants.PRECISELY_ALIGN_POSTPROCESS_VIEW_FINISHED}BCG前后段被切割的坐标值为[{frontcut_index_BCG}, {backcut_index_BCG}]ECG前后段被切割的坐标值为[{frontcut_index_ECG}, {backcut_index_ECG}]" info = f"{Constants.PRECISELY_ALIGN_POSTPROCESS_VIEW_FINISHED}BCG前后段被切割的坐标值为[{Config['frontcut_index_BCG']}, {Config['backcut_index_BCG']}]ECG前后段被切割的坐标值为[{Config['frontcut_index_ECG']}, {Config['backcut_index_ECG']}]"
return Result().success(info=info) return Result().success(info=info)
def save_alignInfo(self): def save_alignInfo(self):

View File

@ -94,6 +94,30 @@ class Constants:
background-color: rgba(255, 0, 0, 128); /* 鼠标悬停时的背景颜色 */ background-color: rgba(255, 0, 0, 128); /* 鼠标悬停时的背景颜色 */
}""" }"""
CHECKBOX_STYLE_NORMAL: str = '''
QCheckBox {
border: 2px solid rgb(128, 128, 128);
border-radius: 11px;
}
QCheckBox::indicator{
width: 20px;
height: 20px;
border-radius: 10px;
}
QCheckBox::indicator:checked {
background-color: rgba(0, 255, 0, 192);
image: url(./image/correct.svg);
}
QCheckBox::indicator:unchecked {
background-color: rgba(255, 0, 0, 128);
}
QCheckBox::indicator:disabled {
background-color: rgba(119, 136, 153, 128);
}'''
FAILURE_REASON: dict = { FAILURE_REASON: dict = {
"Path_Not_Exist": "(路径不存在)", "Path_Not_Exist": "(路径不存在)",
"File_Not_Exist": "(数据文件不存在)", "File_Not_Exist": "(数据文件不存在)",

View File

@ -2,7 +2,7 @@ from datetime import datetime
from logging import error, info from logging import error, info
from pathlib import Path from pathlib import Path
from PySide6.QtWidgets import QMessageBox, QWidget, QPushButton, QProgressBar, QApplication, QRadioButton from PySide6.QtWidgets import QMessageBox, QWidget, QPushButton, QProgressBar, QApplication, QRadioButton, QCheckBox
from func.utils.Constants import Constants from func.utils.Constants import Constants
from func.utils.CustomException import TipsTypeValueNotExistError, MsgBoxTypeValueNotExistError from func.utils.CustomException import TipsTypeValueNotExistError, MsgBoxTypeValueNotExistError
@ -152,6 +152,8 @@ class PublicFunc:
if isinstance(widget, QPushButton): if isinstance(widget, QPushButton):
if widget.objectName() in buttonState["Default"].keys(): if widget.objectName() in buttonState["Default"].keys():
widget.setStyleSheet(Constants.LABELBTN_STYLE_NORMAL) widget.setStyleSheet(Constants.LABELBTN_STYLE_NORMAL)
if isinstance(widget, QCheckBox):
widget.setStyleSheet(Constants.CHECKBOX_STYLE_NORMAL)
@staticmethod @staticmethod
def add_progressbar(mainWindow): def add_progressbar(mainWindow):

2
image/correct.svg Normal file
View File

@ -0,0 +1,2 @@
<?xml version="1.0" ?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg fill="#000000" width="800px" height="800px" viewBox="0 0 200 200" data-name="Layer 1" id="Layer_1" xmlns="http://www.w3.org/2000/svg"><title/><path d="M100,15a85,85,0,1,0,85,85A84.93,84.93,0,0,0,100,15Zm0,150a65,65,0,1,1,65-65A64.87,64.87,0,0,1,100,165Zm25-91.5-29,35L76,94c-4.5-3.5-10.5-2.5-14,2s-2.5,10.5,2,14c6,4.5,12.5,9,18.5,13.5,4.5,3,8.5,7.5,14,8,1.5,0,3.5,0,5-1l3-3,22.5-27c4-5,8-9.5,12-14.5,3-4,4-9,.5-13L138,71.5c-3.5-2.5-9.5-2-13,2Z"/></svg>

After

Width:  |  Height:  |  Size: 560 B

4
run.py
View File

@ -1,3 +1,4 @@
from importlib.util import find_spec
from logging import getLogger, NOTSET, FileHandler, Formatter, StreamHandler, info from logging import getLogger, NOTSET, FileHandler, Formatter, StreamHandler, info
from os import environ from os import environ
from pathlib import Path from pathlib import Path
@ -6,7 +7,6 @@ from time import strftime, localtime, time
from PySide6.QtCore import Qt from PySide6.QtCore import Qt
from PySide6.QtWidgets import QApplication from PySide6.QtWidgets import QApplication
from func.Module_mainwindow import MainWindow from func.Module_mainwindow import MainWindow
import importlib.util
if __name__ == '__main__': if __name__ == '__main__':
# 设置日志 # 设置日志
@ -28,7 +28,7 @@ if __name__ == '__main__':
info("程序启动") info("程序启动")
# 解决 Could not find the Qt platform plugin "windows" # 解决 Could not find the Qt platform plugin "windows"
spec = importlib.util.find_spec("PySide6") spec = find_spec("PySide6")
if spec and spec.origin: if spec and spec.origin:
dirname = Path(spec.origin).parent dirname = Path(spec.origin).parent
plugin_path = dirname / 'plugins' / 'platforms' plugin_path = dirname / 'plugins' / 'platforms'