Coverage for graphica/gui/builders/axis_panel.py: 99.4%

308 statements  

« prev     ^ index     » next       coverage.py v7.16.2, created at 2026-10-12 16:38 +0000

1"""軸の設定の欄(凡例の位置・目盛り・グリッド・カラーバー・目盛りの書式・タイトルと軸ラベル・ラベルのタブ)の組み立て。""" 

2from PySide6.QtCore import Qt 

3from PySide6.QtGui import QFont 

4from PySide6.QtWidgets import ( 

5 QCheckBox, QComboBox, QDoubleSpinBox, QFormLayout, QGroupBox, QHBoxLayout, QLabel, QLineEdit, QPushButton, 

6 QSizePolicy, QSpinBox, QToolButton, QVBoxLayout, QWidget) 

7from graphica.core.i18n import tr 

8from graphica.core.unit_conversion import X_AXIS_UNIT_CHOICES, X_AXIS_UNIT_LABELS 

9from graphica.gui.builders.common import ( 

10 _ClickableMathPreviewLabel, _insert_form_row_after, _svg_icon, cap_combo_width) 

11from graphica.gui.canvas import DEFAULT_MAJOR_TICK_LENGTH, MINOR_TICK_LENGTH_AUTO 

12from graphica.gui.tools.layout_edit import MIN_FREE_RECT_SIZE 

13 

14 

15def build_legend_location_control(app): 

16 app.legend_loc_label = QLabel("凡例の位置") 

17 app.legend_loc_combo = QComboBox() 

18 app.legend_loc_combo.addItems([ 

19 "best", "upper right", "upper left", "lower left", "lower right", "center" 

20 ]) 

21 _insert_form_row_after(app.ui.formLayout_3, app.ui.legend_visible_checkbox, 

22 app.legend_loc_label, app.legend_loc_combo) 

23 

24 app.legend_font_label = QLabel("凡例フォント") 

25 app.legend_font_button = QPushButton("フォント選択...") 

26 _insert_form_row_after(app.ui.formLayout_3, app.legend_loc_combo, 

27 app.legend_font_label, app.legend_font_button) 

28 

29 app.legend_color_label = QLabel("凡例 文字色") 

30 app.legend_color_button = QPushButton("色選択...") 

31 _insert_form_row_after(app.ui.formLayout_3, app.legend_font_button, 

32 app.legend_color_label, app.legend_color_button) 

33 

34 # 凡例の並びは描画順とは別に決められる 

35 app.legend_order_button = QPushButton("凡例の順序...") 

36 _insert_form_row_after(app.ui.formLayout_3, app.legend_color_button, app.legend_order_button) 

37 

38 # ダークモードの切り替えで作り直すので(_refresh_custom_svg_icons)、対応を持っておく 

39 app._field_icon_buttons = { 

40 app.ui.tick_font_button: "typography", 

41 app.ui.tick_color_button: "color-swatch", 

42 app.ui.axis_label_font_button: "typography", 

43 app.ui.axis_label_color_button: "color-swatch", 

44 app.ui.spine_color_button: "color-swatch", 

45 app.legend_font_button: "typography", 

46 app.legend_color_button: "color-swatch", 

47 } 

48 for button, icon_name in app._field_icon_buttons.items(): 

49 button.setIcon(_svg_icon(icon_name, size=16)) 

50 

51 

52def build_tick_grid_and_colorbar_controls(app): 

53 app.tick_direction_label = QLabel("主軸目盛(主/補助)") 

54 app.major_tick_direction_combo = QComboBox() 

55 app.major_tick_direction_combo.addItems(["out", "in", "inout"]) 

56 app.minor_tick_direction_combo = QComboBox() 

57 app.minor_tick_direction_combo.addItems(["out", "in", "inout"]) 

58 dir_layout = QHBoxLayout() 

59 dir_layout.addWidget(app.major_tick_direction_combo) 

