运行 时 GTK# 图像按钮不显示图像

GTK# Image Buttons not showing Images when Running

我正在尝试在 GTK# (Xamarin Studio) 中使用图像按钮。我将图像设置为按钮,然后在 UI 生成器中显示图像。

但是当我 运行 程序时按钮中没有图像

我在 IDE 的不同版本和不同平台(Mac 和 Windows)上尝试过

请帮忙

更新: MainWindow.cs

using System;
using Gtk;

public partial class MainWindow: Gtk.Window
{
    public MainWindow () : base (Gtk.WindowType.Toplevel)
    {
        Build ();
    }

    protected void OnDeleteEvent (object sender, DeleteEventArgs a)
    {
        Application.Quit ();
        a.RetVal = true;
    }
}

gtk-gui 文件夹中我可以找到这些文件

generated.cs

// This file has been generated by the GUI designer. Do not modify.
namespace Stetic
{
    internal class Gui
    {
        private static bool initialized;

        internal static void Initialize (Gtk.Widget iconRenderer)
        {
            if ((Stetic.Gui.initialized == false)) {
                Stetic.Gui.initialized = true;
            }
        }
    }

    internal class IconLoader
    {
        public static Gdk.Pixbuf LoadIcon (Gtk.Widget widget, string name, Gtk.IconSize size)
        {
            Gdk.Pixbuf res = widget.RenderIcon (name, size, null);
            if ((res != null)) {
                return res;
            } else {
                int sz;
                int sy;
                global::Gtk.Icon.SizeLookup (size, out  sz, out  sy);
                try {
                    return Gtk.IconTheme.Default.LoadIcon (name, sz, 0);
                } catch (System.Exception) {
                    if ((name != "gtk-missing-image")) {
                        return Stetic.IconLoader.LoadIcon (widget, "gtk-missing-image", size);
                    } else {
                        Gdk.Pixmap pmap = new Gdk.Pixmap (Gdk.Screen.Default.RootWindow, sz, sz);
                        Gdk.GC gc = new Gdk.GC (pmap);
                        gc.RgbFgColor = new Gdk.Color (255, 255, 255);
                        pmap.DrawRectangle (gc, true, 0, 0, sz, sz);
                        gc.RgbFgColor = new Gdk.Color (0, 0, 0);
                        pmap.DrawRectangle (gc, false, 0, 0, (sz - 1), (sz - 1));
                        gc.SetLineAttributes (3, Gdk.LineStyle.Solid, Gdk.CapStyle.Round, Gdk.JoinStyle.Round);
                        gc.RgbFgColor = new Gdk.Color (255, 0, 0);
                        pmap.DrawLine (gc, (sz / 4), (sz / 4), ((sz - 1) - (sz / 4)), ((sz - 1) - (sz / 4)));
                        pmap.DrawLine (gc, ((sz - 1) - (sz / 4)), (sz / 4), (sz / 4), ((sz - 1) - (sz / 4)));
                        return Gdk.Pixbuf.FromDrawable (pmap, pmap.Colormap, 0, 0, 0, 0, sz, sz);
                    }
                }
            }
        }
    }

    internal class ActionGroups
    {
        public static Gtk.ActionGroup GetActionGroup (System.Type type)
        {
            return Stetic.ActionGroups.GetActionGroup (type.FullName);
        }

        public static Gtk.ActionGroup GetActionGroup (string name)
        {
            return null;
        }
    }
}

Mainwindow.cs

// This file has been generated by the GUI designer. Do not modify.

public partial class MainWindow
{
    private global::Gtk.Fixed fixed1;

    private global::Gtk.Button button1;

    protected virtual void Build ()
    {
        global::Stetic.Gui.Initialize (this);
        // Widget MainWindow
        this.Name = "MainWindow";
        this.Title = global::Mono.Unix.Catalog.GetString ("MainWindow");
        this.WindowPosition = ((global::Gtk.WindowPosition)(4));
        // Container child MainWindow.Gtk.Container+ContainerChild
        this.fixed1 = new global::Gtk.Fixed ();
        this.fixed1.Name = "fixed1";
        this.fixed1.HasWindow = false;
        // Container child fixed1.Gtk.Fixed+FixedChild
        this.button1 = new global::Gtk.Button ();
        this.button1.CanFocus = true;
        this.button1.Name = "button1";
        this.button1.UseUnderline = true;
        this.button1.Label = global::Mono.Unix.Catalog.GetString ("GtkButton");
        global::Gtk.Image w1 = new global::Gtk.Image ();
        w1.Pixbuf = global::Stetic.IconLoader.LoadIcon (this, "gtk-delete", global::Gtk.IconSize.Menu);
        this.button1.Image = w1;
        this.fixed1.Add (this.button1);
        global::Gtk.Fixed.FixedChild w2 = ((global::Gtk.Fixed.FixedChild)(this.fixed1 [this.button1]));
        w2.X = 153;
        w2.Y = 137;
        this.Add (this.fixed1);
        if ((this.Child != null)) {
            this.Child.ShowAll ();
        }
        this.DefaultWidth = 400;
        this.DefaultHeight = 300;
        this.Show ();
        this.DeleteEvent += new global::Gtk.DeleteEventHandler (this.OnDeleteEvent);
    }
}

据我所知,代码没有任何问题。这与Gtk主题化的方式有关。

根据您的主题设置方式,您可能会看到或看不到该图标。顺便说一句,Xamarin 使用的主题与默认使用的主题不同,因此 运行从 Xamarin Studio (F5) 或命令行启动您的应用程序可能会得到不同的结果。

如果我没记错的话,在 windows 下有一个默认的 Gtk 主题和一个 Windows 主题。有一个切换主题的工具,但不幸的是,我可以得到它。

编辑:

获取主题 运行ning 的方法如下:

这里有一个小软件可以让你select一个主题:http://sourceforge.net/projects/tumagcc/files/gtk2_prefs.exe/download

您还必须在网络上的某个地方下载一个 Gtk 主题(我尝试的第一个主题在 windows 上很丑而且无法使用,所以您可能需要稍微试验一下这里)。将主题(通常是 tar.gz 文件)提取到 share/themes 下的 Gtk 安装。确保目录结构,一旦提取的主题如下:

{Gtk}/share/themes/MyFantasticTheme/Gtk-2.0

然后以管理员身份启动小软件,select 在列表中选择您的主题,然后单击“确定”。现在 运行 您的应用来自 Xamarin Studio 外部。

编辑#2:

经过一番尝试,我发现了一种在按钮内显示图标和标签的方法:

Application.Init ();
Gtk.Settings.Default.ThemeName = "Theme/gtk-2.0/gtkrc";
Gtk.Rc.Parse ("./Theme/gtk-2.0/gtkrc");

我的主题由 Theme/gtk-2.0/gtkrc 中的一行组成(关于 gtkrc 文件的文档很容易找到,因为它不是特定于 Gtk# 的):

gtk-button-images = 1

我认为发生的情况是在您的应用程序启动时以某种方式设置了默认主题,并且无法覆盖此默认主题。为什么会这样?可能是因为默认主题 运行 带有特定 Gtk 引擎 windows 不允许按钮中的图标。通过覆盖默认主题,我相信您将 Gtk 切换到默认引擎。

初始化Gtk后加入下面的语句也可以达到同样的效果

//Application.Init(); - insert after this line
Gtk.Settings.Default.SetLongProperty ("gtk-button-images", 1, "");