“Python 已停止工作"在 PyQt5 GUI 退出时 [英] "Python has stopped working" on PyQt5 GUI exit

查看:248
本文介绍了“Python 已停止工作"在 PyQt5 GUI 退出时的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

几个小时以来,我一直在纠结这个问题.我有以下简单示例:

I've been pulling my hairs on this since a few hours. I have the following simple example:

#!/usr/bin/env python

import math

from PyQt5.QtCore import (pyqtSignal, QLineF, QPointF, QRect, QRectF, QSize,
        QSizeF, Qt)
from PyQt5.QtGui import (QBrush, QColor, QFont, QIcon, QIntValidator, QPainter,
        QPainterPath, QPen, QPixmap, QPolygonF)
from PyQt5.QtWidgets import (QAction, QApplication, QButtonGroup, QComboBox,
        QFontComboBox, QGraphicsItem, QGraphicsLineItem, QGraphicsPolygonItem,
        QGraphicsScene, QGraphicsTextItem, QGraphicsView, QGridLayout,
        QHBoxLayout, QLabel, QMainWindow, QMenu, QMessageBox, QSizePolicy,
        QToolBox, QToolButton, QWidget)

class DiagramScene(QGraphicsScene):
    def __init__(self, parent=None):
        super(DiagramScene, self).__init__(parent)

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

        self.scene = DiagramScene()
        self.scene.setSceneRect(QRectF(0, 0, 5000, 5000))

        layout = QHBoxLayout()
        self.view = QGraphicsView(self.scene)
        layout.addWidget(self.view)

        self.widget = QWidget()
        self.widget.setLayout(layout)

        self.setCentralWidget(self.widget)
        self.setWindowTitle("Diagramscene")

if __name__ == '__main__':
    import sys

    app = QApplication(sys.argv)

    mainWindow = MainWindow()
    mainWindow.setGeometry(100, 100, 800, 500)
    mainWindow.show()

    sys.exit(app.exec_())

这个程序运行正常.现在如果你更换

This program works OK. Now if you replace

if __name__ == '__main__':
    import sys

    app = QApplication(sys.argv)

    mainWindow = MainWindow()
    mainWindow.setGeometry(100, 100, 800, 500)
    mainWindow.show()

    sys.exit(app.exec_())

通过这个(当你想用 console_scripts 启动你的程序时,你会这样做):

by this (which is what you do when you want to start your program with console_scripts):

def mainFunc():
    import sys

    app = QApplication(sys.argv)

    mainWindow = MainWindow()
    mainWindow.setGeometry(100, 100, 800, 500)
    mainWindow.show()

    sys.exit(app.exec_())

if __name__ == '__main__':
    mainFunc()

我在退出时遇到段错误.尽管这两个程序(显然?)完全相同.

I get a segfault on exit. Althout both programs are (apparently ?) IDENTICALS.

应该注意的是,如果您从应用程序中删除 QGraphicsView,错误就会消失.退出时不再出现段错误.

It should be noted that if you remove the QGraphicsView from the application, the bug goes away. No more segfault on exit.

问题是否来自我的代码?或者是 PyQt5 的错误?

Is the issue coming from my code ? Or is it a PyQt5 bug ?

推荐答案

正如@user3419537 所指出的,这里的问题是始终为小部件构造提供父级.

As pointed-out by @user3419537, the catch here is to always provide a parent on widget construction.

否则,解除分配会向南进行,您最终会在程序终止时出现很好的段错误.

Otherwise, deallocation goes south and you end up with a nice segfault on program termination.

以下修改后的代码可以正常工作:

The following modified code works correctly:

#!/usr/bin/env python

import math

from PyQt5.QtCore import (QLineF, QPointF, QRect, QRectF, QSize,
        QSizeF, Qt)
from PyQt5.QtGui import (QBrush, QColor, QFont, QIcon, QIntValidator, QPainter,
        QPainterPath, QPen, QPixmap, QPolygonF)
from PyQt5.QtWidgets import (QAction, QApplication, QButtonGroup, QComboBox,
        QFontComboBox, QGraphicsItem, QGraphicsLineItem, QGraphicsPolygonItem,
        QGraphicsScene, QGraphicsTextItem, QGraphicsView, QGridLayout,
        QHBoxLayout, QLabel, QMainWindow, QMenu, QMessageBox, QSizePolicy,
        QToolBox, QToolButton, QWidget)

class DiagramScene(QGraphicsScene):
    def __init__(self, parent=None):
        super(DiagramScene, self).__init__(parent)

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

        # Build Widgets, from top to bottom
        # Always assigning a parent to it
        ## widget is attached to MainWindow
        self.widget = QWidget(self)
        ## view is attached to widget (main area of the MainWindow)
        self.view = QGraphicsView(self.widget)
        ## scene is attached to the view
        self.scene = DiagramScene(self.view)

        # Configure the widgets
        self.view.setScene(self.scene)

        # Configure the layout
        layout = QHBoxLayout()
        layout.addWidget(self.view)
        self.widget.setLayout(layout)
        self.setCentralWidget(self.widget)
        self.setWindowTitle("Diagramscene")

def mainFunc():
    import sys

    app = QApplication(sys.argv)

    mainWindow = MainWindow()
    mainWindow.setGeometry(100, 100, 800, 500)
    mainWindow.show()

    sys.exit(app.exec_())

if __name__ == '__main__':
    mainFunc()

这篇关于“Python 已停止工作"在 PyQt5 GUI 退出时的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