60 dir_layout.addWidget(app.minor_tick_direction_combo) 

61 

62 app.tick_direction_y2_label = QLabel("第2軸目盛(主/補助)") 

63 app.major_tick_direction_y2_combo = QComboBox() 

64 app.major_tick_direction_y2_combo.addItems(["out", "in", "inout"]) 

65 app.minor_tick_direction_y2_combo = QComboBox() 

66 app.minor_tick_direction_y2_combo.addItems(["out", "in", "inout"]) 

67 dir_y2_layout = QHBoxLayout() 

68 dir_y2_layout.addWidget(app.major_tick_direction_y2_combo) 

69 dir_y2_layout.addWidget(app.minor_tick_direction_y2_combo) 

70 

71 _insert_form_row_after(app.ui.formLayout_3, app.ui.tick_format_label, app.tick_direction_label, dir_layout) 

72 _insert_form_row_after(app.ui.formLayout_3, app.tick_direction_label, app.tick_direction_y2_label, dir_y2_layout) 

73 

74 # グリッド線の線種・太さ・透明度(X/Y × 主/補助)。「補助グリッドの表示」のすぐ下に置く 

75 app.grid_linestyle_choices = [ 

76 (tr("実線"), '-'), (tr("破線"), '--'), (tr("点線"), ':'), (tr("一点鎖線"), '-.'), 

77 ] 

78 

79 def _make_grid_style_row(default_linestyle, default_width): 

80 linestyle_combo = QComboBox() 

81 for choice_label, _code in app.grid_linestyle_choices: 

82 linestyle_combo.addItem(choice_label) 

83 default_index = next( 

84 (i for i, (_label, code) in enumerate(app.grid_linestyle_choices) if code == default_linestyle), 

85 0 

86 ) 

87 linestyle_combo.setCurrentIndex(default_index) 

88 linestyle_combo.setToolTip(tr("線種")) 

89 linestyle_combo.setMaximumWidth(90) 

90 

91 width_spinbox = QDoubleSpinBox() 

92 width_spinbox.setRange(0.1, 10.0) 

93 width_spinbox.setSingleStep(0.1) 

94 width_spinbox.setDecimals(1) 

95 width_spinbox.setValue(default_width) 

96 width_spinbox.setToolTip(tr("太さ")) 

97 # これより狭いと矢印ボタンと重なって "10.0" のような値が見切れる 

98 width_spinbox.setMinimumWidth(60) 

99 width_spinbox.setMaximumWidth(78) 

100 

101 alpha_spinbox = QDoubleSpinBox() 

102 alpha_spinbox.setRange(0.0, 1.0) 

103 alpha_spinbox.setSingleStep(0.05) 

104 alpha_spinbox.setDecimals(2) 

105 alpha_spinbox.setValue(1.0) 

106 alpha_spinbox.setToolTip(tr("透過度(アルファ)")) 

107 alpha_spinbox.setMinimumWidth(60) 

108 alpha_spinbox.setMaximumWidth(78) 

109 

110 row_layout = QHBoxLayout() 

111 row_layout.addWidget(linestyle_combo) 

112 row_layout.addWidget(width_spinbox) 

113 row_layout.addWidget(alpha_spinbox) 

114 return linestyle_combo, width_spinbox, alpha_spinbox, row_layout 

115 

116 (app.x_major_grid_linestyle_combo, app.x_major_grid_width_spinbox, 

117 app.x_major_grid_alpha_spinbox, x_major_grid_layout) = _make_grid_style_row('-', 0.8) 

118 (app.x_minor_grid_linestyle_combo, app.x_minor_grid_width_spinbox, 

119 app.x_minor_grid_alpha_spinbox, x_minor_grid_layout) = _make_grid_style_row('--', 0.5) 

120 (app.y_major_grid_linestyle_combo, app.y_major_grid_width_spinbox, 

121 app.y_major_grid_alpha_spinbox, y_major_grid_layout) = _make_grid_style_row('-', 0.8) 

122 (app.y_minor_grid_linestyle_combo, app.y_minor_grid_width_spinbox, 

123 app.y_minor_grid_alpha_spinbox, y_minor_grid_layout) = _make_grid_style_row('--', 0.5) 

124 

125 app.x_major_grid_style_label = QLabel(tr("X軸主目盛")) 

126 app.x_minor_grid_style_label = QLabel(tr("X軸補助目盛")) 

127 app.y_major_grid_style_label = QLabel(tr("Y軸主目盛")) 

128 app.y_minor_grid_style_label = QLabel(tr("Y軸補助目盛")) 

129 

130 _grid_style_anchor = app.ui.minor_grid_visible_checkbox 

131 for _grid_style_label, _grid_style_layout in ( 

132 (app.x_major_grid_style_label, x_major_grid_layout), 

133 (app.x_minor_grid_style_label, x_minor_grid_layout), 

134 (app.y_major_grid_style_label, y_major_grid_layout), 

135 (app.y_minor_grid_style_label, y_minor_grid_layout), 

136 ): 

137 _insert_form_row_after(app.ui.formLayout_3, _grid_style_anchor, _grid_style_label, _grid_style_layout) 

138 _grid_style_anchor = _grid_style_label 

139 

140 # 目盛線の長さ(pt)。「目盛の太さ」の直後。補助目盛の最小値(-0.5)は「自動」(主目盛 × MINOR_TICK_LENGTH_RATIO) 

141 app.tick_length_label = QLabel(tr("目盛の長さ(主/補助)")) 

142 app.major_tick_length_spinbox = QDoubleSpinBox() 

143 app.major_tick_length_spinbox.setRange(0.0, 20.0) 

144 app.major_tick_length_spinbox.setSingleStep(0.5) 

145 app.major_tick_length_spinbox.setDecimals(1) 

146 app.major_tick_length_spinbox.setSuffix(" pt") 

147 app.major_tick_length_spinbox.setValue(DEFAULT_MAJOR_TICK_LENGTH) 

148 app.major_tick_length_spinbox.setToolTip(tr("主目盛の線の長さ(pt)")) 

149 app.minor_tick_length_spinbox = QDoubleSpinBox() 

150 app.minor_tick_length_spinbox.setRange(MINOR_TICK_LENGTH_AUTO, 20.0) 

151 app.minor_tick_length_spinbox.setSingleStep(0.5) 

152 app.minor_tick_length_spinbox.setDecimals(1) 

153 app.minor_tick_length_spinbox.setSuffix(" pt") 

154 app.minor_tick_length_spinbox.setSpecialValueText(tr("自動")) 

155 app.minor_tick_length_spinbox.setValue(MINOR_TICK_LENGTH_AUTO) 

156 app.minor_tick_length_spinbox.setToolTip( 

157 tr("補助目盛の線の長さ(pt)。「自動」は主目盛の長さの約0.57倍")) 

158 # QDoubleSpinBox を2つ並べると最小幅が約306pxになり、フォームの列幅を広げてドックに横スクロールが出る 

159 # (tests/test_main_window.py が検出)。すぐ上の目盛方向の欄と同じ幅に揃える 

160 for _tick_length_spin in (app.major_tick_length_spinbox, app.minor_tick_length_spinbox): 

161 # 「自動 pt」が切れない幅は確保する(幅 340px のインスペクタでも2つ並ぶ) 

162 _tick_length_spin.setMinimumWidth(max(app.major_tick_direction_combo.minimumSizeHint().width(), 78)) 

163 tick_length_layout = QHBoxLayout() 

164 tick_length_layout.addWidget(app.major_tick_length_spinbox) 

165 tick_length_layout.addWidget(app.minor_tick_length_spinbox) 

166 _insert_form_row_after(app.ui.formLayout_3, app.ui.tick_width_spinbox, 

167 app.tick_length_label, tick_length_layout) 

