2013-07-29 13 views
8

Se corro questo codice:PyQt: RuntimeError: Spostato C/C++ oggetto è stato eliminato

#!/usr/local/bin/ python3 

import sys 
from PyQt4.QtCore import * 
from PyQt4.QtGui import * 


class Window(QMainWindow): 

    def __init__(self): 
     super().__init__() 
     self.button1 = QPushButton("1") 
     self.button2 = QPushButton("2") 
     self.setCentralWidget(self.button1) 
     self.button1.clicked.connect(lambda: self.setCentralWidget(self.button2)) 
     self.button2.clicked.connect(lambda: self.setCentralWidget(self.button1)) 
     self.show() 

if __name__ == '__main__': 

    import sys 
    app = QApplication(sys.argv) 
    window = Window() 
    sys.exit(app.exec_()) 

... ottengo questo output:

Traceback (most recent call last): 
    File "test.py", line 16, in <lambda> 
    self.button2.clicked.connect(lambda: self.setCentralWidget(self.button1)) 
RuntimeError: wrapped C/C++ object of type QPushButton has been deleted 

non capisco il motivo per cui l'oggetto è stato cancellato. La finestra dovrebbe mantenere un riferimento ad essa. Ho studiato a fondo questi post: Understanding the “underlying C/C++ object has been deleted” error Can a PyQt4 QObject be queried to determine if the underlying C++ instance has been destroyed?

Perché il pulsante di essere cancellati?

+1

Avevo un problema simile con una sottoclasse di QWidget, e si è scoperto che il problema era che avevo dimenticato di chiamare '__init__' di QWidget all'inizio del mio' __init__'. Furbata. – spookypeanut

risposta

9

Questa risposta a questa domanda è come si trova qui: Python PySide (Internal c++ Object Already Deleted)

A quanto pare, l'assegnazione di un widget per QMainWindow utilizzando setCentralWidget e assegnando un altro widget con setCentralWidget farà sì che il C sottostante ++ QWidget da cancellare, anche se ho un oggetto che mantiene il riferimento ad esso.

Note: QMainWindow takes ownership of the widget pointer and deletes it at the appropriate time.

0

La risposta del cervello spiega perfettamente il problema. This Link spiega le cose in modo più dettagliato.

La mia soluzione a questo problema era di impostare i widget come attributi dell'oggetto (ad esempio semplicemente usando self.label = ... invece di label = ... nei metodi della classe). Potresti voler fare lo stesso per qualsiasi layout collegato al widget.

In questo modo si crea una copia del widget in modo che quando si verifica la pulizia della memoria C++, si abbia ancora un riferimento al widget.

Spero che questo aiuti.

Problemi correlati