2012-07-25 10 views
17

मुझे आश्चर्य है कि कौन से मामले विजेट को अपने पेंट इवेंट प्राप्त करते हैं, और यह ओएस के साथ कैसे भिन्न होता है। paintEvent के लिएएक क्यूटी विजेट कब एक पेंटएवेंट मिलता है?

क्यूटी प्रलेखन कहते हैं केवल

एक पेंट घटना सभी या एक विजेट का हिस्सा फिर से रंगना एक अनुरोध है। यह निम्न कारणों में से एक हो सकता है:

रीपेंट() या अद्यतन() लागू किया गया था,

विजेट छिप गया था और अब पर्दाफ़ाश हो गया है, या

कई अन्य कारणों से।

अब तक, मैं कुछ निशान paintEvent में डाल दिया है,

void Widget::paintEvent(QPaintEvent *e) 
{ 
    static int count = 0; 
    qDebug("paintEvent, %d", count++); 
} 

और यह है कि क्या मैं (विंडोज 7 कम से कम पर) को पता चला है:

paintEvent है जब विजेट खो देता है/लाभ प्राप्त करता है कहा जाता है। पेंट इवेंट को नहीं कहा जाता है जब कोई अन्य विजेट हमारे विजेट पर गुज़रता है। मुझे नहीं पता कि यह विंडोज 7 कंपोजिटिंग के कारण है या नहीं। पेंटएवेंट को तब भी कहा जाता है जब एक न्यूनतम विंडो बहाल की जाती है। आकार बदलने पर पेंटएवेंट को बुलाया जाता है।

तो ओएस पर निर्भर व्यवहार क्या है?

उत्तर

19

हां, जिस अर्थ में आप वर्णन करते हैं, यह ऑपरेटिंग सिस्टम पर निर्भर है।

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

इसका अपवाद यह है कि यह हमेशा CS_SAVEBITS वर्ग शैली के लिए कहा गया है। यदि डीडब्लूएम कैश किए गए बिटमैप को अमान्य कर दिया गया है (उदा।, क्योंकि आपकी विंडो छवि बदल गई है), तो यह इसे छोड़ देगा और आपको विंडो को फिर से निकालने के लिए कहेंगे।

डीडब्लूएम संरचना ("विंडोज क्लासिक" थीम पर स्विच करके) को बंद करके इस सिद्धांत का परीक्षण करें, और फिर यह देखने के लिए कि आप एक पेंट इवेंट प्राप्त करते हैं या नहीं, अपनी विंडो को अस्पष्ट कर रहे हैं। आपको विंडोज़ के पिछले सभी संस्करणों में जैसा करना चाहिए था।

लेकिन बड़ा मुद्दा यह है कि आपको किसी भी विशेष क्रम में पेंट घटनाओं को प्राप्त करने पर भरोसा नहीं करना चाहिए। केवल चीज आपको पेंट इवेंट्स के बारे में माननी चाहिए कि आपको एक प्राप्त होगा जब ऑपरेटिंग सिस्टम को आपकी खिड़की को पुनर्निर्मित करने की आवश्यकता होगी। अन्यथा, यह आपको परेशान नहीं करेगा। मुझे यकीन है कि यही कारण है कि दस्तावेज इस बिंदु पर संभव तकनीकी बाधाओं से परे अस्पष्ट होने के साथ संतुष्ट है।

यही कारण है कि तर्क पेंट इवेंट हैंडलर के अंदर नहीं जाना चाहिए।केवल बात यह है कि विधि को वर्तमान स्थिति द्वारा पुनर्स्थापित करने के लिए जिम्मेदार होना चाहिए। उस राज्य को कहीं और बचाया जाना चाहिए। यह नियम भी कम्यूटिव है: आपको पेंट इवेंट हैंडलर के के बाहर कोई पेंटिंग नहीं करना चाहिए।

बेशक

, आप हमेशा बल एक पेंट घटना अपने विंडो अमान्य द्वारा उठाया जा सकता है (मुझे यकीन है कि क्यूटी इस के लिए एक invalidate या refresh विधि है हूँ, प्रलेखन जाँच), लेकिन है कि अभी भी मतलब नहीं है इस घटना को संभालने वाली विधि में एप्लिकेशन तर्क रखने के लिए यह एक अच्छा पैटर्न है।

+0

यह भी ध्यान दें कि जब भी हम किसी अन्य QWidget ऑनटॉप के बारे में बात कर रहे हैं, तो गायब हो जाता है/गायब/चाल/आकार बदल जाता है। कम से कम यह डिफ़ॉल्ट व्यवहार है। ऐसे मामले में, पेंटएवेंट को QPaintEvent के पैरामीटर के रूप में एक विशिष्ट क्षेत्र (QRegion) के साथ बुलाया जाता है, जो क्षेत्र को अद्यतन करने का वर्णन करता है। जानकारी के इस टुकड़े का उपयोग करके कोई भी आपकी सामग्री को पुनर्निर्मित करने के लिए आवश्यक चरणों को अनुकूलित कर सकता है, लेकिन मुझे लगता है कि इसका शायद ही कभी उपयोग किया जाता है। – leemes

संबंधित मुद्दे