1 from typing import Callable, Dict, List

2

3 from qgis.PyQt.QtWidgets import QDialog, QFileDialog, QLineEdit, QPushButton

4

5 from grm.lib.Util import MsError, MsInfo

6 from grm.ui.UI_climate_data import Ui_Dialog

7

8

9 class ClimateDataDialog(QDialog):

10 def __init__(self, xmltodict={"GRMProject": {"ProjectSettings": {}}}, parent=None):

11 super(ClimateDataDialog, self).__init__(parent)

12 self.ui = Ui_Dialog()

13 self.ui.setupUi(self)

14

15 # 얕은 복사. 해당 값은 주의깊게 사용해야 한다.

16 self.__xmltodict = xmltodict

17

18 self.attr_value_dict = {}

19 self.__require_attr_list = [

20 "PrecipitationDataFile",

21 "PrecipitationInterval_min",

22 ]

23 self.__set_xml_to_attr()

24 self.__set_initial_value()

25 self.__set_btn_browse_event()

26 self.__set_spb_event()

27

28 self.ui.btnCancel.clicked.connect(self.close)

29 self.ui.btnOK.clicked.connect(self.__btn_ok_clicked)

30

31 def __error_handler_decorator(func: Callable) -> Callable:

32 def wrapper(self, *args, **kwargs):

33 try:

34 func(self, *args, **kwargs)

35 except Exception as e:

36 return MsError(e, self)

37

38 return wrapper

39

40 def __set_xml_to_attr(self):

41 """

42 xml에 있는 값들을 클래스 내의 attr_value_dict에 저장한다.

43 """

44

45 attr_list = [

46 "PrecipitationDataFile",

47 "PrecipitationInterval_min",

48 "TemperatureMaxDataFile",

49 "TemperatureMaxInterval_min",

50 "TemperatureMinDataFile",

51 "TemperatureMinInterval_min",

52 "DaytimeLengthDataFile",

53 "DaytimeLengthInterval_min",

54 "DaytimeHoursRatioDataFile",

55 "SolarRadiationDataFile",

56 "SolarRadiationInterval_min",

57 "SnowPackTemperatureDataFile",

58 "SnowPackTemperatureInterval_min",

59 ]

60

61 for attr in attr_list:

62 if self.__xmltodict["GRMProject"]["ProjectSettings"].get(attr):

63 self.attr_value_dict[attr] = self.__xmltodict["GRMProject"][

64 "ProjectSettings"

65 ][attr]

66 else:

67 self.attr_value_dict[attr] = None

68

69 def __set_initial_value(self):

70 for attr in self.attr_value_dict.keys():

71 attr_value = self.attr_value_dict.get(attr)

72 if attr_value:

73 if attr.endswith("_min"):

74 getattr(self.ui, f"spb_{attr}").setValue(int(attr_value))

75 elif attr.endswith("File"):

76 getattr(self.ui, f"path_{attr}").setText(attr_value)

77

78 def __set_btn_browse_event(self) -> None:

79 load_list: List[str] = [

80 string.split("load_btn_")[1]

81 for string in dir(self.ui)

82 if string.startswith("load_btn_")

83 ]

84 btn_line_edit_dict: Dict[QPushButton, QLineEdit] = {

85 getattr(self.ui, f"load_btn_{load}"): getattr(self.ui, f"path_{load}")

86 for load in load_list

87 }

88

89 for btn, line_edit in btn_line_edit_dict.items():

90 btn.clicked.connect(self.__btn_click_browse(line_edit))

91

92 def __btn_click_browse(self, line_edit: QLineEdit) -> Callable:

93 def browse():

94 file_path = QFileDialog.getOpenFileName(self, "Select file")[0]

95 line_edit.setText(file_path)

96 self.attr_value_dict[line_edit.objectName().split("path_")[1]] = file_path

97

98 return browse

99

100 def __set_spb_event(self) -> None:

101 spb_list: List[str] = [

102 string.split("spb_")[1]

103 for string in dir(self.ui)

104 if string.startswith("spb_")

105 ]

106 for spb in spb_list:

107 getattr(self.ui, f"spb_{spb}").valueChanged.connect(

108 self.__spb_value_changed(spb)

109 )

110

111 def __spb_value_changed(self, attr: str) -> Callable:

112 def value_changed():

113 self.attr_value_dict[attr] = getattr(self.ui, f"spb_{attr}").value()

114

115 return value_changed

116

117 @__error_handler_decorator

118 def __btn_ok_clicked(self, _: bool) -> None:

119 for attr in self.__require_attr_list:

120 if not self.attr_value_dict.get(attr):

121 raise Exception(f"해당 속성 값이 필요합니다. : '{attr}'")

122

123 for attr in self.attr_value_dict.keys():

124 if (

125 self.attr_value_dict.get(attr)

126 and attr in self.__xmltodict["GRMProject"]["ProjectSettings"].keys()

127 ):

128 self.__xmltodict["GRMProject"]["ProjectSettings"][

129 attr

130 ] = self.attr_value_dict.get(attr)

131

132 MsInfo("Climate Data setup is completed. ")

133 self.close()

134

135

136 if __name__ == "__main__":

137 import os

138

139 from grm.lib.Util import MsTitle

140

141 os.environ[

142 "QT_QPA_PLATFORM_PLUGIN_PATH"

143 ] = r"C:\Program Files\QGIS 3.10\apps\Qt5\plugins"

144 import sys

145

146 from qgis.PyQt.QtWidgets import QApplication

147

148 MsTitle("ClimateDataDialog")

149 app = QApplication(sys.argv)

150 ui = ClimateDataDialog(

151 {

152 "GRMProject": {

153 "ProjectSettings": {

154 "PrecipitationDataFile": "",

155 "PrecipitationInterval_min": "",

156 "TemperatureMaxDataFile": "",

157 "TemperatureMaxInterval_min": "",

158 "TemperatureMinDataFile": "",

159 "TemperatureMinInterval_min": "",

160 "DaytimeLengthDataFile": "",

161 "DaytimeLengthInterval_min": "",

162 "DaytimeHoursRatioDataFile": "",

163 "SolarRadiationDataFile": "",

164 "SolarRadiationInterval_min": "",

165 "SnowPackTemperatureDataFile": "",

166 "SnowPackTemperatureInterval_min": "",

167 }

168 }

169 }

170 )

171 ui.show()

172 sys.exit(app.exec_())