2011-02-08 11 views
5

के साथ आकार बदलने पर स्वचालित छवि स्केलिंग मेरे पास एक GtkImage विजेट एक आकार बदलने योग्य विंडो में है और एक संदर्भ GdkPixBuf छवि को संग्रहीत करना है जिसे मैं GtkImage भरना चाहता हूं।(पीई) जीटीके

मैं GdkPixBuf पैमाने पर इस पद्धति का उपयोग GtkImage विजेट को भरने के लिए कर सकते हैं:

def update_image(self, widget=None, data=None): 
    # Get the size of the source pixmap 
    src_width, src_height = self.current_image.get_width(), self.current_image.get_height() 

    # Get the size of the widget area 
    widget = self.builder.get_object('image') 
    allocation = widget.get_allocation() 
    dst_width, dst_height = allocation.width, allocation.height 

    # Scale preserving ratio 
    scale = min(float(dst_width)/src_width, float(dst_height)/src_height) 
    new_width = int(scale*src_width) 
    new_height = int(scale*src_height) 
    pixbuf = self.current_image.scale_simple(new_width, new_height, gtk.gdk.INTERP_BILINEAR) 

    # Put the generated pixbuf in the GtkImage widget 
    widget.set_from_pixbuf(pixbuf) 

जब मैं update_image फोन मैन्युअल रूप से यह काम करता है के रूप में उम्मीद। अब जब मैं GtkImage विजेट का आकार बदलता हूं तो स्केलिंग स्वचालित रूप से हो जाती है। मेरे साथ आया सबसे अच्छा समाधान update_image विधि को configure-event विंडो की जीटीके घटना से बांधना था। खिड़की के प्रत्येक आकार में परिवर्तन के बाद, छवि वास्तव में ठीक से स्केल किया गया है। हालांकि मेरे पास इस समाधान के साथ दो मुद्दे हैं:

  • मैं केवल खिड़की को बड़ा कर सकता हूं। एक बार छवि को अपस्केल करने के बाद, जीटीके मुझे खिड़की को छोटा आकार देने नहीं देगा क्योंकि खिड़की अपने विगेट्स से छोटी नहीं हो सकती है। मैं समझता हूं कि यह ऐसा क्यों काम करता है लेकिन मुझे नहीं पता कि इस व्यवहार को कैसे बदला जाए।
  • शायद यह कोई बड़ा सौदा नहीं है लेकिन मैं शीर्ष-स्तरीय विंडो के बजाय GtkImage विजेट से एक ईवेंट पसंद करता।

मुझे इस तरह की छोटी समस्या के लंबे स्पष्टीकरण के लिए खेद है, मुझे आशा है कि आप मेरी मदद कर सकेंगे।

उत्तर

9

मेरा मानना ​​है कि आप छवि स्केलिंग के लिए विजेट के expose-event सिग्नल का उपयोग कर सकते हैं। स्क्रॉल करने योग्य कंटेनर में छवि जोड़ने से विंडो आकार बदलने के साथ समस्या को ठीक करना चाहिए। कृपया जांचें कि नीचे एक उदाहरण आपके लिए काम करेगा या नहीं।

import gtk 

class ScaleImage: 
    def __init__(self): 
     self.temp_height = 0 
     self.temp_width = 0 

     window = gtk.Window(gtk.WINDOW_TOPLEVEL) 

     image = gtk.Image() 
     image.set_from_file('/home/my_test_image.jpg') 
     self.pixbuf = image.get_pixbuf() 
     image.connect('expose-event', self.on_image_resize, window)  

     box = gtk.ScrolledWindow() 
     box.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) 
     box.add(image) 

     window.add(box) 
     window.set_size_request(300, 300) 
     window.show_all()   

    def on_image_resize(self, widget, event, window): 
     allocation = widget.get_allocation() 
     if self.temp_height != allocation.height or self.temp_width != allocation.width: 
      self.temp_height = allocation.height 
      self.temp_width = allocation.width 
      pixbuf = self.pixbuf.scale_simple(allocation.width, allocation.height, gtk.gdk.INTERP_BILINEAR) 
      widget.set_from_pixbuf(pixbuf) 

    def close_application(self, widget, event, data=None): 
     gtk.main_quit() 
     return False 

if __name__ == "__main__": 
    ScaleImage() 
    gtk.main() 

आशा है कि यह मदद करता है, का संबंध

+1

बहुत बहुत धन्यवाद, स्क्रॉलडविंडो चाल काम करती है। मुझे एक 'GtkWarning मिलता है: gtk_scrolled_window_add(): गैर स्क्रोल करने योग्य विजेट का उपयोग gtk_scrolled_window_add_with_viewport() इसके बजाय' लेकिन अगर मैं व्यूपोर्ट जोड़ता हूं तो स्क्रॉलबार दिखाई देता है जब मैं खिड़की के आकार को कम कर रहा हूं तो मैं इसे अभी इस तरह छोड़ दूंगा। प्रत्येक gtk पुनरावृत्ति पर 'एक्सपोज़-इवेंट' कहा जाता है, इसलिए यह सीपीयू उपयोग को अधिकतम करता है। – Jim

0

सभी विगेट्स size-allocate संकेत है।

विजेट को नया स्थान आवंटन दिया जाता है जब "आकार आवंटित" संकेत उत्सर्जित होता है।

शायद आप इसका उपयोग कर सकते हैं।

0

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

gboolean drawing_area_draw (GtkWidget *widget, cairo_t *cr, GdkPixbuf *current_image) 
{ 

    ..... //Calculate size 

    pixbuf = gdk_pixbuf_scale_simple (current_image, 
            new_width, 
            new_height, 
            GDK_INTERP_BILINEAR); 

    gdk_cairo_set_source_pixbuf (cr, 
           pixbuf, 
           allocation.width/2 - new_width/2, 
           allocation.height/2 - new_height/2); 
    cairo_paint (cr); 

    return FALSE; 
} 

int main (int argc, char *argv[]) 
{ 
    ..... 

    drawing_area = gtk_drawing_area_new(); 
    g_signal_connect (G_OBJECT (drawing_area), "draw", 
      G_CALLBACK (drawing_area_draw), current_image); 

    ..... 
} 

हैं, तो FALSE को gtk_widget_set_has_window() सेट हालांकि यह शायद बेहतर है अपने खुद के प्राप्त करने के लिए:

मैं अजगर के बारे में पता नहीं है, लेकिन यहां सी में एक उदाहरण GTK3 उपयोग कर रहा है GtkDrawingArea से विजेट और इस संपत्ति को अपने init फ़ंक्शन में सेट करें।

आप GTK2 उपयोग कर रहे हैं, कोड को छोड़कर आप widget->window पर gdk_cairo_create() फोन और cairo_destroy() फोन काम पूरा हो जाने के लिए है कि इसी तरह की है,।

इसके अलावा, GTK2 साथ, अगर GtkDrawingArea अपनी ही GdkWindow नहीं है, ड्राइंग के लिए निर्देशांक माता पिता GdkWindow बजाय विजेट के सापेक्ष हैं।