[PyQt] bus error and segmentation fault on MacOS

Michael Held michael.held at bc.biol.ethz.ch
Fri Jun 12 09:47:49 BST 2009


hi,

so I am still a newbie in PyQt/Qt and was playing around with QFrames
and QDialogs.
the purpose of the attached program is to show a QFrame XOR a QDialog
editing the same object via a QDoubleSpinBox. Frame and Dialog should
not be visible at the same time.
when switching between Frame and Dialog with certain speed a seg fault /
bus error is occurring on MacOS.

MacOS 10.5.7
Python 2.6 (stackless)
Qt 4.5 (2009.02)
PyQt 4.5 (stable)
SIP sip-4.8-snapshot-20090430

on windows this error is not occurring, therefore the Frame is not
disappearing correctly (it's removed from the layout and destroyed
afterwards)

Windows XP
Python 2.6.2 (stackless)
Qt 4.5.1
PyQt 4.5.1 (binary)

thanks for your help!
michael
-------------- next part --------------
#------------------------------------------------------------------------------
# standard library imports:
#
import time
import sys
import os

#------------------------------------------------------------------------------
# extension module imports:
#
from PyQt4 import QtCore, QtGui

#------------------------------------------------------------------------------
# constants:
#

QT_DIALOG = 'QT_DIALOG'
QT_FRAME = 'QT_FRAME'

#------------------------------------------------------------------------------
# helper functions:
#

def visualize(parent, obj, kind=QT_DIALOG):
    if kind == QT_DIALOG:
        widget = MyDialog(parent, obj)
    elif kind == QT_FRAME:
        widget = MyFrame(parent, obj)
    else:
        raise ValueError("Kind '%s' not supported." % kind)
    return widget


#------------------------------------------------------------------------------
# classes:
#

class _Widget(object):

    def __init__(self, obj):
        layout = QtGui.QGridLayout()
        value = obj.my_float
        print value
        widget = QtGui.QDoubleSpinBox(self)
        widget.setValue(value)
        layout.addWidget(widget, 0, 0)
        shedule = lambda x,y: lambda z: self._setValue(x, y, z)
        self.connect(widget,
                     QtCore.SIGNAL('valueChanged(double)'),
                     shedule(obj, 'my_float'))

        layout.setAlignment(QtCore.Qt.AlignCenter|
                            QtCore.Qt.AlignVCenter)
        self.setLayout(layout)
        self.show()

    def _setValue(self, obj, name, value):
        setattr(obj, name, value)
        print getattr(obj, name)

class MyFrame(QtGui.QFrame, _Widget):

    def __init__(self, parent, obj):
        QtGui.QFrame.__init__(self, parent)
        _Widget.__init__(self, obj)

class MyDialog(QtGui.QDialog, _Widget):

    def __init__(self, parent, obj):
        QtGui.QDialog.__init__(self, parent)
        _Widget.__init__(self, obj)


#------------------------------------------------------------------------------
# main:
#

if __name__ == "__main__":


    class Test:

        my_float = 23.1

    class MainWindow(QtGui.QMainWindow):
        def __init__(self, obj):
            QtGui.QMainWindow.__init__(self)

            self.setGeometry(0, 0, 600, 400)
            self.setWindowTitle('Some test...')

            frame = QtGui.QFrame(self)
            self.setCentralWidget(frame)

            self.obj = obj

            self.frame_widget = None
            self.dialog_widget = None

            self.layout = QtGui.QVBoxLayout()
            self.layout.setAlignment(QtCore.Qt.AlignTop)
            widget = QtGui.QPushButton('Dialog Demo', self)
            self.connect(widget, QtCore.SIGNAL('clicked()'), self._onShowDialog)
            self.layout.addWidget(widget)
            widget = QtGui.QPushButton('Frame Demo', self)
            self.connect(widget, QtCore.SIGNAL('clicked()'), self._onShowFrame)
            self.layout.addWidget(widget)
            frame.setLayout(self.layout)
            frame.show()

            self.center()
            self.show()
            self.raise_()

        def _onShowFrame(self):
            if not self.dialog_widget is None:
                self.dialog_widget.close()
                self.dialog_widget = None
            if self.frame_widget is None:
                self.frame_widget = visualize(self,
                                              self.obj,
                                              QT_FRAME)
                self.layout.addWidget(self.frame_widget)
            self.update()

        def _onShowDialog(self):
            if not self.frame_widget is None:
                self.layout.removeWidget(self.frame_widget)
                self.frame_widget.destroy()
                self.frame_widget = None
            if self.dialog_widget is None:
                self.dialog_widget = visualize(self,
                                               self.obj,
                                               QT_DIALOG)
                self.connect(self.dialog_widget,
                             QtCore.SIGNAL('finished(int)'),
                             self._onDestroyed)
            self.update()

        def _onDestroyed(self, x):
            print "moo"
            self.dialog_widget.close()
            self.dialog_widget = None

        def center(self):
            screen = QtGui.QDesktopWidget().screenGeometry()
            size =  self.geometry()
            self.move((screen.width()-size.width())/2,
            (screen.height()-size.height())/2)

    app = QtGui.QApplication(sys.argv)
    main = MainWindow(Test())
    main.raise_()

    sys.exit(app.exec_())


More information about the PyQt mailing list