" Python已停止工作"在PyQt5 GUI退出

时间:2018-01-17 14:58:10

标签: 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()

退出时我遇到了段错误。但这两个项目(显然都是?)IDENTICALS。

应该注意的是,如果从应用程序中删除QGraphicsView,则该bug将消失。退出时不再有段错误。

segfault illustration

问题来自我的代码吗?或者它是一个PyQt5错误?

1 个答案:

答案 0 :(得分:2)

正如@ 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()