应用程序是否可以覆盖一个窗口小部件的一个属性的gtk主题?

时间:2013-02-15 02:55:54

标签: c++ gtk

我正在编写一个gtk应用程序,但它与我的主题并不相符。具体来说,应用程序需要适合只有50像素宽的工具栏,并且需要包含进度条,但主题有ProgressBar :: min-horizo​​ntal-bar-width = 150(这是默认值)。我想在代码中告诉gtk这个特定的小部件可以忽略那个特定的样式属性。

我意识到我可以改变我的系统主题,但如果我以后做过任何与主题相关的事情,应用程序就会破坏。我更喜欢强大的解决方案。

我也更喜欢保留主题其余部分的解决方案,因此进度条看起来很正常(除了更小)。

编辑:这是gtk3

4 个答案:

答案 0 :(得分:5)

是的,你可以。您尚未指定是否需要GTk + 2或3。

在2中,您可以通过在代码中创建仅适用于命名窗口小部件的资源来实现。然后,您可以设置进度条的名称。

char *custom_theme = "style \"Custom\" { ProgressBar::min-horizontal-bar-width = 10 }\n widget \"*.GtkProgressBar.my_progress_bar\" style \"Custom\"";

. . .

// After you've initialised the gtk system
gtk_rc_parse_string (custom_theme);

然后,无论何时创建进度条都要忽略主题,请调用

gtk_widget_set_name (progress_bar, "my_progress_bar");

它应该应用自定义样式。

主题系统很难让路径正确,因此可能需要一些摆弄。

资源文件的文档位于:http://developer.gnome.org/gtk2/stable/gtk2-Resource-Files.html

然而,所有这些都已经被GTK + 3弃用了,尽管它仍然可以使用,正确的方法是使用CSS样式,这里描述:http://developer.gnome.org/gtk3/stable/GtkCssProvider.html但我不得不承认我不确定它们是如何工作的,虽然我认为它类似但类似于CSS的语法

答案 1 :(得分:5)

知道了!感谢@iain指出我正确的方向。

GtkCssProvider* provider = gtk_css_provider_new();
const char* css = "GtkProgressBar#small { -GtkProgressBar-min-horizontal-bar-width: 1; }";
gtk_css_provider_load_from_data(provider, css, strlen(css), NULL);
GdkDisplay *display = gdk_display_get_default ();
GdkScreen *screen = gdk_display_get_default_screen (display);
gtk_style_context_add_provider_for_screen (screen,
                       GTK_STYLE_PROVIDER (provider),
                       GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
g_object_unref (provider);
peakProgressBar.set_name("small");

答案 2 :(得分:2)

谢谢,这对我来说非常有用。

用于一个小部件而不是添加到屏幕上 功能 gtk_widget_get_style_context() 和 gtk_style_context_add_provider() 可以使用...像这样:

void style_to_widget(GtkWidget * w, GtkStyleProvider * s)
{
    gtk_style_context_add_provider(gtk_widget_get_style_context(w),
                                   s, GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
}

答案 3 :(得分:1)

Gtk(和Gtkmm)为此目的使用CSS。 我在下面解释的是将程序设置为使用外部CSS文件,与在.cpp文件中对其进行编码相关的现有答案进行比较。

准备自定义CSS

首先需要创建CssProviderStyle ContextScreen

运行程序之前,这三个对象需要位于主循环内。

// Create CssProvider
Glib::RefPtr<Gtk::CssProvider> cssProvider = Gtk::CssProvider::create();
cssProvider->load_from_path("relative or absolute path to YourTheme.css");

// Create StyleContext
Glib::RefPtr<Gtk::StyleContext> styleContext = Gtk::StyleContext::create();

//get default screen
Glib::RefPtr<Gdk::Screen> screen = Gdk::Screen::get_default();

//add provider for screen in all application
styleContext->add_provider_for_screen(screen, cssProvider, GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);

使用CSS

由于文档在Gtkmm上低于标准,因此使用Gtk +文档更容易找到&#34;类&#34;或&#34;风格&#34;小部件的名称。 或者,您可以找到现有主题并打开其CSS文件以查找名称(&#39; / usr / share / themes /&#39;)。

Gtk / mm遵循与普通CSS相似的选择器。

以下是完整列表的摘录,您可以找到here(尽管标记为GTK +,但它适用于所有包装器,包括Gtkmm)。

*任何节点。
E任何名称为&#34; E&#34;。的节点 E.class具有给定样式类的任何E节点 E#id#具有给定ID的任何E节点。 (GTK使用小部件名称作为ID) E:nth-child任何E节点,它是其父节点的第n个子节点 E:active, E:hover, E:focus任何E节点,它是具有相应状态的小部件的一部分 E>F任何F节点,它是E节点的子节点。

实施例

以下是我用于我自己的一个程序的CSS的示例摘录。

&#13;
&#13;
.background{
	background-color: @shade0;
	color: @mainTextColour;
}

#EngineTabSidePanel > GtkGrid{

	background-color: @shade1;
}

/* BUTTONS:*/
.button{
	border: none;
	border-radius: 0;
	background-color: @shade1;
	color: rgb(175, 175, 175);
}

.button:insensitive{
	background-color: @shade0;
	color: rgb(150, 150, 150);
}

.button:hover {
	background-color: @shade2;
}

.button:active{
	background-color: @shade1;
}


.stack-switcher .button{
	border-bottom: 3.5px solid @primary_4;
}

.stack-switcher .button:checked,
.stack-switcher .button:active{
	background-color: @shade2;
	border-bottom: 7.5px solid @primary_0;
}

.stack-switcher .requires-attention{
	border-bottom: 7.5px solid @altprimary_0;
}
&#13;
&#13;
&#13;

Gotchas&amp;其他链接:

  • 如果您的CSS文件包含任何语法错误,则程序将无法运行
  • ID / Class名称可能相互混淆。例如,有一个&#39; .progressbar&#39;和一个&#39; GtkProgressBar&#39;
  • An index page与Gtk中的主题相关。
  • A page特定于GTK CSS。