簡體   English   中英

如何使用GTK3和PyGObject繪制GdkPixbuf

[英]How to draw a GdkPixbuf using GTK3 and PyGObject

我有一個小應用程序,它使用DrawingArea使用PyGObjectGTK3繪制一個簡單的地圖。

我使用加載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到Gtk3遷移指南 ,這應該可行。 我究竟做錯了什么?

新的繪制信號使用已經將cairo上下文作為參數傳遞的回調,你不需要像在PyGtk中那樣做像window = widget.get_window()這樣的東西來獲取cairo上下文,同時參加expos -event信號。 在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

也就是說,如果您不需要PixBuf,但如果您需要其它的東西,您有幾個選擇:

  1. 將兩個對象都放在內存中。 如果兩者都是從PNG加載的,那么除了浪費內存之外,應該沒有太多問題。
  2. 將GdkPixbuf轉換為PIL Image,然后將PIL Image轉換為數據數組,然后使用create_for_data()從該數據數組創建Cairo ImageSurface。 氂牛:SI不知道更好,對不起:S
  3. 使用hock提出的Gdk.cairo_set_source_pixbuf() 這似乎是在ImageSurface中繪制Pixbuf的正確方法,但它完全是unpythonic(這就是為什么我討厭這個Introspection的東西,所有看起來像C,就像一個壞的C端口)。

如果你選擇了糟糕的第二個選項,那么如何:

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() 尚不適用於Python3僅適用於Python2

如果這是你想要實現的,請查看我在PyGObject中如何使用雙緩沖區的答案: 在PyGobject中繪圖(python3)

親切的問候

以下似乎做了這個工作:

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

一個問題仍然存在:這是首選的做事方式嗎?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM