为啥当我放大Windows尺寸时,pyqt5中笔没有在鼠标坐标点上绘画

Posted

技术标签:

【中文标题】为啥当我放大Windows尺寸时,pyqt5中笔没有在鼠标坐标点上绘画【英文标题】:why When I large the size of Windows, the pen does not painting at the coordinate point of the mouse in pyqt5为什么当我放大Windows尺寸时,pyqt5中笔没有在鼠标坐标点上绘画 【发布时间】:2021-12-05 08:02:47 【问题描述】:

各位亲爱的教授大家好! 我制作了以下用笔书写的程序。当窗口大小为 900x600 时,笔在鼠标坐标点上书写是正确的,但是当我放大程序窗口时,笔在离鼠标光标点更远的地方书写。 一般情况下,为什么我将像素图添加到标签时,我们不能在鼠标点击点绘制?

import sys
from PyQt5 import QtCore, QtGui, QtWidgets, uic
from PyQt5.QtCore import Qt


class MainWindow(QtWidgets.QMainWindow):

    def __init__(self):
        super().__init__()

        self.label = QtWidgets.QLabel()
        canvas = QtGui.QPixmap(900, 600)
        canvas.fill(Qt.white)
        self.label.setPixmap(canvas)
        self.setCentralWidget(self.label)

        self.last_x, self.last_y = None, None

    def mouseMoveEvent(self, e):
        if self.last_x is None: # First event.
            self.last_x = e.x()
            self.last_y = e.y()
            return # Ignore the first time.

        painter = QtGui.QPainter(self.label.pixmap())
        painter.drawLine(self.last_x, self.last_y, e.x(), e.y())
        painter.end()
        self.update()

        # Update the origin for next time.
        self.last_x = e.x()
        self.last_y = e.y()

    def mouseReleaseEvent(self, e):
        self.last_x = None
        self.last_y = None


app = QtWidgets.QApplication(sys.argv)
window = MainWindow()
window.show()
app.exec_()

【问题讨论】:

鼠标事件与主窗口相关,而不是像素图(具有固定大小),这似乎很明显。 【参考方案1】:

QLabel 的alignment() 属性文档对此进行了说明:

默认情况下,标签的内容是左对齐垂直居中的。

在任何情况下,即使忽略对齐,任何基于鼠标的绘图都应该在小部件坐标中完成,而您尝试使用父级的坐标进行。

更好的方法应该是使用 QLabel 的子类,使用以下实现:

class MyLabel(QtWidgets.QLabel):
    def __init__(self):
        super().__init__()
        canvas = QtGui.QPixmap(900, 600)
        canvas.fill(Qt.white)
        self.setPixmap(canvas)
        self.last_x, self.last_y = None, None
        self.setAlignment(QtCore.Qt.AlignLeft|QtCore.Qt.AlignTop)

    def mouseMoveEvent(self, e):
        if self.last_x is None: # First event.
            self.last_x = e.x()
            self.last_y = e.y()
            return # Ignore the first time.

        painter = QtGui.QPainter(self.pixmap())
        painter.drawLine(self.last_x, self.last_y, e.x(), e.y())
        painter.end()
        self.update()

        # Update the origin for next time.
        self.last_x = e.x()
        self.last_y = e.y()

    def mouseReleaseEvent(self, e):
        self.last_x = None
        self.last_y = None

class MainWindow(QtWidgets.QMainWindow):

    def __init__(self):
        super().__init__()

        self.label = MyLabel()
        self.setCentralWidget(self.label)

另外,请参阅此相关问题:Mouse position on mouse move event is set on parent instead of child。

【讨论】:

@AmanullahAmini 不客气。如果它解决了您的问题,请单击答案左侧的灰色勾号,以使其被接受。

以上是关于为啥当我放大Windows尺寸时,pyqt5中笔没有在鼠标坐标点上绘画的主要内容,如果未能解决你的问题,请参考以下文章

为啥当我单击提交按钮时,此 PyQt5 发票 GUI 应用程序的“Python 停止工作”? [复制]

为啥在 PyQt5 中打开新窗口时我的应用程序会关闭?

当我尝试使用文件维度作为行和列在 C 中创建矩阵时,为啥会出现错误?

Wordpress 的图像的“尺寸”属性是如何计算的?

在 macOS 和 Windows 上使用 PyInstaller 编译时,简单的 PyQt5 GUI 看起来像 GTK

请问做设计时条码可以随便改变尺寸大小吗?