2

有一段时间我一直试图在滚动窗口上放置一个绘图区域。我一直在阅读有关 pygtk 和 C 解决方案的文章,但我认为它们不适用于 pyGobject。

我做了一个最小的例子:

from gi.repository import Gtk, Gdk
import cairo

class Test(Gtk.Window):

    def __init__(self):
        Gtk.Window.__init__(self)
        sw=Gtk.ScrolledWindow()
        vp=Gtk.Viewport()
        box=Gtk.VBox()

        vp.set_size_request(100,100)

        for i in range(3):
            da=Gtk.DrawingArea()
            da.connect("draw", self.draw, [0.3, 0.4, 0.6], da)
            da.set_size_request(100,100)
            box.add(da)

        sw.add(vp)
        vp.add(box)        
        self.add(sw)
        self.show_all()

    def draw(self, widget, event, color, da):
        cr = widget.get_property('window').cairo_create()
        cr.rectangle(0, 0, 100, 100)
        cr.set_source_rgb(color[0], color[1], color[2])
        cr.fill()

main=Test()
Gtk.main()

所以问题是绘图区域并不总是被渲染。例如,一个 gtk2 工作代码:

import gtk, cairo

class Test(gtk.Window):

    def __init__(self):
        gtk.Window.__init__(self)
        sw=gtk.ScrolledWindow()
        vp=gtk.Viewport()
        box=gtk.VBox()

        for i in range(3):
            da=gtk.DrawingArea()
            da.connect("expose-event", self.draw, [0.3, 0.4, 0.6], da)
            box.add(da)

        sw.add(vp)
        vp.add(box)        
        self.add(sw)
        self.show_all()

    def draw(self, widget, event, color, da):
        cr = widget.get_property('window').cairo_create()
        cr.rectangle(0, 0, 100, 100)
        cr.set_source_rgb(color[0], color[1], color[2])
        cr.fill()

main=Test()
gtk.main()

请不要指给我看下面的文章,我已经看了好几遍了!

我已经添加了viewportand a size_request,还有什么可能会丢失?

谢谢您的帮助!

4

2 回答 2

2

由 Emmanuele 通过 Gtk 邮件列表:

from gi.repository import Gtk, Gdk
import cairo

class Test(Gtk.Window):

    def __init__(self):
        Gtk.Window.__init__(self)
        sw=Gtk.ScrolledWindow()
        vp=Gtk.Viewport()
        box=Gtk.VBox()

        vp.set_size_request(100,100)

        for i in range(3):
            da=Gtk.DrawingArea()
            da.connect("draw", self.draw, [0.3, 0.4, 0.6])
            da.set_size_request(100,100)
            box.add(da)

        sw.add(vp)
        vp.add(box)        
        self.add(sw)
        self.show_all()

    def draw(self, widget, cr, color):
        cr.rectangle(0, 0, 100, 100)
        cr.set_source_rgb(color[0], color[1], color[2])
        cr.fill()
        cr.queue_draw_area(0, 0, 100, 100)

        return True

main=Test()
Gtk.main()

您应该阅读 GTK+ 3.x 的 API 参考:

https://developer.gnome.org/gtk/stable

以及 Python API 参考:

http://lazka.github.io/pgi-docs/#Gtk-3.0

于 2015-05-06T10:54:43.040 回答
0

您可以添加损坏区域并强制重绘,我稍微修改了您的示例(对不起,我无法抗拒修复一些事情)并添加 queue_draw_area

我强烈建议避免使用 Gtk.DrawingArea 并改用画布小部件,在画布上绘图更容易,GooCanvas 是一个很好的例子,但还有很多其他的你可以使用。

from gi.repository import Gtk, Gdk
import math, cairo

class Test(Gtk.Window):

    def __init__(self):
        Gtk.Window.__init__(self)
        sw=Gtk.ScrolledWindow()
        box=Gtk.VBox()

        for i in range(3):
            da=Gtk.DrawingArea()
            da.connect("draw", self.draw, [0.3, 0.4, 0.6], da)
            da.set_size_request(100,100)
            box.pack_start(da, True, True, 10)

        sw.add(box)
        self.add(sw)

        self.connect("destroy", Gtk.main_quit)
        self.show_all()

    def draw(self, widget, event, color, da):
        cr = widget.get_property('window').cairo_create()
        lg1 = cairo.LinearGradient(0.0, 0.0, 100, 0)
        lg1.add_color_stop_rgb(0, color[0], color[1], color[2])
        lg1.add_color_stop_rgb(1, color[0], color[1], color[2])
        cr.rectangle(0, 0, 100, 100)
        cr.set_source(lg1)
        cr.fill()
        da.queue_draw_area(0, 0, 100, 100)

main=Test()
Gtk.main()
于 2015-05-02T19:14:33.667 回答