update
This commit is contained in:
@@ -79,15 +79,13 @@ class BaseUI(object):
|
||||
def create_connections(self):
|
||||
"""连接UI信号和槽"""
|
||||
pass
|
||||
|
||||
def showEvent(self, event):
|
||||
"""显示事件处理函数"""
|
||||
# 调用父类的showEvent方法
|
||||
super(BaseUI, self).showEvent(event)
|
||||
|
||||
# 强制设置分割器均等大小
|
||||
if hasattr(self, 'splitters') and 'main_splitter' in self.splitters:
|
||||
setup_splitter(self, 'main_splitter', equal_sizes=True)
|
||||
def update_language(self):
|
||||
"""
|
||||
更新所有UI文本到当前语言
|
||||
"""
|
||||
if self.main_widget:
|
||||
update_ui_texts(self.main_widget)
|
||||
|
||||
#============================================ UI HELPERS ==========================================
|
||||
def connect_ui_signals(ui_instance, signal_mapping):
|
||||
@@ -222,247 +220,78 @@ def load_icon(icon_name):
|
||||
return QtGui.QIcon()
|
||||
|
||||
#============================================ SPLITTER ==========================================
|
||||
def create_splitter(orientation=QtCore.Qt.Horizontal, parent=None):
|
||||
def set_splitter_proportions(splitter, proportions):
|
||||
"""
|
||||
创建一个QSplitter对象,并设置基本属性
|
||||
设置分割器各部分的比例
|
||||
|
||||
Args:
|
||||
orientation: 分割器方向,默认水平
|
||||
parent: 父窗口对象
|
||||
|
||||
Returns:
|
||||
QtWidgets.QSplitter: 创建的分割器对象
|
||||
splitter: 要设置的分割器
|
||||
proportions: 比例列表,如 [0.3, 0.7] 表示左侧占30%,右侧占70%
|
||||
"""
|
||||
splitter = QtWidgets.QSplitter(orientation, parent)
|
||||
splitter.setOpaqueResize(True) # 拖动时实时显示
|
||||
splitter.setChildrenCollapsible(False) # 防止子部件被完全折叠
|
||||
splitter.setHandleWidth(2) # 设置分割条宽度
|
||||
return splitter
|
||||
|
||||
def setup_splitter(ui_instance, splitter_name="main_splitter", equal_sizes=True):
|
||||
"""
|
||||
设置分割器的属性和大小,确保完全自由调整
|
||||
|
||||
Args:
|
||||
ui_instance: UI实例对象
|
||||
splitter_name (str): 分割器名称
|
||||
equal_sizes (bool): 是否设置均等大小
|
||||
|
||||
Returns:
|
||||
bool: 是否成功设置
|
||||
"""
|
||||
# 检查分割器是否存在
|
||||
if not hasattr(ui_instance, 'splitters') or splitter_name not in ui_instance.splitters:
|
||||
print(f"分割器 '{splitter_name}' 不存在")
|
||||
return False
|
||||
|
||||
# 获取分割器
|
||||
splitter = ui_instance.splitters[splitter_name]
|
||||
if not isinstance(splitter, QtWidgets.QSplitter):
|
||||
print(f"对象 '{splitter_name}' 不是QSplitter类型")
|
||||
return False
|
||||
|
||||
# 设置分割器属性
|
||||
splitter.setOpaqueResize(True) # 拖动时实时显示
|
||||
splitter.setChildrenCollapsible(False) # 防止子部件被完全折叠
|
||||
splitter.setHandleWidth(2) # 设置分割条宽度
|
||||
|
||||
# 设置子部件属性
|
||||
for i in range(splitter.count()):
|
||||
# 设置伸缩因子 - 所有子部件使用相同的伸缩因子
|
||||
splitter.setStretchFactor(i, 1)
|
||||
|
||||
# 设置子部件属性
|
||||
widget = splitter.widget(i)
|
||||
if widget:
|
||||
# 确保子部件可以自由调整大小
|
||||
widget.setMinimumWidth(10) # 设置最小宽度而不是0,防止完全消失
|
||||
widget.setMinimumHeight(10) # 设置最小高度而不是0,防止完全消失
|
||||
widget.setSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
|
||||
|
||||
# 设置均等大小
|
||||
if equal_sizes and splitter.count() > 0:
|
||||
# 计算每个部件应该的大小
|
||||
total_size = splitter.width() if splitter.orientation() == QtCore.Qt.Horizontal else splitter.height()
|
||||
size_per_widget = max(1, total_size // splitter.count())
|
||||
sizes = [size_per_widget] * splitter.count()
|
||||
|
||||
# 立即设置大小
|
||||
splitter.setSizes(sizes)
|
||||
splitter.update()
|
||||
|
||||
# 延迟设置确保生效 - 使用两次定时器调用,确保在UI完全加载后生效
|
||||
QtCore.QTimer.singleShot(50, lambda: splitter.setSizes(sizes))
|
||||
QtCore.QTimer.singleShot(200, lambda: splitter.setSizes(sizes))
|
||||
|
||||
# 连接分割器移动信号
|
||||
splitter.splitterMoved.connect(lambda: on_splitter_moved(splitter))
|
||||
|
||||
return True
|
||||
|
||||
def on_splitter_moved(splitter):
|
||||
"""
|
||||
处理分割器移动事件
|
||||
|
||||
Args:
|
||||
splitter: 被移动的分割器对象
|
||||
"""
|
||||
# 这里可以添加分割器移动后的处理逻辑
|
||||
# 例如记录分割器位置,或者调整其他UI元素
|
||||
pass
|
||||
|
||||
def reset_splitter_sizes(splitter, equal_sizes=True):
|
||||
"""
|
||||
重置分割器大小,可选择设置均等大小
|
||||
|
||||
Args:
|
||||
splitter: 分割器对象
|
||||
equal_sizes: 是否设置均等大小
|
||||
"""
|
||||
if not isinstance(splitter, QtWidgets.QSplitter):
|
||||
return
|
||||
|
||||
if equal_sizes and splitter.count() > 0:
|
||||
# 计算每个部件应该的大小
|
||||
total_size = splitter.width() if splitter.orientation() == QtCore.Qt.Horizontal else splitter.height()
|
||||
size_per_widget = max(1, total_size // splitter.count())
|
||||
sizes = [size_per_widget] * splitter.count()
|
||||
|
||||
# 设置大小
|
||||
splitter.setSizes(sizes)
|
||||
splitter.update()
|
||||
|
||||
# 延迟设置确保生效
|
||||
QtCore.QTimer.singleShot(50, lambda: splitter.setSizes(sizes))
|
||||
QtCore.QTimer.singleShot(200, lambda: splitter.setSizes(sizes))
|
||||
|
||||
def force_equal_splitter_sizes(ui_instance, splitter_name="main_splitter"):
|
||||
"""
|
||||
强制设置分割器大小为均等,并确保完全自由调整
|
||||
|
||||
Args:
|
||||
ui_instance: UI实例对象
|
||||
splitter_name (str): 分割器名称
|
||||
"""
|
||||
# 调用通用的分割器设置函数,设置均等大小
|
||||
return setup_splitter(ui_instance, splitter_name, equal_sizes=True)
|
||||
|
||||
def set_splitter_children_minimum_size(ui_instance, splitter_name="main_splitter", recursive=True):
|
||||
"""
|
||||
设置分割器所有子元素的最小宽度和高度为0,允许完全自由调整
|
||||
|
||||
Args:
|
||||
ui_instance: UI实例对象
|
||||
splitter_name (str): 分割器名称
|
||||
recursive (bool): 是否递归设置所有子元素
|
||||
"""
|
||||
# 检查分割器是否存在
|
||||
if not hasattr(ui_instance, 'splitters') or splitter_name not in ui_instance.splitters:
|
||||
if not isinstance(splitter, QtWidgets.QSplitter) or not proportions:
|
||||
return
|
||||
|
||||
# 获取分割器
|
||||
splitter = ui_instance.splitters[splitter_name]
|
||||
|
||||
# 设置分割器属性
|
||||
splitter.setOpaqueResize(True)
|
||||
splitter.setChildrenCollapsible(False)
|
||||
|
||||
# 设置所有子部件的最小尺寸为0
|
||||
for i in range(splitter.count()):
|
||||
widget = splitter.widget(i)
|
||||
if widget and recursive:
|
||||
# 设置最小尺寸为0
|
||||
widget.setMinimumWidth(0)
|
||||
widget.setMinimumHeight(0)
|
||||
widget.setSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
|
||||
|
||||
# 递归设置子控件
|
||||
_set_widget_children_minimum_size(widget)
|
||||
|
||||
def _set_widget_children_minimum_size(widget):
|
||||
"""
|
||||
递归设置控件及其所有子控件的最小尺寸为0
|
||||
|
||||
Args:
|
||||
widget: 要设置的控件
|
||||
"""
|
||||
# 递归设置所有子部件
|
||||
for child in widget.findChildren(QtWidgets.QWidget):
|
||||
# 设置每个子控件的最小宽度为0
|
||||
child.setMinimumWidth(0)
|
||||
# 确保比例数量与分割器子部件数量一致
|
||||
if len(proportions) != splitter.count():
|
||||
return
|
||||
|
||||
# 对于按钮、标签等控件,不应该设置最小高度为0,否则会导致界面异常
|
||||
if isinstance(child, (QtWidgets.QPushButton, QtWidgets.QToolButton,
|
||||
QtWidgets.QLabel, QtWidgets.QLineEdit,
|
||||
QtWidgets.QComboBox, QtWidgets.QCheckBox,
|
||||
QtWidgets.QRadioButton)):
|
||||
# 这些控件应该保持其默认高度,只设置水平方向的策略为Expanding
|
||||
policy = child.sizePolicy()
|
||||
policy.setHorizontalPolicy(QtWidgets.QSizePolicy.Expanding)
|
||||
child.setSizePolicy(policy)
|
||||
else:
|
||||
# 其他控件可以设置最小高度为0
|
||||
child.setMinimumHeight(0)
|
||||
child.setSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
|
||||
# 确保比例总和为1
|
||||
total = sum(proportions)
|
||||
if total <= 0:
|
||||
return
|
||||
|
||||
# 特别处理容器控件
|
||||
if isinstance(child, (QtWidgets.QSplitter, QtWidgets.QScrollArea,
|
||||
QtWidgets.QGroupBox, QtWidgets.QFrame,
|
||||
QtWidgets.QTabWidget, QtWidgets.QStackedWidget)) and hasattr(child, 'layout') and child.layout():
|
||||
child.layout().setContentsMargins(0, 0, 0, 0)
|
||||
child.layout().setSpacing(0)
|
||||
|
||||
# 特别处理列表、树和表格控件
|
||||
elif isinstance(child, (QtWidgets.QListWidget, QtWidgets.QTreeWidget,
|
||||
QtWidgets.QTableWidget, QtWidgets.QListView,
|
||||
QtWidgets.QTreeView, QtWidgets.QTableView)):
|
||||
child.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAsNeeded)
|
||||
child.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAsNeeded)
|
||||
|
||||
def set_all_controls_minimum_size(ui_instance):
|
||||
"""
|
||||
设置UI实例中所有控件的最小尺寸为0,确保分割器可以自由移动
|
||||
|
||||
Args:
|
||||
ui_instance: UI实例对象,必须包含controls和buttons字典
|
||||
"""
|
||||
# 设置所有按钮的最小尺寸
|
||||
if hasattr(ui_instance, 'buttons'):
|
||||
for button in ui_instance.buttons.values():
|
||||
_set_control_minimum_size(button)
|
||||
|
||||
# 设置所有控件的最小尺寸
|
||||
if hasattr(ui_instance, 'controls'):
|
||||
for control in ui_instance.controls.values():
|
||||
_set_control_minimum_size(control)
|
||||
|
||||
def _set_control_minimum_size(control):
|
||||
"""
|
||||
设置单个控件的最小尺寸为0
|
||||
|
||||
Args:
|
||||
control: 要设置的控件
|
||||
"""
|
||||
control.setMinimumWidth(0)
|
||||
|
||||
# 对于按钮、标签等控件,不应该设置最小高度为0,否则会导致界面异常
|
||||
if isinstance(control, (QtWidgets.QPushButton, QtWidgets.QToolButton,
|
||||
QtWidgets.QLabel, QtWidgets.QLineEdit,
|
||||
QtWidgets.QComboBox, QtWidgets.QCheckBox,
|
||||
QtWidgets.QRadioButton)):
|
||||
# 这些控件应该保持其默认高度,只设置水平方向的策略为Expanding
|
||||
policy = control.sizePolicy()
|
||||
policy.setHorizontalPolicy(QtWidgets.QSizePolicy.Expanding)
|
||||
control.setSizePolicy(policy)
|
||||
# 计算每个部件应该的大小
|
||||
if splitter.orientation() == QtCore.Qt.Horizontal:
|
||||
total_size = splitter.width()
|
||||
else:
|
||||
# 其他控件可以设置最小高度为0
|
||||
control.setMinimumHeight(0)
|
||||
control.setSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
|
||||
total_size = splitter.height()
|
||||
|
||||
# 计算实际大小
|
||||
sizes = [int(total_size * (p / total)) for p in proportions]
|
||||
|
||||
# 特别处理列表、树和表格控件
|
||||
if isinstance(control, (QtWidgets.QListWidget, QtWidgets.QTreeWidget,
|
||||
QtWidgets.QTableWidget, QtWidgets.QListView,
|
||||
QtWidgets.QTreeView, QtWidgets.QTableView)):
|
||||
# 确保这些控件可以自由调整大小
|
||||
control.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAsNeeded)
|
||||
control.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAsNeeded)
|
||||
# 设置大小
|
||||
splitter.setSizes(sizes)
|
||||
|
||||
def update_ui_texts(widget):
|
||||
"""
|
||||
递归更新控件文本以应用当前语言
|
||||
|
||||
Args:
|
||||
widget: 要更新的控件或控件容器
|
||||
"""
|
||||
from scripts.ui import localization
|
||||
|
||||
# 更新标签文本
|
||||
if isinstance(widget, QtWidgets.QLabel):
|
||||
# 尝试查找与当前文本匹配的键
|
||||
current_text = widget.text()
|
||||
for lang in ["zh_CN", "en_US"]:
|
||||
for key, text in localization.LANG.get(lang, {}).items():
|
||||
if text == current_text:
|
||||
widget.setText(localization.get_text(key, current_text))
|
||||
break
|
||||
|
||||
# 更新按钮文本和工具提示
|
||||
elif isinstance(widget, QtWidgets.QPushButton) or isinstance(widget, QtWidgets.QToolButton):
|
||||
# 更新按钮文本
|
||||
if widget.text():
|
||||
current_text = widget.text()
|
||||
for lang in ["zh_CN", "en_US"]:
|
||||
for key, text in localization.LANG.get(lang, {}).items():
|
||||
if text == current_text:
|
||||
widget.setText(localization.get_text(key, current_text))
|
||||
break
|
||||
|
||||
# 更新工具提示
|
||||
if widget.toolTip():
|
||||
current_tip = widget.toolTip()
|
||||
for lang in ["zh_CN", "en_US"]:
|
||||
for key, text in localization.LANG.get(lang, {}).items():
|
||||
if text == current_tip:
|
||||
widget.setToolTip(localization.get_text(key, current_tip))
|
||||
break
|
||||
|
||||
# 递归处理所有子控件
|
||||
for child in widget.findChildren(QtWidgets.QWidget):
|
||||
update_ui_texts(child)
|
||||
|
||||
|
Reference in New Issue
Block a user