使用 HeaderBar Python 和 Gtk3 在透明 window 上绘画
Paint on Transparent window with HeaderBar Python and Gtk3
我对下面的代码有点问题。它创建了一个 GtkWindow,使其可绘制,这样我就可以在绘制事件中使用 cairo 在其上绘制。然后我添加一个 GtkHeaderBar 和一个简单的按钮小部件。
from gi.repository import Gtk
import cairo
def draw_callback(widget,cr):
if widget.transparency:
cr.set_source_rgba(0,0,0,0.5)
else:
cr.set_source_rgb(0,0,0)
cr.set_operator(cairo.OPERATOR_SOURCE)
cr.paint()
cr.set_operator(cairo.OPERATOR_OVER)
win= Gtk.Window()
win.connect('delete-event', Gtk.main_quit)
win.set_app_paintable(True)
screen = win.get_screen()
visual = screen.get_rgba_visual()
win.transparency = False
if visual and screen.is_composited():
win.set_visual(visual)
win.transparency = True
else:
print('System doesn\'t support transparency')
win.set_visual(screen.get_system_visual)
win.connect('draw', draw_callback)
win.add(Gtk.Button(label='test'))
bar = Gtk.HeaderBar(title='title')
bar.set_has_subtitle(False)
bar.set_show_close_button(True)
win.set_titlebar(bar)
win.show_all()
Gtk.main()
draw_callback 绘制 window 背景,但这个背景看起来像这样:
cairo 上下文的大小与 window 不同。 window 之外的绘制部分似乎不响应鼠标事件(例如,我无法从该部分获取 window)
如果我不使用HeaderBar,我就没有这个问题。
这适用于 ruby 2.2 和 Gtk3 绑定。
我的 python 版本是 python 3 和最新的 Gtk 模块
编辑:
问题仍然存在:
def size_allocation_cb(widget, rectangle):
widget.x = rectangle.x
widget.y = rectangle.y
widget.width = rectangle.width
widget.height = rectangle.height
win.connect('size-allocate', size_allocation_cb)
def draw_callback(widget,cr):
if widget.transparency:
cr.set_source_rgba(0,0,0,0.5)
else:
cr.set_source_rgb(0,0,0)
cr.set_operator(cairo.OPERATOR_SOURCE)
cr.rectangle(widget.x, widget.y, widget.width, widget.height)
cr.fill()
cr.set_operator(cairo.OPERATOR_OVER)
当你有一个 header 栏时,你的 window 完全在客户端绘制,包括阴影(出于某种原因)。您将需要调用 cairo_rectangle()
或其他一些函数,最好使用 GtkWindow 的 child 的大小分配(而不是大小请求!),以将 cairo_paint()
剪辑到正确的大小。
我对下面的代码有点问题。它创建了一个 GtkWindow,使其可绘制,这样我就可以在绘制事件中使用 cairo 在其上绘制。然后我添加一个 GtkHeaderBar 和一个简单的按钮小部件。
from gi.repository import Gtk
import cairo
def draw_callback(widget,cr):
if widget.transparency:
cr.set_source_rgba(0,0,0,0.5)
else:
cr.set_source_rgb(0,0,0)
cr.set_operator(cairo.OPERATOR_SOURCE)
cr.paint()
cr.set_operator(cairo.OPERATOR_OVER)
win= Gtk.Window()
win.connect('delete-event', Gtk.main_quit)
win.set_app_paintable(True)
screen = win.get_screen()
visual = screen.get_rgba_visual()
win.transparency = False
if visual and screen.is_composited():
win.set_visual(visual)
win.transparency = True
else:
print('System doesn\'t support transparency')
win.set_visual(screen.get_system_visual)
win.connect('draw', draw_callback)
win.add(Gtk.Button(label='test'))
bar = Gtk.HeaderBar(title='title')
bar.set_has_subtitle(False)
bar.set_show_close_button(True)
win.set_titlebar(bar)
win.show_all()
Gtk.main()
draw_callback 绘制 window 背景,但这个背景看起来像这样:
cairo 上下文的大小与 window 不同。 window 之外的绘制部分似乎不响应鼠标事件(例如,我无法从该部分获取 window)
如果我不使用HeaderBar,我就没有这个问题。
这适用于 ruby 2.2 和 Gtk3 绑定。
我的 python 版本是 python 3 和最新的 Gtk 模块
编辑:
问题仍然存在:
def size_allocation_cb(widget, rectangle):
widget.x = rectangle.x
widget.y = rectangle.y
widget.width = rectangle.width
widget.height = rectangle.height
win.connect('size-allocate', size_allocation_cb)
def draw_callback(widget,cr):
if widget.transparency:
cr.set_source_rgba(0,0,0,0.5)
else:
cr.set_source_rgb(0,0,0)
cr.set_operator(cairo.OPERATOR_SOURCE)
cr.rectangle(widget.x, widget.y, widget.width, widget.height)
cr.fill()
cr.set_operator(cairo.OPERATOR_OVER)
当你有一个 header 栏时,你的 window 完全在客户端绘制,包括阴影(出于某种原因)。您将需要调用 cairo_rectangle()
或其他一些函数,最好使用 GtkWindow 的 child 的大小分配(而不是大小请求!),以将 cairo_paint()
剪辑到正确的大小。