C#Gtk获得渲染大小

时间:2015-06-26 16:06:44

标签: c# mono gtk gtk#

在Gtk#中(使用Mono),我有时需要将默认大小分配给widget(我知道你是通过widget.SetSizeRequest(-1, -1);来做的。如果这不是正确的方法请有人纠正我)。我这样做是为了确保Button窗口小部件的大小与预期一致。我不希望它太大或太小。分配默认大小可确保按钮不会太大但也不会太小。

因此,当我为窗口小部件分配默认大小时,widget.GetSizeRequest(out width, out height);分别为宽度和高度返回-1和-1。
这是预期但不是我需要的。我需要知道渲染的大小(单独的宽度和高度),因为我需要放置相对于它的另一个小部件。因此,除非我知道它的大小,否则我无法将其他小部件放在正确的位置。

虽然在其他情况下,了解渲染大小会有所帮助,但这是主要原因。

我希望你能理解渲染大小的含义。

更新:
由于答案似乎建议使用widget.Allocation虽然我已尝试过(请参阅我的评论),但这是我尝试的内容:

Widget[] widgets = GetWidgets();//I initialize the widgets somewhere and get them as an array

//fix is a Gtk.Fixed container
foreach(Widget widget in widgets)
{
    //although this is not the exact way I place the widgets, this is just an example
    fix.Put(widget, GetPosition(widget).X, GetPosition(widget).Y);
    widget.SetSizeRequest(-1, -1);
    Console.WriteLine(w.Allocation.Size);
}
//later on, I need to place a few widgets relative to another

此代码的输出为:

{Width=1, Height=1}
{Width=1, Height=1}
{Width=1, Height=1}
{Width=1, Height=1}
{Width=1, Height=1}
{Width=1, Height=1}

但是,当我在Allocation的{​​{1}}事件中打印Button的{​​{1}}小部件时,会按预期打印呈现的大小。但是,在上面的场景中,它只打印1和1 谁能确定我做错了什么?

3 个答案:

答案 0 :(得分:1)

您正在查找Allocation属性(gtk中的get_allocation)。

示例:

protected void OnButton2Clicked (object sender, EventArgs e)
{
    var rect = button.Allocation;
    PropertyInfo[] properties = rect.GetType().GetProperties();
    var sb = new System.Text.StringBuilder();
    foreach (PropertyInfo pi in properties)
    {
        sb.Append(
            string.Format("Name: {0} | Value: {1}\n", 
                pi.Name, 
                pi.GetValue(rect, null)
            ) 
        );
    }
    Console.WriteLine (sb);
}

<强>输出:

Name: GType | Value: GdkRectangle
Name: Top | Value: 50
Name: Bottom | Value: 82
Name: Right | Value: 69
Name: Left | Value: 30
Name: IsEmpty | Value: False
Name: Size | Value: {Width=40, Height=33}
Name: Location | Value: (30,50)

<强>更新

尚未呈现的窗口小部件(包括Visible = false)没有任何容器分配,因为它不需要任何容器分配,因此对于其余的可见窗口小部件将正确打包。

Name: GType | Value: GdkRectangle
Name: Top | Value: -1
Name: Bottom | Value: -1
Name: Right | Value: -1
Name: Left | Value: -1
Name: IsEmpty | Value: False
Name: Size | Value: {Width=1, Height=1}
Name: Location | Value: (-1,-1)

如果你真的需要一个真正的渲染大小(使用当前字体,边框等...),你需要在某处渲染它。一个真正的黑客将它放在一个双缓冲的固定容器上并“渲染”它但从不显示它。从中获取并保存分配(可能在字典中),删除小部件并为下一个小部件执行。现在你有一个小部件大小的字典,它与当前的运行时环境相匹配......就像我说的那样,真正的黑客......

同样问这个问题Gtk标记的C语言问题,或者在他们的邮件列表上,可能会给你一个更好的答案,他们的答案将是C vs C#,根据需要进行转换。请务必提及您需要在Gtk2中执行此操作,因为Gtk3 真的不同。

答案 1 :(得分:0)

您要查找的内容是widget.Allocation,但大小仅在Expose事件中设置。这为您提供了窗口小部件的渲染大小。我猜你也在使用固定容器。 widget.SetSizeRequest(-1, -1)清除任何编程的大小调整,让Gtk库按照大小执行所需的操作。除非您确实需要严格控制放置每个小部件的位置,否则最好使用VBox和HBox等容器。 Gtk的一个优点是它为你做了很多更精细的小部件对齐。

修改

您可以一次绘制一个小部件。它的那种“递归”。一旦Gtk运行时调用了公开事件处理程序,就会确定窗口小部件的大小,以便您可以使用它来放置下一个窗口小部件。这是一个非常简化的示例,它在向下的对角线上绘制三个按钮。

int idx;
string[] userDefinedText;
Fixed fix;

public MainWindow () : base (Gtk.WindowType.Toplevel) {
    Build ();

    // I'm not really sure how you store the text or just a list of widgets 
    // but for the sake of simplicity I'm just using a string array
    idx = 0;
    userDefinedText = new string[3] { "Medium text length", "Long text that goes on and on", "Short" };

    fix = new Fixed ();
    fix.SetSizeRequest (400, 400);
    Add (fix);
    fix.Show ();

    Button b = new Button ();
    b.SetSizeRequest (-1, -1);
    b.Label = userDefinedText [idx];
    b.ExposeEvent += OnButtonExposeEvent;
    fix.Put (b, 5, 5);
    b.Show ();

    ShowAll ();
}

protected void OnButtonExposeEvent (object sender, ExposeEventArgs args) {
    if (idx < (userDefinedText.Length - 1)) {
        // There are still widgets to be placed on the screen
        ++idx;

        Button b = sender as Button;
        int x = b.Allocation.Right;
        int y = b.Allocation.Bottom;

        Button b2 = new Button ();
        b2.SetSizeRequest (-1, -1);
        b2.Label = userDefinedText [idx];
        b2.ExposeEvent += OnButtonExposeEvent;
        fix.Put (b2, x + 5, y + 5);
        b2.Show ();
    }
}

答案 2 :(得分:0)

最后一点,只有你使用的是GTK + 3:

我真的不知道你想要获得什么样的尺寸,如果你正在实现自己的容器并希望看到小部件想要的大小(在比RobertN的“真正的黑客”更好的方法是使用首选尺寸系统。 GTK + 3有get_preferred_width()get_preferred_height()等方法,它们都返回最小值(绝对最小值,因此只是标签的宽度...)和自然(小部件更喜欢的大小,以保持其每个部分可见)大小,你可以使用;看看哪一个更适合你的用例。高度宽度和高度宽度几何等效(如果您决定这样做)。

我不知道在C#中调用这些方法是什么。