168 

169 # カラーバーは2Dマップ(か値で色分けした散布図)がある軸でだけ効く 

170 app.colorbar_enabled_checkbox = QCheckBox(tr("カラーバーを表示")) 

171 app.colorbar_enabled_checkbox.setChecked(True) 

172 app.ui.formLayout_3.addRow(app.colorbar_enabled_checkbox) 

173 

174 app.colorbar_position_label = QLabel(tr("カラーバーの位置")) 

175 app.colorbar_position_combo = QComboBox() 

176 app.colorbar_position_combo.addItem(tr("右"), "right") 

177 app.colorbar_position_combo.addItem(tr("左"), "left") 

178 app.colorbar_position_combo.addItem(tr("上"), "top") 

179 app.colorbar_position_combo.addItem(tr("下"), "bottom") 

180 app.ui.formLayout_3.addRow(app.colorbar_position_label, app.colorbar_position_combo) 

181 

182 app.colorbar_width_label = QLabel(tr("カラーバーの幅(割合)")) 

183 app.colorbar_width_spinbox = QDoubleSpinBox() 

184 app.colorbar_width_spinbox.setRange(0.01, 0.5) 

185 app.colorbar_width_spinbox.setSingleStep(0.01) 

186 app.colorbar_width_spinbox.setDecimals(2) 

187 app.colorbar_width_spinbox.setValue(0.05) 

188 app.ui.formLayout_3.addRow(app.colorbar_width_label, app.colorbar_width_spinbox) 

189 

190 app.colorbar_label_label = QLabel(tr("カラーバーのラベル")) 

191 app.colorbar_label_edit = QLineEdit() 

192 app.ui.formLayout_3.addRow(app.colorbar_label_label, app.colorbar_label_edit) 

193 

194 

195def build_tick_format_controls(app): 

196 tick_format_choices = [ 

197 tr("自動"), 

198 tr("軸端にまとめて指数表記 (×10ⁿ)"), 

199 tr("目盛りごとに指数表記 (例: 1.0×10¹⁰)"), 

200 tr("常に小数表記"), 

201 ] 

202 app.x_tick_format_label = QLabel(tr("目盛り表記")) 

203 app.x_tick_format_combo = QComboBox() 

204 app.x_tick_format_combo.addItems(tick_format_choices) 

205 cap_combo_width(app.x_tick_format_combo) 

206 app.ui.formLayout.addRow(app.x_tick_format_label, app.x_tick_format_combo) 

207 

208 # 目盛線と目盛数値の表示は X/Y で別々なので、それぞれの軸のタブに置く 

209 app.x_ticks_visible_checkbox = QCheckBox(tr("目盛を表示")) 

210 app.x_ticks_visible_checkbox.setChecked(True) 

211 app.ui.formLayout.addRow(app.x_ticks_visible_checkbox) 

212 app.x_tick_labels_visible_checkbox = QCheckBox(tr("目盛の数値を表示")) 

213 app.x_tick_labels_visible_checkbox.setChecked(True) 

214 app.ui.formLayout.addRow(app.x_tick_labels_visible_checkbox) 

215 

216 # 目盛数値の小数点以下の桁数。-1(最小値)は「自動」で、指数表記の設定に任せる 

217 app.x_tick_decimals_spinbox = QSpinBox() 

218 app.x_tick_decimals_spinbox.setRange(-1, 10) 

219 app.x_tick_decimals_spinbox.setSpecialValueText(tr("自動")) 

220 app.x_tick_decimals_spinbox.setValue(-1) 

221 app.x_tick_decimals_spinbox.setToolTip( 

222 tr("目盛りの数値を表示する小数点以下の桁数(「自動」以外を選ぶと指数表記モードより優先されます)")) 

223 app.ui.formLayout.addRow(QLabel(tr("小数桁数")), app.x_tick_decimals_spinbox) 

224 

