2012-04-22 8 views
6

का उपयोग करके एक GdkPixbuf को कैसे आकर्षित करें मेरे पास एक छोटा सा एप्लिकेशन है जो PyGObject और GTK3 का उपयोग करके एक साधारण मानचित्र खींचने के लिए DrawingArea का उपयोग करता है।GTK3 और PyGObject

मैं एक Pixbuf लोड

from gi.repository import Gtk, GdkPixbuf 
pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_size("logo.png", 25, 25) 

का उपयोग कर और फिर DrawingArea की घटना संकेत

def draw(self, widget, context): 
    window = widget.get_window() 
    ctx = window.cairo_create() 
    ctx.set_source_pixbuf(pixbuf, 0, 0) 

आकर्षित में यह आकर्षित करने के लिए कोशिश, लेकिन मैं त्रुटि संदेश मिलता है

"AttributeError: 'cairo.Context' object has no attribute 'set_source_pixbuf'" 

अगर मैं Gtk2 to Gtk3 migration guide सही ढंग से पढ़ रहा हूं, तो यह काम करना चाहिए। मैं क्या गलत कर रहा हूँ?

def draw(self, widget, context): 
    Gdk.cairo_set_source_pixbuf(context, self.pixbuf, 0, 0) 
    context.paint() 

एक सवाल अभी भी बना हुआ: यह काम करने के लिए पसंदीदा तरीका है

+0

क्या आप वाकई get_window से कुछ drawable वापस हो रही है कर रहे हैं ? – stark

+0

हां, मुझे 0xb71aab44 पर एक 'ऑब्जेक्ट बैक, इसलिए ड्रॉइंग एरिया विजेट एहसास हुआ है। मुझे लगता है कि जीटीके 3 में पिक्सबफ्स को कैसे आकर्षित करना है, इस बारे में एक नुकसान हुआ है। – gnirx

उत्तर

9

नई संकेत आकर्षित एक कॉलबैक कि पहले से ही एक पैरामीटर के रूप काहिरा संदर्भ गुजरता का उपयोग करता है, तो आप window = widget.get_window() की तरह सामान क्या करने की जरूरत नहीं है जैसे आप PyGTK में किया था काहिरा संदर्भ पाने के लिए बेनकाब घटना में भाग लेने जबकि सिग्नल। PYGObject में सरल है:

import cairo 

class Foo(object): 
    def __init__(self): 

     (...) 
     self.image = cairo.ImageSurface.create_from_png('logo.png') 
     (...) 

    def draw(self, widget, context): 
     if self.image is not None: 
      context.set_source_surface(self.image, 0.0, 0.0) 
      context.paint() 
     else: 
      print('Invalid image') 
     return False 

अगर आप जरूर की आवश्यकता नहीं है यही कारण है, लेकिन यदि आप इसे कुछ के लिए की जरूरत है वरना आप कई विकल्प हैं:

  1. स्मृति में दोनों वस्तुओं करवाने के लिए। यदि दोनों पीएनजी से लोड होते हैं तो स्मृति की बर्बादी के अलावा अन्य समस्याएं नहीं होनी चाहिए।
  2. GdkPixbuf को पीआईएल छवि में कनवर्ट करें, फिर पीआईएल छवि डेटा सरणी में कनवर्ट करें और फिर create_for_data() का उपयोग करके उस डेटा सरणी से एक काहिरा ImageSurface बनाएं। याक: एस मुझे बेहतर नहीं पता, क्षमा करें: एस
  3. का उपयोग करें Gdk.cairo_set_source_pixbuf() हॉक द्वारा प्रस्तावित। ऐसा लगता है कि एक छविसर्फ़ेस में पिक्सबफ खींचने का सही तरीका है, लेकिन यह पूरी तरह से अवांछित है (और यही कारण है कि मैं इस आत्मनिरीक्षण सामग्री से नफरत करता हूं, सी जैसे सभी खराब सी बंदरगाह की तरह दिखते हैं)।

    import Image 
    import array 
    from gi.repository import Gtk, GdkPixbuf 
    
    width = 25 
    height = 25 
    pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_size('logo.png', width, height) 
    pil_image = Image.fromstring('RGBA', (width, height), pixbuf.get_pixels()) 
    byte_array = array.array('B', pil_image.tostring()) 
    cairo_surface = cairo.ImageSurface.create_for_data(byte_array, cairo.FORMAT_ARGB32, width, height, width * 4) 
    

    ध्यान दें कि create_for_data()not yet available for Python3, only for Python2 है:

आप यहाँ भयंकर दूसरा विकल्प चुनते हैं कि कैसे है।

चेक भी अगर यह आप क्या हासिल करने की कोशिश कर रहे हैं कि कैसे PyGObject में एक डबल बफर का उपयोग करने पर मेरा उत्तर: Drawing in PyGobject (python3)

तरह का संबंध

+0

धन्यवाद। यह मेरे विभिन्न प्रयासों की तुलना में जीटीके 3 में ग्राफिक्स को संभालने का एक बहुत ही सशक्त तरीका प्रतीत होता है;) – gnirx

+2

+1 "लेकिन यह पूरी तरह से अवांछित है (और यही कारण है कि मैं इस आत्मनिरीक्षण सामग्री से नफरत करता हूं, सी जैसे सभी खराब सी बंदरगाह की तरह दिखते हैं)। " – xubuntix

6

निम्नलिखित काम करने के लिए लगता है?

+1

मेरा प्रोग्राम "cairo_set_source_pixbuf'' किसी भी मदद को निष्पादित करने के बाद" सेगमेंटेशन दोष "उत्पन्न करता है? –

+0

जीटीके डॉक्टर में वे कहते हैं, "सावधान रहें, यह कार्य कैरो से नहीं है ..."। मुझे इस से ऊपर का जवाब चाहिए, लेकिन ऐसा लगता है कि इसे +1 करने के लिए और अधिक रचनात्मक है। जीटीके 3 चीजों का एक अलग तरीका है, यह कैरो का उपयोग करता है और हैंडलर को सतह पर वापस देता है, इसलिए ऐसा न करें जैसे कि यह एक बाहरी उपकरण है: जहां चित्र खींचे जाते हैं। – cox

+1

@ आकाशशेंडे - मुझे '.cairo_get_source_pixbuf' का उपयोग करके सेगमेंटेशन गलती भी मिल रही है, क्या आप इसे ठीक करने का तरीका समझते हैं? – nluigi

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