GTK:一起摆脱系统主题/ CSS

时间:2018-10-04 21:55:06

标签: c++ css gtk gtk3 gtkmm3

GTK3应用程序可以使用CSS设置样式和主题。如何强制GTK仅使用我的应用程序附带的CSS,而不是将其与用户系统上安装的主题组合/层叠?

为什么要这么做?从理论上讲,CSS将会是一个很好的基于规则的样式系统,您只需在其中添加一个全屏明智选择的规则,即可一致地定义应用程序的外观。不幸的是,实际上,人们倾向于在样式表中添加数百个脑死亡的重复性定义,从而伪造了级联的本质。

实际的问题是,与用户系统上安装的全局主题无关,我的应用程序应具有媒体处理应用程序典型的柔和的深灰色外观。通过阅读GTK文档和GTKmm tutorial,我想到了以下代码来阅读自己的CSS样式表:

auto screen = Gdk::Screen::get_default();
auto css_provider = Gtk::CssProvider::create();
try {
    css_provider->load_from_path(lib::resolveModulePath (stylesheetName, resourceSerachPath));

} catch(Glib::Error const& failure) {
    WARN(gui, "Failure while loading stylesheet '%s': %s", cStr(stylesheetName), cStr(failure.what()));
}

Gtk::StyleContext::add_provider_for_screen(screen, css_provider, GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);

技术上,这很完美。但是,现在-我不得不“反对”用户系统上存在的CSS规则。如果我先在默认规则中设置合适的边框颜色,在GtkWindow的规则中设置深灰色背景,在文本中设置合适的文本颜色,再为文本输入字段设置一些规则,那么我会在某些部分得到所需的外观,但是无论何时用户系统主题为某些特定的小部件或小部件组合添加了一个特定的定义,从而明确地重复颜色,而不是从通用规则继承它们,我需要在我的应用程序样式表中添加另一个特定的规则来解决该问题具体情况。也就是说,已安装系统主题的可能不正确的结构迫使我的应用程序样式表进入相同的不正确的不良做法,并且有成百上千的单例定义一遍又一遍地重复相同的值。

问题

  • 如何告诉GTK在我的应用程序中仅使用 我的样式表?
  • 是否有任何可行的替代方案,虽然不是那么彻底,但仍允许我按预期的方式使用CSS(最少的规则+级联)?

2 个答案:

答案 0 :(得分:3)

您可以使用GTK演示中的reset.css文件来取消设置所有现有规则。

一种不太激进的选择是忽略默认主题以外的用户主题。据推测,如果用户的主题采用不良的CSS做法构建,那么他们仍然会喜欢该主题。那么,为什么他们不能以他们喜欢的主题查看您的应用程序?

答案 1 :(得分:3)

正如@ptomato指出的,

您可以安装CSS来有效地覆盖系统上任何预先存在的其他规则。但是,这也显示了一种朝着不太激进的解决方案迈进的方法:只需取消预装主题的问题部分即可。

它如何工作?

我们向CSS添加了包罗万象的规则,即以某种方式选择任何可能的元素或至少一个完整子树的规则。这可以通过在选择器中使用通配符*来实现。而且由于我们以较高的优先级(通常为GTK_STYLE_PROVIDER_PRIORITY_APPLICATION)安装样式表,因此这些规则将“盖章”每一个恰好以较低的优先级出现的特定规则。

  • 我们可以使用值unset清除设置
  • 我们可以使用值inherit强制将该属性从该属性的父窗口小部件设置中派生。

特别是对于给定的问题,在具有“浅色”主题的环境中获得“灰色制服的媒体应用程序”外观,我们可以使用

* {
    color: inherit;
    background-color: inherit;
}

...仅取消存在的“浅色”主题中有问题的部分,即背景和颜色设置。然后,我们可以在一个中心点设置一次我们自己的值,这些值将按预期继承。

通过使用CSS上下文选择器下方的通配符,我们甚至可以扩展该想法并处理给定范围内的其他问题设置。正确实现这一目标的关键技巧是在运行的应用程序上使用GTK+ inspector并调查实际设置,以找到可能的最低点,从而“抓住”问题设置。 (要激活GTK +检查器,请使用GTK_DEBUG=interactive path/to/my/app运行您的应用程序)