1

Vala でカスタム GTK ウィジェットを作成しようとしていますが、最初の基本的な試みですでに失敗しているため、どこが間違っているのかを知るために助けが必要です。骨の折れるほど明白な何かを見逃しているに違いないと感じていますが、それを見ることができません。

次の内容の 3 つのファイルがあります。

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;
        }
}

main_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 には 2 つのコード セットがあります。Entry ウィジェットを直接追加するものと、カスタム ウィジェットを追加するものです。Entry ウィジェットを直接追加するものを実行すると、次の結果が得られます。

機能しているウィジェット

ただし、カスタム ウィジェットを使用して実行すると、次の結果が得られます。

ウィジェットの不具合

記録のために、これは私が使用する複雑なコマンドです。

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

編集:

user4815162342 の提案に従って、次のsize_allocateようにカスタム Bin ウィジェットにメソッドを実装しました。

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

ウィンドウは次のようにレンダリングされます。

部分的に機能するウィジェット

4

1 に答える 1

2

GtkBin通常、何らかの方法で子ウィジェットを装飾したり、その可視性やサイズを変更したりすることを目的とした、単一の子の抽象的なコンテナーです。何らかの付加価値がなければ、単一の子コンテナはそれに含まれるウィジェットと区別がつかないため、あまり役に立ちません。

GtkBinは、子の周りにどのような装飾を描画するかを知らないため、独自の を実装することを期待していますsize_allocate。簡単な実装は でgtk_event_area_size_allocate、より複雑な実装は で利用できますgtk_button_size_allocate

この回答は、Vala に簡単に移植できる PyGTK での最小限のsize_allocate実装を示しています。それよりも複雑なことを行う場合はexpose、 や、場合によっては他のメソッドも実装する必要がありますが、これで作業を開始できます。

于 2013-04-07T09:18:56.473 に答える