m0_74357767 2024-05-09 23:00 采纳率: 0%
浏览 46

pyqt做的ui界面,我用鼠标在label中显示的图像绘制矩形,为什么它绘制的起点位置跟我鼠标按下起点位置不一样,蓝点为鼠标起点,红点为绘制起点

pyqt做的ui界面,我用鼠标在label中显示的图像绘制矩形,为什么它绘制的起点位置跟我鼠标按下起点位置不一样,怎么解决
如图,蓝点为鼠标起点,红点为绘制起点,下面是代码块

img

    def show_rectangle_selection(self):
        # 确保label_2有图像
        if not self.label_2.pixmap():
            return
        # 连接鼠标事件
        self.label_2.mousePressEvent = self.mousePressEvent
        self.label_2.mouseMoveEvent = self.mouseMoveEvent
        self.label_2.mouseReleaseEvent = self.mouseReleaseEvent

    def mousePressEvent(self, event):
        """处理鼠标按下事件"""
        if event.button() == Qt.LeftButton:
            self.start_point = event.pos()
            self.end_point = event.pos()
            self.update_label_2()

    def mouseMoveEvent(self, event):
        """处理鼠标移动事件"""
        if event.buttons() & Qt.LeftButton:
            self.end_point = event.pos()
            self.update()

    def mouseReleaseEvent(self, event):
        """处理鼠标释放事件"""
        if event.button() == Qt.LeftButton:
            self.end_point = event.pos()
            self.update_label_2()

    def update_label_2(self):
        """更新label_2以显示选择的矩形"""
        if not self.label_2.pixmap():
            return
        pixmap = self.label_2.pixmap().copy()
        painter = QPainter(pixmap)
        painter.setPen(QPen(Qt.red, 2))  # 设置红色边框和2像素宽度

        # 如果已经有起始点和结束点,则绘制矩形边框
        if self.start_point and self.end_point:
            rect = QRect(self.start_point, self.end_point).normalized()
            painter.drawRect(rect)
        painter.end()
        self.label_2.setPixmap(pixmap)

  • 写回答

3条回答 默认 最新

  • 笑面虎 2024-05-09 23:00
    关注

    以下内容由CHATGPT及笑面虎共同生成、有用望采纳:


    【问题概括】:您遇到的问题是在使用PyQt进行UI界面设计时,使用鼠标在Label中绘制矩形时,发现绘制的起点位置与鼠标按下的起点位置不一致。您希望找出原因并解决这个问题。

    【图片内容】:您上传的图片显示了一个UI界面,其中有一个Label用于显示图像,并且有一个蓝点表示鼠标按下的起点,一个红点表示矩形绘制的起点。从图片中可以看出,红点并不在蓝点的位置,这表明起点位置有偏差。

    【问题出现原因】:问题可能出现的原因是在处理鼠标事件时,坐标系的转换或者坐标的获取方式有误。在PyQt中,event.pos()返回的是鼠标事件相对于接收事件的控件(在这种情况下是Label)的坐标。如果Label不是您鼠标按下时的顶层控件,或者Label的坐标系与鼠标事件的坐标系不一致,那么获取到的坐标就会有所不同。

    【问题解决方案】:为了解决这个问题,您需要确保在鼠标按下事件中获取的是相对于Label的坐标,并且在绘制矩形时使用相同的坐标系。此外,您可能需要调整坐标的获取方式,确保使用的是屏幕坐标或者控件的局部坐标。

    【提供代码】:以下是修改后的代码示例,它确保了在鼠标按下时获取的是相对于Label的坐标:

    from PyQt5.QtWidgets import QLabel, QApplication, QPainter, QPen, QRect
    from PyQt5.QtCore import Qt
    from PyQt5.QtGui import QPixmap
    
    class Example(QLabel):
        def __init__(self):
            super().__init__()
            self.start_point = None
            self.end_point = None
            self.show_rectangle_selection()
    
        def show_rectangle_selection(self):
            if not self.pixmap():
                return
            self.mousePressEvent = self.mousePressEvent
            self.mouseMoveEvent = self.mouseMoveEvent
            self.mouseReleaseEvent = self.mouseReleaseEvent
    
        def mousePressEvent(self, event):
            if event.button() == Qt.LeftButton:
                # 获取鼠标按下事件在Label上的坐标
                self.start_point = event.localPos()  # 使用localPos()获取相对于当前控件的坐标
                self.end_point = self.start_point
                self.update()
    
        def mouseMoveEvent(self, event):
            if event.buttons() & Qt.LeftButton:
                self.end_point = event.localPos()
                self.update()
    
        def mouseReleaseEvent(self, event):
            if event.button() == Qt.LeftButton:
                self.end_point = event.localPos()
                self.update()
    
        def paintEvent(self):
            super().paintEvent(None)
            if not self.pixmap():
                return
            pixmap = self.pixmap().copy()
            painter = QPainter(pixmap)
            painter.setPen(QPen(Qt.red, 2))
            if self.start_point and self.end_point:
                rect = QRect(self.start_point, self.end_point).normalized()
                painter.drawRect(rect)
            painter.end()
            self.setPixmap(pixmap)
    
    # 主程序
    if __name__ == '__main__':
        import sys
        app = QApplication(sys.argv)
        ex = Example()
        ex.show()
        sys.exit(app.exec_())
    

    【代码运行方式】:您需要有Python环境,并且安装了PyQt5库。您可以将上述代码保存为.py文件,并在命令行或IDE中运行它。

    【代码预期运行结果】:运行代码后,应该会看到一个窗口,其中包含一个Label。当您在Label上按下鼠标左键并拖动时,应该能够绘制一个矩形,其起点与鼠标按下的位置一致。

    【推荐相关链接】:

    评论 编辑记录

报告相同问题?

问题事件

  • 创建了问题 5月9日