This commit is contained in:
zj
2026-02-03 04:49:37 +08:00
parent a351d75673
commit f17080b506
29 changed files with 21704 additions and 1671 deletions

View File

@@ -357,15 +357,16 @@ class CreateLvDialog(QDialog):
self.available_vgs = available_vgs if available_vgs is not None else []
self.vg_sizes = vg_sizes if vg_sizes is not None else {} # 存储每个 VG 的可用大小 (GB)
logger.debug(f"CreateLvDialog initialized. Available VGs: {self.available_vgs}, VG Sizes: {self.vg_sizes}")
self.lv_name_input = QLineEdit()
self.vg_combo_box = QComboBox()
self.lv_size_spinbox = QDoubleSpinBox()
self.use_max_space_checkbox = QCheckBox("使用最大可用空间") # 新增复选框
self.use_max_space_checkbox = QCheckBox("使用最大可用空间")
self._setup_ui()
self._connect_signals()
self._initialize_state() # 初始化状态
self._initialize_state()
def _setup_ui(self):
layout = QVBoxLayout(self)
@@ -374,7 +375,7 @@ class CreateLvDialog(QDialog):
form_layout.addRow("逻辑卷名称:", self.lv_name_input)
form_layout.addRow("选择卷组:", self.vg_combo_box)
form_layout.addRow("逻辑卷大小 (GB):", self.lv_size_spinbox)
form_layout.addRow("", self.use_max_space_checkbox) # 添加复选框
form_layout.addRow("", self.use_max_space_checkbox)
layout.addLayout(form_layout)
@@ -385,68 +386,75 @@ class CreateLvDialog(QDialog):
button_box.addWidget(self.cancel_button)
layout.addLayout(button_box)
self.lv_size_spinbox.setMinimum(0.1) # 逻辑卷最小大小,例如 0.1 GB
self.lv_size_spinbox.setMinimum(0.01) # 逻辑卷最小大小,例如 0.01 GB
self.lv_size_spinbox.setSuffix(" GB")
self.lv_size_spinbox.setDecimals(2)
# 设置一个较大的初始最大值,它将在 _update_size_options 中被实际的 VG 大小覆盖
self.lv_size_spinbox.setMaximum(100000.0) # 初始设置一个足够大的最大值
def _connect_signals(self):
self.confirm_button.clicked.connect(self.accept)
self.cancel_button.clicked.connect(self.reject)
self.vg_combo_box.currentIndexChanged.connect(self._update_size_options) # 卷组选择改变时更新大小选项
self.use_max_space_checkbox.stateChanged.connect(self._toggle_size_input) # 复选框状态改变时切换输入
self.vg_combo_box.currentIndexChanged.connect(self._update_size_options)
# 信号连接到不带参数的槽函数
self.use_max_space_checkbox.stateChanged.connect(self._toggle_size_input)
def _initialize_state(self):
self.vg_combo_box.addItems(self.available_vgs)
self._update_size_options() # 首次调用以设置初始状态
self.use_max_space_checkbox.setChecked(True) # 默认选中“使用最大可用空间”
# 默认选中“使用最大可用空间”,这将触发 _toggle_size_input
self.use_max_space_checkbox.setChecked(True)
# 首次调用以设置初始状态和根据复选框状态设置值
# 这一步是必要的,即使 setChecked(True) 也会触发一次 _toggle_size_input
# 但 _update_size_options 会在设置了正确的最大值后再次调用 _toggle_size_input确保最终状态正确。
self._update_size_options()
logger.debug("CreateLvDialog _initialize_state completed.")
def _update_size_options(self):
"""根据选中的卷组更新逻辑卷大小的选项。"""
"""
根据选中的卷组更新逻辑卷大小的范围 (最小值和最大值)。
并根据当前“使用最大可用空间”复选框的状态调整 spinbox 的值和启用状态。
"""
selected_vg = self.vg_combo_box.currentText()
max_size_gb = self.vg_sizes.get(selected_vg, 0.0)
logger.debug(f"[_update_size_options] Selected VG: {selected_vg}, Max available GB: {max_size_gb}")
# 确保 max_size_gb 至少是 spinbox 的最小值,以防卷组可用空间过小导致 UI 问题
current_min_limit = self.lv_size_spinbox.minimum() # 获取当前的最小值限制
if max_size_gb < current_min_limit:
# 如果实际最大可用空间小于当前最小值限制,则将最小值临时调整为实际最大值
self.lv_size_spinbox.setMinimum(max_size_gb if max_size_gb > 0 else 0.01) # 至少0.01GB
else:
self.lv_size_spinbox.setMinimum(0.1) # 恢复正常最小值
# 确保实际最大可用空间至少大于或等于 spinbox 的最小值
# 避免当可用空间非常小时spinbox 无法设置有效值
effective_max_size_gb = max(self.lv_size_spinbox.minimum(), max_size_gb)
self.lv_size_spinbox.setMaximum(effective_max_size_gb)
logger.debug(f"[_update_size_options] Spinbox max set to: {effective_max_size_gb} GB.")
# 计算并设置 spinbox 的最大值
clamped_max_gb = max(self.lv_size_spinbox.minimum(), max_size_gb)
self.lv_size_spinbox.setMaximum(clamped_max_gb)
# 在设置了新的最大值后,重新应用复选框的状态来更新值和启用状态
self._toggle_size_input() # 调用不带参数的槽函数
logger.debug("[_update_size_options] Completed.")
# 如果选中了“使用最大可用空间”,则将 spinbox 值设置为最大值
if self.use_max_space_checkbox.isChecked():
self.lv_size_spinbox.setValue(clamped_max_gb) # 使用计算出的最大值
else:
# 如果当前值超过了新的最大值,则调整为新的最大值
if self.lv_size_spinbox.value() > clamped_max_gb:
self.lv_size_spinbox.setValue(clamped_max_gb)
# 如果当前值小于新的最小值,则调整
elif self.lv_size_spinbox.value() < self.lv_size_spinbox.minimum():
self.lv_size_spinbox.setValue(self.lv_size_spinbox.minimum())
def _toggle_size_input(self): # 不再接收 'state' 参数
"""
根据“使用最大可用空间”复选框的状态切换大小输入框的启用/禁用状态和值。
"""
is_checked = self.use_max_space_checkbox.isChecked() # 直接查询复选框的当前状态
logger.debug(f"[_toggle_size_input] Called. Checkbox isChecked(): {is_checked}")
def _toggle_size_input(self, state):
"""根据“使用最大可用空间”复选框的状态切换大小输入框的启用/禁用状态。"""
# 获取当前选中的卷组的实际最大可用空间GB
selected_vg = self.vg_combo_box.currentText()
actual_max_gb = self.vg_sizes.get(selected_vg, 0.0)
# 确保计算出的最大值不小于spinbox的最小值
clamped_max_gb = max(self.lv_size_spinbox.minimum(), actual_max_gb)
if state == Qt.Checked:
self.lv_size_spinbox.setDisabled(True)
self.lv_size_spinbox.setValue(clamped_max_gb) # 使用计算出的最大值
else:
self.lv_size_spinbox.setDisabled(False)
# 如果之前是最大值,取消勾选后,恢复到最小值或一个合理值
if self.lv_size_spinbox.value() == clamped_max_gb: # 比较时也使用计算出的最大值
self.lv_size_spinbox.setValue(self.lv_size_spinbox.minimum())
# 否则,保持当前值(用户手动输入的值)
current_max_spinbox_value = self.lv_size_spinbox.maximum()
current_spinbox_value = self.lv_size_spinbox.value()
if is_checked:
logger.debug(f"[_toggle_size_input] Checkbox is CHECKED. Disabling spinbox and setting value to max.")
self.lv_size_spinbox.setDisabled(True) # 禁用 spinbox
self.lv_size_spinbox.setValue(current_max_spinbox_value) # 设置为最大可用 GB
logger.debug(f"[_toggle_size_input] Spinbox value set to max: {current_max_spinbox_value} GB.")
else: # is_checked is False
logger.debug(f"[_toggle_size_input] Checkbox is UNCHECKED. Enabling spinbox.")
self.lv_size_spinbox.setDisabled(False) # 启用 spinbox
# 如果之前是最大值(因为复选框被勾选),取消勾选后,恢复到最小值,方便用户输入自定义值
if current_spinbox_value == current_max_spinbox_value:
min_val = self.lv_size_spinbox.minimum()
self.lv_size_spinbox.setValue(min_val)
logger.debug(f"[_toggle_size_input] Spinbox was at max, reset to min: {min_val} GB.")
else:
logger.debug(f"[_toggle_size_input] Spinbox was not at max, keeping current value: {self.lv_size_spinbox.value()} GB.")
logger.debug("[_toggle_size_input] Completed.")
def get_lv_info(self):
lv_name = self.lv_name_input.text().strip()
@@ -460,13 +468,15 @@ class CreateLvDialog(QDialog):
if not vg_name:
QMessageBox.warning(self, "输入错误", "请选择一个卷组。")
return None
if not use_max_space and size_gb <= 0:
QMessageBox.warning(self, "输入错误", "逻辑卷大小必须大于0。")
return None
# 这里的检查应该使用 self.lv_size_spinbox.maximum() 来判断,因为它是实际的最大值
if not use_max_space and size_gb > self.lv_size_spinbox.maximum():
QMessageBox.warning(self, "输入错误", "逻辑卷大小不能超过卷组的可用空间。")
return None
# 如果没有使用最大空间,则检查输入大小的有效性
if not use_max_space:
if size_gb <= 0:
QMessageBox.warning(self, "输入错误", "逻辑卷大小必须大于0。")
return None
# 这里的检查应该使用 self.lv_size_spinbox.maximum() 来判断,因为它是实际的最大值
if size_gb > self.lv_size_spinbox.maximum():
QMessageBox.warning(self, "输入错误", "逻辑卷大小不能超过卷组的可用空间。")
return None
return {
'lv_name': lv_name,