225 # 対数軸で補助目盛を出すときだけ使う(出し入れは _on_x_minor_tick_visibility_changed)。 

226 # ラベルの列幅は X/Y のタブで揃えるので、長いと両方の入力欄が狭まる。説明はツールチップに回す 

227 app.x_log_minor_subs_label = QLabel(tr("対数補助目盛")) 

228 app.x_log_minor_subs_label.setToolTip(tr("対数軸の補助目盛りをどこに打つか")) 

229 app.x_log_minor_subs_combo = QComboBox() 

230 app.x_log_minor_subs_combo.addItem(tr("自動(既定)"), "auto") 

231 app.x_log_minor_subs_combo.addItem(tr("全て(2〜9)"), "all") 

232 app.x_log_minor_subs_combo.addItem(tr("少なめ(2, 5)"), "few") 

233 app.x_log_minor_subs_combo.addItem(tr("最小限(5)"), "one") 

234 app.ui.formLayout.addRow(app.x_log_minor_subs_label, app.x_log_minor_subs_combo) 

235 app.x_log_minor_labels_checkbox = QCheckBox(tr("補助目盛りに数値ラベルを表示")) 

236 app.ui.formLayout.addRow(app.x_log_minor_labels_checkbox) 

237 app.x_log_minor_subs_label.setVisible(False) 

238 app.x_log_minor_subs_combo.setVisible(False) 

239 app.x_log_minor_labels_checkbox.setVisible(False) 

240 # 対数軸で表示されない 0 以下の値を知らせる(中身は log_axis_notes.update_log_axis_notes) 

241 app.x_log_note = _log_note_label("x_log_note") 

242 _insert_form_row_after(app.ui.formLayout, app.ui.x_log_checkbox, app.x_log_note) 

243 

244 # X の単位と上に出したい単位が別々に選ばれていれば、単位を変換した第2X軸を上に付ける。 

245 # ラベルは短く保つ(フォームの全行でラベルの列幅を共有するので、長いとドックに横スクロールが出る。 

246 # test_properties_dock_has_no_horizontal_scrollbar)。説明はツールチップに置く 

247 # 選んだ番号で値を持つ(choice の束ね)ので、表示だけを訳してよい 

248 unit_combo_choices = [tr(X_AXIS_UNIT_LABELS[u]) for u in X_AXIS_UNIT_CHOICES] 

249 app.x_secondary_axis_source_unit_label = QLabel(tr("X軸単位")) 

250 app.x_secondary_axis_source_unit_combo = QComboBox() 

251 app.x_secondary_axis_source_unit_combo.addItems(unit_combo_choices) 

252 app.x_secondary_axis_source_unit_combo.setToolTip(tr("X軸データが表している物理量の単位")) 

253 app.ui.formLayout.addRow( 

254 app.x_secondary_axis_source_unit_label, app.x_secondary_axis_source_unit_combo) 

255 

256 app.x_secondary_axis_target_unit_label = QLabel(tr("第2X軸単位")) 

257 app.x_secondary_axis_target_unit_combo = QComboBox() 

258 app.x_secondary_axis_target_unit_combo.addItems(unit_combo_choices) 

259 app.x_secondary_axis_target_unit_combo.setToolTip(tr("上部に追加する第2X軸に変換して表示する単位")) 

260 app.ui.formLayout.addRow( 

261 app.x_secondary_axis_target_unit_label, app.x_secondary_axis_target_unit_combo) 

262 

263 app.y_tick_format_label = QLabel(tr("目盛り表記")) 

264 app.y_tick_format_combo = QComboBox() 

265 app.y_tick_format_combo.addItems(tick_format_choices) 

266 cap_combo_width(app.y_tick_format_combo) 

267 app.ui.formLayout_2.addRow(app.y_tick_format_label, app.y_tick_format_combo) 

268 

269 app.y_ticks_visible_checkbox = QCheckBox(tr("目盛を表示")) 

