滚动窗口上的 GTK3+ (3.14) 绘图区
GTK3+ (3.14) drawing area on scrolledwindow
一段时间以来,我一直在尝试将绘图区域放在滚动的 window 上。我一直在阅读有关 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()
以下文章请不要点我,我已经看了好几遍了!
我添加了 viewport
和一个 size_request
,还缺少什么?
感谢您的帮助!
你可以添加一个损坏区域并强制重绘,我稍微修改了你的例子(抱歉我无法抗拒修复一些东西)并添加 queue_draw_area
我强烈建议避免使用 Gtk.DrawingArea 并改用 canvas 小部件,在 canvas 上绘图更容易,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()
来自 Gtk 邮件列表的 Emmanuele:
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+ 的 API 参考 3.x:
https://developer.gnome.org/gtk/stable
以及 Python API 参考:
一段时间以来,我一直在尝试将绘图区域放在滚动的 window 上。我一直在阅读有关 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()
以下文章请不要点我,我已经看了好几遍了!
我添加了 viewport
和一个 size_request
,还缺少什么?
感谢您的帮助!
你可以添加一个损坏区域并强制重绘,我稍微修改了你的例子(抱歉我无法抗拒修复一些东西)并添加 queue_draw_area
我强烈建议避免使用 Gtk.DrawingArea 并改用 canvas 小部件,在 canvas 上绘图更容易,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()
来自 Gtk 邮件列表的 Emmanuele:
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+ 的 API 参考 3.x:
https://developer.gnome.org/gtk/stable
以及 Python API 参考: