使用PySide6扩展QLable控件如何实现Word中图片裁剪框一样的效果。
可以通过拖动图片四周的8个控制块获取当前图片的真实裁剪区域(考虑为了显示整图可能等比缩放显示)。
使用PySide6扩展QLable控件如何实现Word中图片裁剪框一样的效果。
可以通过拖动图片四周的8个控制块获取当前图片的真实裁剪区域(考虑为了显示整图可能等比缩放显示)。
该回答结合ChatGPT4o及杨同学*共同作答, 如有帮助,还请采纳。
要实现一个类似于Word中图片裁剪框的效果,可以使用PySide6扩展QLabel控件,添加鼠标事件来实现裁剪区域的控制。我们需要在QLabel上绘制8个控制块,通过拖动这些控制块来改变图片的裁剪区域。下面是一个基本的实现方法:
安装必要的库
pip install PySide6
实现代码
import sys
from PySide6.QtCore import Qt, QRect, QPoint
from PySide6.QtGui import QPainter, QPen, QPixmap
from PySide6.QtWidgets import QApplication, QLabel, QMainWindow, QWidget, QVBoxLayout, QSizePolicy
class ImageCropLabel(QLabel):
def __init__(self, parent=None):
super().__init__(parent)
self.setScaledContents(True)
self.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Ignored)
self.image = QPixmap("image.png")
self.setPixmap(self.image)
self.crop_rect = QRect(50, 50, 200, 150)
self.dragging = False
self.dragging_point = None
self.control_size = 10
self.setMinimumSize(1, 1)
def paintEvent(self, event):
super().paintEvent(event)
painter = QPainter(self)
painter.setPen(QPen(Qt.red, 2, Qt.SolidLine))
painter.drawRect(self.crop_rect)
# Draw the control points
control_points = self.get_control_points()
for point in control_points:
painter.fillRect(point.x() - self.control_size // 2, point.y() - self.control_size // 2,
self.control_size, self.control_size, Qt.blue)
def get_control_points(self):
return [
self.crop_rect.topLeft(),
self.crop_rect.topRight(),
self.crop_rect.bottomLeft(),
self.crop_rect.bottomRight(),
self.crop_rect.topLeft() + QPoint(self.crop_rect.width() // 2, 0),
self.crop_rect.topLeft() + QPoint(0, self.crop_rect.height() // 2),
self.crop_rect.bottomRight() - QPoint(self.crop_rect.width() // 2, 0),
self.crop_rect.bottomRight() - QPoint(0, self.crop_rect.height() // 2),
]
def mousePressEvent(self, event):
if event.button() == Qt.LeftButton:
self.dragging = False
self.dragging_point = None
control_points = self.get_control_points()
for point in control_points:
if (point - event.pos()).manhattanLength() < self.control_size:
self.dragging_point = point
break
if self.dragging_point is None and self.crop_rect.contains(event.pos()):
self.dragging = True
self.drag_start_position = event.pos()
def mouseMoveEvent(self, event):
if self.dragging_point:
self.update_crop_rect(self.dragging_point, event.pos())
elif self.dragging:
delta = event.pos() - self.drag_start_position
self.crop_rect.translate(delta)
self.drag_start_position = event.pos()
self.update()
def update_crop_rect(self, control_point, new_pos):
index = self.get_control_points().index(control_point)
if index == 0: # topLeft
self.crop_rect.setTopLeft(new_pos)
elif index == 1: # topRight
self.crop_rect.setTopRight(new_pos)
elif index == 2: # bottomLeft
self.crop_rect.setBottomLeft(new_pos)
elif index == 3: # bottomRight
self.crop_rect.setBottomRight(new_pos)
elif index == 4: # top center
self.crop_rect.setTop(new_pos.y())
elif index == 5: # left center
self.crop_rect.setLeft(new_pos.x())
elif index == 6: # bottom center
self.crop_rect.setBottom(new_pos.y())
elif index == 7: # right center
self.crop_rect.setRight(new_pos.x())
def mouseReleaseEvent(self, event):
self.dragging = False
self.dragging_point = None
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("Image Cropper")
self.setGeometry(100, 100, 800, 600)
self.label = ImageCropLabel()
self.setCentralWidget(self.label)
app = QApplication(sys.argv)
window = MainWindow()
window.show()
app.exec()
ImageCropLabel 类:
QLabel
并添加了裁剪区域 (crop_rect
)。paintEvent
方法来绘制裁剪矩形和控制点。mousePressEvent
、mouseMoveEvent
和 mouseReleaseEvent
方法来处理鼠标事件。MainWindow 类:
ImageCropLabel
设置为其中心小部件。运行此代码,你将看到一个可以拖动和调整裁剪区域的图片。你可以根据需要进一步扩展功能,例如添加裁剪确认按钮、保存裁剪结果等。