270 app.y_ticks_visible_checkbox.setChecked(True) 

271 app.ui.formLayout_2.addRow(app.y_ticks_visible_checkbox) 

272 app.y_tick_labels_visible_checkbox = QCheckBox(tr("目盛の数値を表示")) 

273 app.y_tick_labels_visible_checkbox.setChecked(True) 

274 app.ui.formLayout_2.addRow(app.y_tick_labels_visible_checkbox) 

275 

276 app.y_tick_decimals_spinbox = QSpinBox() 

277 app.y_tick_decimals_spinbox.setRange(-1, 10) 

278 app.y_tick_decimals_spinbox.setSpecialValueText(tr("自動")) 

279 app.y_tick_decimals_spinbox.setValue(-1) 

280 app.y_tick_decimals_spinbox.setToolTip( 

281 tr("目盛りの数値を表示する小数点以下の桁数(「自動」以外を選ぶと指数表記モードより優先されます)")) 

282 app.ui.formLayout_2.addRow(QLabel(tr("小数桁数")), app.y_tick_decimals_spinbox) 

283 

284 # X 軸と同じく、ラベルは短くして説明はツールチップへ 

285 app.y_log_minor_subs_label = QLabel(tr("対数補助目盛")) 

286 app.y_log_minor_subs_label.setToolTip(tr("対数軸の補助目盛りをどこに打つか")) 

287 app.y_log_minor_subs_combo = QComboBox() 

288 app.y_log_minor_subs_combo.addItem(tr("自動(既定)"), "auto") 

289 app.y_log_minor_subs_combo.addItem(tr("全て(2〜9)"), "all") 

290 app.y_log_minor_subs_combo.addItem(tr("少なめ(2, 5)"), "few") 

291 app.y_log_minor_subs_combo.addItem(tr("最小限(5)"), "one") 

292 app.ui.formLayout_2.addRow(app.y_log_minor_subs_label, app.y_log_minor_subs_combo) 

293 app.y_log_minor_labels_checkbox = QCheckBox(tr("補助目盛りに数値ラベルを表示")) 

294 app.ui.formLayout_2.addRow(app.y_log_minor_labels_checkbox) 

295 app.y_log_minor_subs_label.setVisible(False) 

296 app.y_log_minor_subs_combo.setVisible(False) 

297 app.y_log_minor_labels_checkbox.setVisible(False) 

298 app.y_log_note = _log_note_label("y_log_note") 

299 _insert_form_row_after(app.ui.formLayout_2, app.ui.y_log_checkbox, app.y_log_note) 

300 

301 

302def _log_note_label(name): 

303 label = QLabel() 

304 label.setObjectName(name) 

305 label.setWordWrap(True) 

306 label.setVisible(False) 

307 return label 

308 

309 

310def build_label_editors(app): 

311 # タイトルと軸ラベルは、mathtext を描いたプレビューに差し替え、クリックで編集ダイアログを開く。 

312 # 元の QLineEdit は値の置き場と textChanged の発信元として、見えないまま残す 

313 app._label_preview_widgets = [] # [(preview_label, line_edit, placeholder), ...] 

314 for field_key, line_edit, dialog_title, placeholder in ( 

315 ('title', app.ui.title_text_edit, tr("タイトルを編集"), tr("タイトルを入力")), 

316 ('x_label', app.ui.x_label_text_edit, tr("X軸ラベルを編集"), tr("X軸ラベルを入力")), 

317 ('y_label', app.ui.y_label_text_edit, tr("Y軸ラベルを編集"), tr("Y軸ラベルを入力")), 

318 ): 

319 wrapper = QWidget() 

320 wrapper_layout = QHBoxLayout(wrapper) 

321 wrapper_layout.setContentsMargins(0, 0, 0, 0) 

322 wrapper_layout.setSpacing(4) 

323 

324 # 同じ位置に差し替える(行の位置がずれない) 

