如何在 GTK 中更新(绘制)一个小部件和仅这个小部件
Posted
技术标签:
【中文标题】如何在 GTK 中更新(绘制)一个小部件和仅这个小部件【英文标题】:How to update (draw) a widget and only this widget in GTK 【发布时间】:2021-05-11 12:12:12 【问题描述】:例如,当我有以下小部件层次结构时:
窗口 盒子 绘图区 1 绘图区 2然后我在绘图区 1 上调用 queue_draw,然后绘图区 2 也被更新(绘图)。这种行为是有意的吗?出于性能原因,我是否可以阻止这种行为并且只更新绘图区 1。
编辑:添加了一个最小示例:
#!/usr/bin/env python3
import pgi
pgi.require_version('Gtk', '3.0')
from pgi.repository import Gtk, Gdk, GdkPixbuf
import cairo
class DrawingArea(Gtk.DrawingArea):
def __init__(self, id):
super().__init__()
self.id = id
self.vexpand = True
self.hexpand = True
self.connect("draw", self.on_draw)
def on_draw(self, area, context):
print ("on_draw ", self.id)
context.set_source_rgb (1, 0, 0)
context.rectangle (0,0,20,20)
context.fill ()
return False
class Window(Gtk.Window):
def __init__(self):
Gtk.Window.__init__(self)
self.set_title("Test Draw Radial Gradient")
self.set_default_size(400, 200)
self.connect("destroy", Gtk.main_quit)
self.drawingArea1 = DrawingArea (1)
self.drawingArea2 = DrawingArea (2)
box = Gtk.Box ()
box .pack_start (self.drawingArea1, True, True, 0)
box .pack_start (self.drawingArea2, True, True, 0)
button = Gtk.Button.new_with_label("Click Me")
box .pack_start (button, True, True, 0)
button.connect("clicked", self.on_click_me_clicked)
self.add(box)
def on_click_me_clicked(self, button):
print ("Button clicked")
self.drawingArea1.queue_draw()
window = Window()
window.show_all()
Gtk.main()
【问题讨论】:
请发布一个最小且可重现的示例,以便我们自己测试。 添加示例@BobMorane。 【参考方案1】:除非我误解了 Gtk 源代码,否则这是某种预期行为。 queue_draw
导致部分窗口失效,并递归更新小部件。最有可能(这只是猜测!)它告诉box
被重绘并且框重绘它所有的孩子。
无论如何,您的小部件应该随时可以重绘。如果用户调整窗口大小 - 很多重绘。如果他最小化并带回窗口——那就是另一个重绘。
首先,确保您的重绘是一个真正的瓶颈。其次,我建议实现某种缓存或代理:与小部件大小相同的 cairo 表面,当您的数据发生更改时,您将其绘制在那里,并且在重绘时您只需在小部件的表面上绘制该表面。另一种方法是在另一个线程中准备可绘制对象(如果您使用 python,这会产生问题),但同样:从一些测量开始,看看重绘是否真的很慢。
【讨论】:
以上是关于如何在 GTK 中更新(绘制)一个小部件和仅这个小部件的主要内容,如果未能解决你的问题,请参考以下文章
TreeViewColumn标头中的PyGTK Entry小部件