如何在 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 中更新(绘制)一个小部件和仅这个小部件的主要内容,如果未能解决你的问题,请参考以下文章

如何更改 GTK 容器小部件的大小?

如何计算存储在 Gtk::Grid 中的小部件?

GTK 或 Qt 的图表小部件 [关闭]

TreeViewColumn标头中的PyGTK Entry小部件

如何访问存储在 Gtk::Box / Gtk::Grid 中的 [i] 处的小部件?

如何控制在树的展开行中可见哪些 GTK 小部件?