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
« 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
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)
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)
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)
34 # 凡例の並びは描画順とは別に決められる
35 app.legend_order_button = QPushButton("凡例の順序...")
36 _insert_form_row_after(app.ui.formLayout_3, app.legend_color_button, app.legend_order_button)
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))
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)
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)
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)
74 # グリッド線の線種・太さ・透明度(X/Y × 主/補助)。「補助グリッドの表示」のすぐ下に置く
75 app.grid_linestyle_choices = [
76 (tr("実線"), '-'), (tr("破線"), '--'), (tr("点線"), ':'), (tr("一点鎖線"), '-.'),
77 ]
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)
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)
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)
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
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)
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軸補助目盛"))
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
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
302def _log_note_label(name):
303 label = QLabel()
304 label.setObjectName(name)
305 label.setWordWrap(True)
306 label.setVisible(False)
307 return label
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)
324 # 同じ位置に差し替える(行の位置がずれない)
325 app.ui.formLayout_3.replaceWidget(line_edit, wrapper)
326 # レイアウトには入れない(隠れていても余白の計算に関わることがある)。親を wrapper にするだけ
327 line_edit.setParent(wrapper)
328 line_edit.hide()
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)
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)
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 )
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)
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)
388 app.free_layout_checkbox = QCheckBox(tr("自由配置レイアウト(ドラッグで配置)"))
389 layout_form.addRow(app.free_layout_checkbox)
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)
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)
425 layout_group.setLayout(layout_form)
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)
436 grid_layout = app.ui.tab_3.layout() # QGridLayout
438 # 既存の formLayout_3 を (0, 0) から外し、新しい2つの下(2行目)に入れ直す
439 existing_layout_item = grid_layout.itemAtPosition(0, 0)
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)
444 grid_layout.addWidget(layout_group, 0, 0)
445 grid_layout.addWidget(active_axis_group, 1, 0)
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)