在Windows 10,python3.10上,当调用QPainter.DrawLine()时,PySide6(或PyQt6)QApplication崩溃.

终端只显示:

进程已完成,退出代码为-1073741819(0xC0000005)

请查看下面的代码:

import sys
from PySide6.QtCore import QPoint, Qt
from PySide6.QtGui import QColor, QPainter, QPen, QPixmap
from PySide6.QtWidgets import QApplication, QLabel, QMainWindow


# from PyQt6.QtCore import QPoint, Qt
# from PyQt6.QtGui import QColor, QPainter, QPen, QPixmap
# from PyQt6.QtWidgets import QApplication, QLabel, QMainWindow

class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()

        self.label = QLabel()
        canvas = QPixmap(400, 300)
        canvas.fill(Qt.GlobalColor.white)

        self.label.setPixmap(canvas)
        self.setCentralWidget(self.label)
        self.draw_something()

    def draw_something(self):
        painter = QPainter(self.label.pixmap())
        painter.drawLine(10, 10, 300, 200)  # >=========== Crash Here
        painter.end()


if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = MainWindow()
    window.show()
    app.exec()

推荐答案

这是由于从Qt5.15开始对API进行了轻微(没有详细记录)的更 retrofit 成的.

在Qt5之前,pixmap()返回一个指向标签的current个像素图的直接指针,而在Qt6中,它返回一个implicit copy个像素图.只有最新的pixmap()家wine 店的Qt5文档才会强调这一区别:

以前,Qt提供了一个按指针返回像素图的Pixmap()版本.该版本现已弃用.为了保持与旧代码的兼容性,您可以明确区分按指针函数和按值函数:

对于Python开发人员来说,这并不明显,但对于C++来说,通过将const QPixmap *(注意星号,意味着它是pointer)更改为纯QPixmap类型,这一点很明显,这意味着返回的对象是基于当前像素图的new QPixmap对象,而不是对当前为标签设置的像素图对象的引用.

现在,事实是,从概念上讲,我们不应该能够直接在标签的当前像素图上"实时绘制",因为:

  • setPixmap()总是为标签创建copy的像素图;
  • 由于上述原因,在不同标签之间共享same像素映射对象是没有意义的,因此,pixmap()应该始终返回该对象的副本;

以前,可以直接在QLabel的像素图上绘制(同时确保标签上立即调用update()).当前API改为在绘制后请求显式调用setPixmap().

因此,只要需要,解决方案就是创建对像素图的引用:

    def draw_something(self):
        pm = self.label.pixmap()
        painter = QPainter(pm)
        painter.drawLine(10, 10, 300, 200)
        painter.end()
        self.label.setPixmap(pm)

Python相关问答推荐

如何找到满足各组口罩条件的第一行?

为什么默认情况下所有Python类都是可调用的?

ODE集成中如何终止solve_ivp的无限运行

如何将一个动态分配的C数组转换为Numpy数组,并在C扩展模块中返回给Python

如何获得每个组的时间戳差异?

未知依赖项pin—1阻止conda安装""

Python Pandas获取层次路径直到顶层管理

Django admin Csrf令牌未设置

将scipy. sparse矩阵直接保存为常规txt文件

Python—转换日期:价目表到新行

如何使用OpenGL使球体遵循Python中的八样路径?

关于两个表达式的区别

如何删除重复的文字翻拍?

将CSS链接到HTML文件的问题

为什么dict. items()可以快速查找?

文本溢出了Kivy的视区

普洛特利express 发布的人口普查数据失败

如何判断变量可调用函数的参数是否都属于某个子类?

判断字典键、值对是否满足用户定义的搜索条件

通过PyTorch中的MIN函数传递渐变