325 app.ui.formLayout_3.replaceWidget(line_edit, wrapper) 

326 # レイアウトには入れない(隠れていても余白の計算に関わることがある)。親を wrapper にするだけ 

327 line_edit.setParent(wrapper) 

328 line_edit.hide() 

329 

330 preview_label = _ClickableMathPreviewLabel(wrapper) 

331 wrapper_layout.addWidget(preview_label, 1) 

332 preview_label.clicked.connect( 

333 lambda le=line_edit, dt=dialog_title: app._open_label_edit_dialog(le, dt) 

334 ) 

335 app._label_preview_widgets.append((preview_label, line_edit, placeholder)) 

336 line_edit.textChanged.connect( 

337 lambda text, lbl=preview_label, ph=placeholder: 

338 app._refresh_label_preview(lbl, text, ph) 

339 ) 

340 app._refresh_label_preview(preview_label, line_edit.text(), placeholder) 

341 

342 # 軸ラベルだけ、文字を残したまま隠せる(タイトルには付けない) 

343 if field_key in ('x_label', 'y_label'): 

344 visible_checkbox = QCheckBox() 

345 visible_checkbox.setChecked(True) 

346 visible_checkbox.setToolTip(tr("ラベルの表示/非表示(テキスト自体は保持されます)")) 

347 wrapper_layout.addWidget(visible_checkbox) 

348 setattr(app, f'{field_key}_visible_checkbox', visible_checkbox) 

349 

350 format_button = QToolButton() 

351 format_button.setText("Aa") 

352 format_button.setToolTip(tr("タイトル/ラベルを編集(書式・記号入力)")) 

353 format_button.setFocusPolicy(Qt.FocusPolicy.NoFocus) 

354 # パネルの幅が狭いので、ボタンは小さくして欄の幅を取らない 

355 format_button.setFixedSize(26, 22) 

356 small_font = QFont(format_button.font()) 

357 small_font.setPointSize(max(7, small_font.pointSize() - 2)) 

358 format_button.setFont(small_font) 

359 wrapper_layout.addWidget(format_button) 

360 format_button.clicked.connect( 

361 lambda checked=False, le=line_edit, dt=dialog_title: 

362 app._open_label_edit_dialog(le, dt) 

363 ) 

364 

365 

366def rebuild_label_tab(app): 

367 # 「ラベル/書式」タブの先頭に、グラフ全体のレイアウトと編集対象の軸の欄を入れる 

368 layout_group = QGroupBox(tr("グラフ全体レイアウト")) 

369 layout_form = QFormLayout() 

370 sizePolicy = layout_group.sizePolicy() 

371 sizePolicy.setVerticalPolicy(QSizePolicy.Policy.Fixed) 

372 layout_group.setSizePolicy(sizePolicy) 

373 app.subplot_rows_spinbox = QSpinBox() 

374 app.subplot_rows_spinbox.setRange(1, 10) 

375 app.subplot_rows_spinbox.setValue(1) 

376 app.subplot_cols_spinbox = QSpinBox() 

377 app.subplot_cols_spinbox.setRange(1, 10) 

378 app.subplot_cols_spinbox.setValue(1) 

379 layout_form.addRow(tr("行数"), app.subplot_rows_spinbox) 

380 layout_form.addRow(tr("列数"), app.subplot_cols_spinbox) 

381 

382 # 軸の共有は自由配置では意味が無いので、_on_toggle_free_layout で有効/無効を合わせる 

383 app.share_x_checkbox = QCheckBox(tr("X軸を共有(グリッドレイアウト時)")) 

384 app.share_y_checkbox = QCheckBox(tr("Y軸を共有(グリッドレイアウト時)")) 

385 layout_form.addRow(app.share_x_checkbox) 

386 layout_form.addRow(app.share_y_checkbox) 

387 

388 app.free_layout_checkbox = QCheckBox(tr("自由配置レイアウト(ドラッグで配置)")) 

