2

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

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

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

编辑:这是gtk3

4

4 回答 4

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");
于 2013-02-15T19:53:30.013 回答
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 的语法

于 2013-02-15T11:56:40.193 回答
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);
}
于 2013-03-02T21:02:42.837 回答
1

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

准备自定义 CSS

您首先需要创建一个CssProvider、一个Style Context和一个Screen

在运行程序之前,这三个对象需要在主循环中。

// 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+ 文档更容易找到小部件的“类”或“样式”名称。或者,您可以找到现有主题并打开它们的 CSS 文件以查找名称('/usr/share/themes/')。

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

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

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

例子:

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

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


陷阱和附加链接:

  • 如果您的 CSS 文件包含任何语法错误,程序将无法运行
  • ID/类名称可能会相互混淆。例如,有一个 '.progressbar' 和一个 'GtkProgressBar'
  • 与 Gtk 中的主题相关的索引页面。
  • 特定于 GTK CSS的页面。
于 2018-03-16T17:16:05.283 回答