2013-07-29 32 views
8

silindi sarılmış:PyQT: RuntimeError: Bu kodu çalıştırırsanız C/C++ nesne

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

... Bu çıktıyı almak:

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 

anlamıyorum neden nesne siliniyor. Pencere, bir referansı korumalıdır. iyice bu mesajları araştırdık: Understanding the “underlying C/C++ object has been deleted” error

Neden düğmesi siliniyor Can a PyQt4 QObject be queried to determine if the underlying C++ instance has been destroyed??

+1

QWidget'in bir alt sınıfı ile benzer bir sorunla karşılaşıyordum ve sorun şu ki, '__init__' başarımda QWidget'ın '__init__' diye çağırmayı unutmuştum. Tricksy. – spookypeanut

cevap

9

bu soruya bu cevabı burada bulunur bulunmaz: Görünüşe Python PySide (Internal c++ Object Already Deleted)

, setCentralWidget kullanarak QMainWindow bir widget'ı atayarak ve sonra altta yatan C++ QWidget neden olacaktır setCentralWidget başka widget'ı atama Silinecek ben olsa bile referansı tutan bir nesne.

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

0

Brain'in cevabı, sorunu mükemmel bir şekilde açıklıyor. This Link, işleri daha ayrıntılı bir şekilde açıklar.

Bu soruna yönelik çözümüm, widget'ları nesnenin öznitelikleri olarak ayarlamaktı (örneğin, sınıf yöntemlerinde label = ... yerine self.label = ...'u kullanarak). Widget'a eklenen tüm düzenler için de aynısını yapmak isteyebilirsiniz.

Bu şekilde, widget'ın bir kopyasını yaratırsınız, böylece C++ bellek temizleme işlemi gerçekleştiğinde, widget'a hala başvurunuz olur.

Bu yardımcı olur umarım.