【问题标题】:Custom GTK widget in Vala not workingVala 中的自定义 GTK 小部件不起作用
【发布时间】:2013-04-07 08:50:49
【问题描述】:

我正在尝试在 Vala 中制作自定义 GTK 小部件,但我已经在第一次基本尝试中失败了,所以我想知道我哪里出错了。我觉得我一定遗漏了一些非常明显的东西,但我就是看不到。

我有三个文件,内容如下:

start.vala

using Gtk;

namespace WTF
{
        MainWindow main_window;

        int main(string[] args)
        {
                Gtk.init(ref args);
                main_window = new MainWindow();
                Gtk.main();
                return 0;
        }
}

ma​​in_window.vala

using Gtk;

namespace WTF
{
        public class MainWindow : Window
        {
                public MainWindow()
                {
                        /* */
                        Entry entry = new Entry();
                        entry.set_text("Yo!");
                        this.add(entry);
                        /* */

                        /* 
                        CustomWidget cw = new CustomWidget();
                        this.add(cw);
                        /* */

                        this.window_position = WindowPosition.CENTER;
                        this.set_default_size(400, 200);
                        this.destroy.connect(Gtk.main_quit);

                        this.show_all();
                }
        }
}

custom_widget.vala

using Gtk;

namespace WTF
{
        public class CustomWidget : Bin
        {
                public CustomWidget()
                {
                        Entry entry = new Entry();
                        entry.set_text("Yo");
                        this.add(entry);
                        this.show_all();
                }
        }
}

如您所见,在 main_window.vala 中,我有两组代码。一种是直接添加 Entry 小部件,另一种是添加我的自定义小部件。如果你运行直接添加 Entry 小部件的那个,你会得到这样的结果:

但是,如果您使用自定义小部件运行该小部件,则会得到以下结果:

仅作记录,这是我使用的复杂命令:

valac --pkg gtk+-2.0 start.vala main_window.vala custom_widget.vala -o wtf

编辑:

按照 user4815162342 的建议,我在自定义 Bin 小部件上实现了 size_allocate 方法,如下所示:

public override void size_allocate(Gdk.Rectangle r)
{
        stdout.printf("Size_allocate: %d,%d ; %d,%d\n", r.x, r.y, r.width, r.height);
        Allocation a = Allocation() { x = r.x, y = r.y, width = r.width, height = r.height };
        this.set_allocation(a);

        stdout.printf("\tHas child: %s\n", this.child != null ? "true" : "false");
        if (this.child != null)
        {
                int border_width = (int)this.border_width;
                Gdk.Rectangle cr = Gdk.Rectangle()
                {
                        x = r.x + border_width,
                        y = r.y + border_width,
                        width = r.width - 2 * border_width,
                        height = r.height - 2 * border_width
                };
                stdout.printf("\tChild size allocate: %d,%d ; %d, %d\n", cr.x, cr.y, cr.width, cr.height);
                this.child.size_allocate(cr);
        }
}

它在控制台中写入以下内容:

Size_allocate: 0,0 ; 400,200
        Has child: true
        Child size allocate: 0,0 ; 400, 200

窗口就这样渲染了:

【问题讨论】:

    标签: widget gtk vala


    【解决方案1】:

    GtkBin 是一个抽象的单子容器,通常用于以某种方式装饰子小部件,或更改其可见性或大小。如果没有一些附加值,单子容器将无法与它包含的小部件区分开来,因此不是很有用。

    由于GtkBin不知道你会在孩子周围画什么样的装饰,它希望你实现自己的size_allocategtk_event_area_size_allocate 提供了一个简单的实现,gtk_button_size_allocate 提供了一个更复杂的实现。

    This answer 显示了 PyGTK 中最小的size_allocate 实现,应该可以直接移植到 Vala。如果你做了比这更复杂的事情,你还需要实现expose,可能还有其他方法,但这会让你开始。

    【讨论】:

    • 谢谢,我完全不知道 GtkBin 小部件作为一个通用容器本身是无用的。根据您所说,我决定改为从 GtkEventBox 继承,并且一切似乎都非常出色。我尝试通过您在 Vala 中的链接实现最小 size_allocate,但结果并不好,呵呵。
    • @Alex 你不能实例化它在某种程度上是一种赠品。 :) GtkEventBox 提供了更温和的介绍,但它确实带有一些您不需要的附加功能。它还强制容器使用 GDK 窗口,如果不需要,这是一种浪费。一旦您对小部件的低级工作更加精通,您可能想回到GtkBin
    • 是的,我可能会在稍后的某个时间试一试……没有设法实现 size_allocate 有点令人失望。我 99% 确定我做了 Python 版本所做的事情,但是当我的版本渲染时,我看到的只是一条细线而不是输入文本框。
    • @Alex 你有没有尝试添加一些打印来帮助你调试出了什么问题?
    • 是的,我使用的值似乎没有任何问题......这些数字是明智的,我基本上只是将它们设置在自己身上(使用 set_allocation(...))然后传递它们到子小部件(使用 child.size_allocate(...)),但就像我说的那样,它最终只是出于某种原因渲染了一条线......(我确实也包括了border_width 计算,尽管这些数字都是0,所以它实际上并没有改变分配的大小。)我将编辑我的问题以包含该代码,你可以看看。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多