python - PyQt5 GUI 退出时为 "Python has stopped working"

标签 python python-3.x pyqt5

几个小时以来我一直在为这个问题烦恼。我有以下简单的例子:

#!/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_())

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

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 启动程序时,您要做的就是这样做):

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()

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

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

segfault illustration

问题是出在我的代码上吗?或者是 PyQt5 的错误?

最佳答案

正如 @user3419537 所指出的,这里的要点是始终在小部件构造上提供父级。

否则,释放会发生错误,最终会在程序终止时出现良好的段错误。

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

#!/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 退出时为 "Python has stopped working",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48303984/

相关文章:

python - 有没有办法 "work around"装饰器的保留状态?

python - 将模块中的所有对象作为它们在模块中的名称导入的大多数 pythonic 方法

python - 如何在 Python 中按顺序计算两个单词之间的常用字母?

python - 如何在使用 Python 3 的过程中更改数组中的元素?

python - functools.wraps 不允许我用 Python 3 中的类包装函数

python - 在 PyQt5 中,如何在 QTreeWidget 单元格内添加 QSpinBox?

pyqt - 我可以将 Neumorphism 效果应用于 QWidget 吗?

python - 在 pd.DataFrame.query() 之后插入值并保留原始数据

python - 如何控制QSplitter内部的间距

python - 无法理解如何通过列表切片将字符串中的字符分配给列表在以下代码段中工作