from PySide6 import QtWidgets, QtCore, QtGui class FloatingImagePanel(QtWidgets.QWidget): def __init__(self, parent, title="原始比例预览", image_path=None): super().__init__(parent) self.is_expanded = True # 1. 样式配置 (保持深色风格,方便看清信号) self.setAttribute(QtCore.Qt.WA_StyledBackground, True) self.setStyleSheet(""" FloatingImagePanel { background-color: rgba(30, 30, 30, 220); border: 2px solid #444; border-radius: 4px; } QLabel#title_label { color: #ffffff; font-weight: bold; font-family: 'Consolas'; } QPushButton#toggle_btn { background: #444; color: white; border: none; } """) # 2. 布局初始化 self.main_layout = QtWidgets.QVBoxLayout(self) self.main_layout.setContentsMargins(4, 4, 4, 4) self.main_layout.setSpacing(2) # --- 标题栏 --- self.header = QtWidgets.QWidget() header_layout = QtWidgets.QHBoxLayout(self.header) header_layout.setContentsMargins(2, 2, 2, 2) self.title_label = QtWidgets.QLabel(title) self.title_label.setObjectName("title_label") self.toggle_btn = QtWidgets.QPushButton("▲") self.toggle_btn.setFixedSize(22, 22) header_layout.addWidget(self.title_label) header_layout.addStretch() header_layout.addWidget(self.toggle_btn) self.main_layout.addWidget(self.header) # --- 图片展示区 --- self.image_label = QtWidgets.QLabel() # 关键点 1:关闭自动填充,确保我们手动控制尺寸 self.image_label.setScaledContents(False) # 关键点 2:设置对齐方式为中心 self.image_label.setAlignment(QtCore.Qt.AlignCenter) self.main_layout.addWidget(self.image_label) # 3. 信号绑定 self.toggle_btn.clicked.connect(self.toggle_content) # 4. 加载图片 if image_path: self.update_image(image_path) def update_image(self, path): """完全根据图片的物理尺寸调整窗口""" pixmap = QtGui.QPixmap(path) if not pixmap.isNull(): # 拿到图片的原始宽高 w = pixmap.width() h = pixmap.height() # 强制 Label 等于图片大小 self.image_label.setFixedSize(w, h) self.image_label.setPixmap(pixmap) # 让整个窗口重新计算布局,贴合 Label self.adjustSize() # 保持展开状态 self.set_expanded(True) def set_expanded(self, expanded: bool): self.is_expanded = expanded self.image_label.setVisible(expanded) self.toggle_btn.setText("▲" if expanded else "▼") # 关键点 3:重置窗口大小 # 展开时它会变大包住图片,收起时它会缩成标题栏大小 self.adjustSize() # 通知父窗口刷新位置,防止因为变大而超出右边界 if hasattr(self.parent(), 'update_overlay_position'): self.parent().update_overlay_position() def toggle_content(self): self.set_expanded(not self.is_expanded) # --- 封装的调用函数 --- def add_floating_image_panel(parent_widget, title="图片原尺寸", img_path=None): panel = FloatingImagePanel(parent_widget, title, img_path) panel.raise_() return panel