2009-07-13 17 views
14

में एक QPainter डिवाइस कैसे प्राप्त करूं, मैं QT 4.5 के साथ एक पेंटिंग प्रोग्राम करने की कोशिश कर रहा हूं, इसलिए मैं कैनवास के लिए QGraphicsView का उपयोग कर रहा हूं, और QGraphicsScene तैयार वस्तुओं को संग्रहीत करने के लिए उपयोग कर रहा हूं। कुछ कारणों के लिए, मैं सिर्फ एक QPainter संदर्भ अपने ही व्युत्पन्न QGraphicsView में अगर मैं DrawingCanvas बदलने QWidget का एक बच्चा होने के लिए मिल सकता हैक्यूटी 4.5 - मैं QGraphicsView

class DrawingCanvas : public QGraphicsView 
{ 
    DrawingCanvas::DrawingCanvas(QWidget * parent); 

... 
}; 

DrawingCanvas::DrawingCanvas(QWidget * parent = 0) : QGraphicsView(parent) 
{ 
    .... 
} 

void DrawingCanvas::paintEvent(QPaintEvent& paintEventInfo) 
{ 
    // Result in painter not active 
    QPainter(this); 
    ... 
} 

हालांकि, यह काम करता है। यह देखते हुए कि QGraphicsView QAbstractScrollArea से लिया गया है, फिर QFrame, फिर QWidget, मैं उम्मीद करता हूं कि कोड काम करेगा।

तो मुझे लगता है कि सवाल कर रहे हैं:

1) क्यों है कि मैं एक सक्रिय QPainter पाने के लिए एक QGraphicsView में paintEvent उपयोग नहीं कर सकते है? 2) क्या कोई संभव है कि मैं एक प्राप्त कर सकूं?

अग्रिम धन्यवाद!

उत्तर

15

यदि कोई भी अभी भी सोच रहा है कि यह किसी भी तरह से संभव है, तो जवाब हाँ है।

लघु संस्करण

void DrawingCanvas::paintEvent(QPaintEvent& paintEventInfo) 
{ 
    // Result in painter active 
    QPainter(viewport()); 
    ... 
} 

लांग संस्करण

QGraphicsScene पर कोई पेंटिंग करता है, लेकिन इसके बजाय व्यूपोर्ट विजेट आप इसे या डिफ़ॉल्ट एक QWidget द्वारा देने पर पेंट करता है।

व्यूपोर्ट पर पेंटिंग करके आप ओवरलेड पेंटिंग प्राप्त कर सकते हैं जिसे दृश्य में गठबंधन किया जाएगा, न कि दृश्य। वैकल्पिक रूप से आप QGlWidget और इसके paintOverlayGl() का उपयोग कर सकते हैं।

भी ViewportUpdateMode (QGraphicsView :: FullViewportUpdate) सेट करना याद रखें या आपको प्रतिपादन कलाकृतियां मिलेंगी। हर बार पूरे दृश्य को अपडेट करने के बजाय कलाकृतियों से बचने के लिए एक शानदार तरीका हो सकता है, लेकिन जब तक मुझे प्रदर्शन समस्याओं का सामना नहीं होता है, तो मैं इसे आराम दूंगा।

4

ठीक है, मेरे बालों को थोड़ी देर के लिए खींचने के बाद, यह असंभव प्रतीत होता है, इसलिए मेरा समाधान यहां है। आपके द्वारा खींचा जाने वाला सब कुछ QGraphicsScene में जोड़ा जाना चाहिए; इसलिए आप इससे अपना खुद का कार्यान्वयन प्राप्त करते हैं।

सबसे आसान तरीका लाइनों, आयतों और आदि के लिए एक अस्थायी QGraphicsItem सूचक को परिभाषित करना है जिसे आप आकर्षित करना चाहते हैं।

आभासी माउस दबाए गए(), mouseMove() और mouseRelease() घटना के अनुसार ओवरराइड करें। माउस दबाए गए() पर, temp QGraphicsItem सूचक प्रारंभ करें और इसे दृश्य में जोड़ें।

माउस के अंदर(), तदनुसार temp QGraphicsItem के निर्देशांक सेट करें। माउस के लिए, टेम्पलेट ऑब्जेक्ट की एक प्रति बनाएं और इसे दृश्य में जोड़ें, और दृश्य से temp QGraphicsItem (जिसे आप रेखाचित्र, आयताकार इत्यादि के लिए उपयोग कर रहे हैं) को हटा दें।

मुझे लगता है कि इसका नैतिकता यह है कि QGraphicsView के भीतर कोई QPainter संदर्भ नहीं है, और आप इसके paintEvent() को अनदेखा करने से बेहतर हैं।

आशा है कि इससे किसी ऐसे व्यक्ति की मदद मिलेगी जो इस पर ठोकर खा सकता है।

+1

मैं बस इसी सटीक प्रक्रिया के माध्यम से चला गया>। <आपको लगता है कि वे अस्थायी वस्तुओं को ड्राइंग करना अधिक आसान बना देंगे। हालांकि एक और समाधान है ... overpainting। यदि आप वास्तव में चाहते थे तो आप उस पर एक अदृश्य विजेट ओवरले कर सकते हैं और उस पर पेंट कर सकते हैं। – mpen

1

एक और संभावना है: दृश्य पर drawForeground ओवरराइड करें। आपको जिस प्रकार की वस्तुओं को आकर्षित करने की आवश्यकता है, उसके आधार पर, यह एक बहुत ही सरल समाधान हो सकता है (उदाहरण के लिए, मार्कर लाइनों का ओवरले) या कभी-कभी दृश्य में कस्टम आइटम बनाने से अधिक काम होता है - आपके वांछित परिणामों पर निर्भर करता है।

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