389 layout_form.addRow(app.free_layout_checkbox) 

390 

391 free_layout_button_row = QHBoxLayout() 

392 app.add_free_subplot_button = QPushButton(tr("+ プロット追加")) 

393 app.remove_free_subplot_button = QPushButton(tr("- プロット削除")) 

394 app.add_free_subplot_button.setEnabled(False) 

395 app.remove_free_subplot_button.setEnabled(False) 

396 free_layout_button_row.addWidget(app.add_free_subplot_button) 

397 free_layout_button_row.addWidget(app.remove_free_subplot_button) 

398 layout_form.addRow(free_layout_button_row) 

399 

400 # 自由配置で選んだ軸の位置と大きさを数値でも入れられる。値は Figure に対する割合(ax.set_position と同じ)で、 

401 # ドラッグと同じく少しなら範囲外も許す 

402 app.free_layout_position_group = QGroupBox(tr("選択中のサブプロットの位置・サイズ")) 

403 free_layout_position_form = QFormLayout() 

404 app.free_layout_x_spinbox = QDoubleSpinBox() 

405 app.free_layout_y_spinbox = QDoubleSpinBox() 

406 app.free_layout_width_spinbox = QDoubleSpinBox() 

407 app.free_layout_height_spinbox = QDoubleSpinBox() 

408 for spinbox in (app.free_layout_x_spinbox, app.free_layout_y_spinbox): 

409 spinbox.setRange(-1.0, 2.0) 

410 spinbox.setDecimals(3) 

411 spinbox.setSingleStep(0.01) 

412 for spinbox in (app.free_layout_width_spinbox, app.free_layout_height_spinbox): 

413 spinbox.setRange(MIN_FREE_RECT_SIZE, 2.0) 

414 spinbox.setDecimals(3) 

415 spinbox.setSingleStep(0.01) 

416 free_layout_position_form.addRow(tr("X"), app.free_layout_x_spinbox) 

417 free_layout_position_form.addRow(tr("Y"), app.free_layout_y_spinbox) 

418 free_layout_position_form.addRow(tr("幅"), app.free_layout_width_spinbox) 

419 free_layout_position_form.addRow(tr("高さ"), app.free_layout_height_spinbox) 

420 app.free_layout_position_group.setLayout(free_layout_position_form) 

421 # 自由配置モードで、かつサブプロットが選択されている間だけ表示する 

422 app.free_layout_position_group.setVisible(False) 

423 layout_form.addRow(app.free_layout_position_group) 

424 

425 layout_group.setLayout(layout_form) 

426 

427 active_axis_group = QGroupBox(tr("編集対象のプロット")) 

428 active_axis_layout = QVBoxLayout() 

429 sizePolicy = active_axis_group.sizePolicy() 

430 sizePolicy.setVerticalPolicy(QSizePolicy.Policy.Fixed) 

431 active_axis_group.setSizePolicy(sizePolicy) 

432 app.active_axis_combo = QComboBox() 

433 active_axis_layout.addWidget(app.active_axis_combo) 

434 active_axis_group.setLayout(active_axis_layout) 

435 

436 grid_layout = app.ui.tab_3.layout() # QGridLayout 

437 

438 # 既存の formLayout_3 を (0, 0) から外し、新しい2つの下(2行目)に入れ直す 

439 existing_layout_item = grid_layout.itemAtPosition(0, 0) 

440 

441 if existing_layout_item: 441 ↛ 444line 441 didn't jump to line 444 because the condition on line 441 was always true

442 grid_layout.removeItem(existing_layout_item) 

443 

444 grid_layout.addWidget(layout_group, 0, 0) 

445 grid_layout.addWidget(active_axis_group, 1, 0) 

446 

447 if existing_layout_item: 447 ↛ exitline 447 didn't return from function 'rebuild_label_tab' because the condition on line 447 was always true

448 grid_layout.addItem(existing_layout_item, 2, 0)