pyqt

2012-12-11 25 views
6

में विजेट को साफ़ करने का उचित तरीका PyQt4 का उपयोग करते समय विजेट को साफ़/हटाने के लिए 'सही' या बेवकूफ तरीका क्या है?pyqt

पर विचार करें निम्नलिखित कोड:

choices = ['a', 'b', 'c'] 
checkboxes = [] 
layout = QtGui.QVBoxLayout() 

dialog = MyDialog() 

for c in choices: 
    checkboxes.append(QtGui.QCheckBox(c) 
    layout.addWidget(chkbox) 

dialog.setLayout(layout) 

for c in checkboxes: 
    c.setParent(None) 
    c.deleteLater() 
    c = None 

ऊपर कोड setParent()deleteLater() का उपयोग करता है, और None करने के लिए वस्तु की स्थापना। क्या ये सभी आवश्यक हैं?

एक और संभावित परिदृश्य है कि मेरे पास विजेट्स के समूह के साथ एक संवाद है और इन विगेट्स को हटाना और नए जोड़ना चाहते हैं। मैं पुराने विजेट को 'रिसाव' नहीं करना चाहता, लेकिन मुझे यकीन नहीं है कि ऐसा कुछ करने का सही तरीका क्या होगा।

ऐसा लगता है कि deleteLater() की आवश्यकता नहीं हो सकती है। क्या यह सिर्फ संदर्भ गणना में कमी करता है? यदि ऐसा है, तो केवल वैरिएबल को सेट करने के लिए कोई भी चीज़ नहीं करेगा?

उत्तर

15

सबसे पहले आपको याद रखना चाहिए कि अपने विजेट के लिए माता-पिता/बाल संबंधों का उपयोग करना है। जब आप ऐसा करते हैं, तो उनका स्वामित्व Qt के स्वामित्व में होगा और माता-पिता को हटाए जाने पर स्वचालित रूप से सभी बच्चों को साफ़ कर दिया जाएगा।

dialog = MyDialog() 

for c in choices: 
    checkboxes.append(QtGui.QCheckBox(c, parent=dialog)) 
    layout.addWidget(chkbox) 

इस स्थिति में, जब आप संवाद हटाते हैं तो सभी चेकबॉक्स ठीक से साफ हो जाएंगे। यह आपके प्रश्न का एक हिस्सा संभालता है। मुझे एहसास है कि जब आप उन्हें लेआउट में जोड़ते हैं तो आप निश्चित रूप से पैरेंट सेट रखते हैं। लेकिन आपको उस माता-पिता को हटाने से पहले साफ़ नहीं करना चाहिए। यह माता-पिता संबंध है जो बच्चे को स्वचालित रूप से हटाने की अनुमति देता है। संदर्भ संख्या नहीं है। संदर्भ पहलू एक पाइथन-साइड चीज होगी जहां इसे कचरा मिलेगा जब इसमें कोई और संदर्भ नहीं होगा।

deleteLater बहुत महत्वपूर्ण है, जब आप ईवेंटलोप पर नियंत्रण लौटने पर हटाना चाहते हैं तो उपयोग के लिए बहुत महत्वपूर्ण है।

# clear a layout and delete all widgets 
# aLayout is some QLayout for instance 
while aLayout.count(): 
    item = aLayout.takeAt(0) 
    item.widget().deleteLater() 

ये विजेट वास्तव में एक बार इस विधि पूरा कर लिया है हटा दिया जाएगा: यह भी विगेट्स जब आप एक लेआउट से कुछ को दूर करने और नए लोगों को जोड़ रहे हैं हटाना सुरक्षित तरीका है। deleteLater विजेट को हटाने के लिए भी उपयोगी है जिसके तहत स्लॉट या ईवेंट वर्तमान में हो रहा है। जैसे QPushButton जो क्लिक पर खुद को हटा सकता है।

c = None सेट करने की भी आवश्यकता नहीं है। एक बार माता-पिता को हटा दिए जाने के बाद, और यह आपके सभी बच्चों को हटाने का ट्रिगर करता है, इसके बाद, उस ऑब्जेक्ट के आपके पायथन संदर्भ अमान्य होंगे। तो आपको बस इतना करना है कि अब उनका उपयोग न करें। यदि वे एक सूची में हैं, तो सूची साफ़ करें। उन्हें एक्सेस करने से RuntimeError: wrapped C/C++ object of %S has been deleted बढ़ जाएगा जिसका अर्थ है कि वे हटा दिए गए हैं।

+0

क्या लेआउट में जोड़े जाने वाले सभी ऑब्जेक्ट्स बनाते समय 'पैरेंट' तर्क का उपयोग करना आवश्यक है? मुझे एहसास है कि यह शायद थोड़ा और स्पष्ट है, लेकिन क्या इसकी आवश्यकता है? –

+0

वास्तव में नहीं। यदि आप उन्हें सीधे लेआउट में जोड़ रहे हैं तो लेआउट उन्हें लेआउट के मालिक के बच्चे बना देगा। – jdi

+0

पार्टी के लिए बहुत देर हो चुकी है, लेकिन सोचा कि मैं इसे जोड़ दूंगा - हालांकि यह 'पैरेंट' तर्क का उपयोग करने के लिए _necessary_ नहीं है - यह शायद एक अच्छा विचार है, क्योंकि यह आपके कोड की संरचना को थोड़ा सा बाधित करता है, और दूसरों के लिए यह आसान बनाता है यह देखने के लिए कि इच्छित रोकथाम पदानुक्रम क्या है। – Emmet