首页下载资源操作系统pyqt pyside 随窗口自适应、可缩放、拖动QLabel

ZIPpyqt pyside 随窗口自适应、可缩放、拖动QLabel

hz1hz4.09MB需要积分:1

资源文件列表:

pyqt pyside 随窗口自适应、可缩放、拖动QLabel.zip 大约有7个文件
  1. pyqt pyside 随窗口自适应、可缩放、拖动QLabel/
  2. pyqt pyside 随窗口自适应、可缩放、拖动QLabel/check_except.py 2.16KB
  3. pyqt pyside 随窗口自适应、可缩放、拖动QLabel/custom_label.py 12.7KB
  4. pyqt pyside 随窗口自适应、可缩放、拖动QLabel/img.png 4.08MB
  5. pyqt pyside 随窗口自适应、可缩放、拖动QLabel/test_custom_label.py 1.7KB
  6. pyqt pyside 随窗口自适应、可缩放、拖动QLabel/test_custom_label.ui 3.25KB
  7. pyqt pyside 随窗口自适应、可缩放、拖动QLabel/test_custom_labelUI.py 4.55KB

资源介绍:

pyqt pyside 随窗口自适应、可缩放、拖动QLabel python 在小才玩yolo目标检测时,总是使用PyQt或PySide来展示识别结果。一开始小才使用自带的QLabel来显示图像,但是发现显示的比较呆,原QLabel显示有以下特点: 1. 窗口大小改变时,QLabel图片显示不会跟随窗口变化。 2. 图片不能够缩放,拖动。 于是小才就去搜索学习,许久后,总结加拓展自己实现了一个 随窗口自适应、可缩放、拖动、画框图片的自定义QLabel类(嘲笑请偷偷)。 以上代码是使用的pyside6实现,pyqt和pyside导入的都差不多,如果使用PyQt5的话删除上面pyside6的import,重新使用pycharm的自动导入提示重新import就行。 ImageLabel继承的QLabel。因此使用时直接将写好的label = QLabel(parent)替换为label = ImageLabel(parent)就可以得到升级!方法上的装饰器check_except是为了方便异常捕捉,小才不想因为显示报错而导致页面卡住然后退出。实现请看小才得另一篇文章python 程序运行
import cv2 from PySide6.QtCore import QPoint, Qt, QRect from PySide6.QtCore import Signal from PySide6.QtGui import QPainter, QPixmap, QImage, QMouseEvent, QKeyEvent, QPen, QColor from PySide6.QtWidgets import QLabel from check_except import check_except class ImageLabel(QLabel): clicked_signal = Signal() # clicked_signal = pyqtSignal()# pyqt5 # 当画框完成后向外输出信号 index: 0原图 1 裁剪后的图片 [2-5裁剪范围]2:x1 3:y1 4:width 5:height bbox_down_signal = Signal(list) def __init__(self, parent, scale_flag=True, move_flag=True, is_original=False, draw_bbox_flag=False): super(ImageLabel, self).__init__(parent) ''' @param parent: 父控件 @param scale_flag: 是否可以缩放 @param move_flag: 是否可以移动 @param is_original: 是否为原图 @param draw_bbox_flag: 是否开启画框 ''' self.scaled_img = None # QPixmap self.cv_image = None # draw_bbox_flag=True 时,为cv2原图 self.point = None # 图片位置 self.start_pos = None # 鼠标按下时的位置 self.end_pos = None # 鼠标松开时的位置 self.right_press = False # 右键正在按压 self.left_press = False # 左键正在按压 self.is_original = is_original # 是否为原图显示 self.x_scale = 1 self.y_scale = 1 # 画框起始点 self.bbox_start_point = None # 画框结束点 self.bbox_end_point = None # 是否可以缩放 scale_flag True 可以缩放 self.scale_flag = scale_flag # 是否可以移动 self.move_flag = move_flag # 是否开启画框 self.draw_bbox_flag = draw_bbox_flag @check_except() def clear_image(self): self.set_q_pixmap(QPixmap(None)) @check_except() def to_q_image(self, image): label_size = (self.height(), self.width()) height, width = image.shape[:2] if not self.is_original: n_height = label_size[0] n_width = int((width / height) * label_size[0]) if n_width > label_size[1]: n_width = label_size[1] n_height = int((height / width) * label_size[1]) image = cv2.resize(image, (n_width, n_height)) else: n_height = height n_width = width channels = len(image.shape) if channels == 2: bytes_per_line = n_width q_image = QImage(image.data, n_width, n_height, bytes_per_line, QImage.Format_Grayscale8) else: bytes_per_line = 3 * n_width q_image = QImage(image.data, n_width, n_height, bytes_per_line, QImage.Format_RGB888).rgbSwapped() return q_image @check_except() def set_cv_image(self, img): # 设置cv2读取的图片 self.set_q_image(self.to_q_image(img)) @check_except() def set_q_image(self, img): # 设置QImage图片 self.set_q_pixmap(QPixmap.fromImage(img)) @check_except() def set_q_pixmap(self, q_pixmap): # 设置QPixmap图片 self.scaled_img = q_pixmap if self.point is None: self._reset_scale() self._reset_point() self.update() def _reset_scale(self): if self.scaled_img: self.x_scale = self.width() / self.scaled_img.width() b = self.scaled_img.height() / self.scaled_img.width() n_height = self.width() * b if n_height > self.height(): self.y_scale = self.height() / self.scaled_img.height() self.x_scale = self.y_scale else: self.y_scale = self.x_scale self.reset_bbox() def _reset_point(self): if self.scaled_img: width, height = self.scaled_img.width(), self.scaled_img.height() p1 = 0 p2 = 0 if self.width() > width * self.x_scale: p1 = int((self.width() - width * self.x_scale) / 2) if self.height() > height * self.y_scale: p2 = int((self.height() - height * self.x_scale) / 2) self.point = QPoint(int(p1 / self.x_scale) if self.x_scale != 0 else 0, int(p2 / self.y_scale) if self.y_scale != 0 else 0) # 重置框 self.reset_bbox() def reset_bbox(self): self.bbox_start_point = None self.bbox_end_point = None @check_except() def paintEvent(self, e): if self.scaled_img: painter = QPainter() painter.begin(self) painter.scale(self.x_scale, self.y_scale) painter.drawPixmap(self.point, self.scaled_img) # 此函数中还会用scale对point进行处理 if self.draw_bbox_flag and self.bbox_start_point is not None and self.bbox_end_point is not None: lw = max(round(sum(self.cv_image.shape) / 2 * 0.003), 3) fs = lw / 3 # line width pen = QPen(QColor('red')) pen.setWidth(fs) painter.setPen(pen) painter.drawRect(self.bbox_start_point.x(), self.bbox_start_point.y(), self.bbox_end_point.x() - self.bbox_start_point.x(), self.bbox_end_point.y() - self.bbox_start_point.y()) painter.end() @check_except() def clear_image(self): self.scaled_img = None self.update() @check_except() def wheelEvent(self, event): if self.scale_flag: angle = event.angleDelta() / 8 # 返回QPoint对象,为滚轮转过的数值,单位为1/8度 angleY = angle.y() self.wheel_flag = True # 获取当前鼠标相对于view的位置 if angleY > 0: self.set_scale(x_scale=1.08 * self.x_scale, y_scale=1.08 * self.y_scale) else: # 滚轮下滚 self.set_scale(x_scale=0.92 * self.x_scale, y_scale=0.92 * self.y_scale) if self.x_scale < 0.05: self.x_scale = 0.05 if self.y_scale < 0.05: self.y_scale = 0.05 if self.x_scale > 50: self.x_scale = 50 if self.y_scale > 50: self.y_scale = 50 self.update() def set_scale(self, x_scale=None, y_scale=None): if x_scale is not None: self.x_scale = x_scale if y_scale is not None: self.y_scale = y_scale @check_except() def mouseMoveEvent(self, e): if self.scaled_img is None: return if self.right_press and self.move_flag: self.end_pos: QPoint = e.pos() - self.start_pos # 当前位置-起始位置=差值 x = round(self.end_pos.x() / self.x_scale) y = round(self.end_pos.y() / self.y_scale) self.point = self.point + QPoint(x, y) # 左上角的距离变化 if self.bbox_start_point is not None: self.bbox_end_point = self.bbox_end_point + QPoint(x, y) if self.bbox_start_point is not None: self.bbox_start_point = self.bbox_start_point + QPoint(x, y) self.start_pos = e.pos() self.repaint() elif self.left_press and self.draw_bbox_flag: img_rect = self.get_image_rect() if img_rect is not None: current_press_point = QPoint(int(e.x() / self.x_scale), int(e.y() / self.y_scale)) if img_rect.contains(current_press_point): # 设置框的结束位置点 self.bbox_end_point = current_press_point self.repaint() @check_except() def mo
100+评论
captcha