我正在尝试提供我自己的GtkStyleProvider
实现,因为“普通”CSS提供程序需要大量的工作和额外的处理才能在我的情况下使用。
我希望能够基于某些内部状态提供小部件样式,并且要在CSS中执行此操作,我必须写出一大串CSS(将Pango.FontDescription
之类的内容翻译成CSS-样式声明)基于状态的任何变化,然后将其提供给GktCssProvider
,它将返回处理到Gtk-land。与自定义提供程序相比,它只是发出信号(不知何故)其客户端小部件应该询问它的样式,并直接根据状态分发新的样式。
似乎GtkStyleProvider
是实现这一目标的一种方式 - 我可以创建一个基于某个状态返回样式的提供程序,并将其作为样式提供程序添加到相关的GtkStyleContext
。 (C)接口是
// deprecated - return NULL in new code
GtkIconFactory * gtk_style_provider_get_icon_factory (
GtkStyleProvider *provider,
GtkWidgetPath *path);)
// deprecated - return NULL in new code
GtkStyleProperties * gtk_style_provider_get_style (
GtkStyleProvider *provider,
GtkWidgetPath *path))
// return true if property found and has a value, else false
gboolean gtk_style_provider_get_style_property (
GtkStyleProvider *provider,
GtkWidgetPath *path,
GtkStateFlags state,
GParamSpec *pspec,
GValue *value);
为此,我写了这样的东西,我希望它可以工作,但什么都不做,因为它应该总是报告属性没有设置:
# compile with: valac styleprov.vala --pkg gtk+-3.0 --pkg gdk-3.0
using Gtk;
using Gdk;
public class DerivedStyleProvider : Object, Gtk.StyleProvider
{
public unowned Gtk.IconFactory get_icon_factory (Gtk.WidgetPath path)
{
return (Gtk.IconFactory) null; // Evil cast to work around buggy declaration in VAPI file
}
public Gtk.StyleProperties get_style (Gtk.WidgetPath path)
{
return (Gtk.StyleProperties) null; // Evil cast to work around buggy declaration in VAPI file
}
public bool get_style_property (Gtk.WidgetPath path,
Gtk.StateFlags state,
GLib.ParamSpec pspec,
out GLib.Value value)
{
stdout.printf("get_style_property");
// Compiler happiness for testing
value = Value (typeof (string));
return false; //TODO
}
}
public class styleprov.MainWindow : Gtk.Window
{
construct {
DerivedStyleProvider styleProvider = new DerivedStyleProvider();
// but this would work
//Gtk.CssProvider styleProvider = new Gtk.CssProvider();
//styleProvider.load_from_data("*{ background-color: #ff0000; }");
StyleContext.add_provider_for_screen(this.get_screen(),
styleProvider,
Gtk.STYLE_PROVIDER_PRIORITY_USER);
}
}
class styleprov.Main : GLib.Object
{
public void run() {
styleprov.MainWindow mainWindow = new styleprov.MainWindow();
mainWindow.show_all();
}
public static int main (string[] args) {
Gtk.init (ref args);
Main app = new Main();
app.run();
Gtk.main ();
return 0;
}
}
这编译好了,然后跑了,但几乎发出警告:
(styleprov:32365): GLib-GObject-WARNING **: gsignal.c:2523: signal '-gtk-private-changed' is invalid for instance '0x1154ac0' of type 'DerivedStyleProvider'
(styleprov:32365): Gtk-WARNING **: (gtkstylecascade.c:256):gtk_style_cascade_lookup: code should not be reached
(styleprov:32365): Gtk-WARNING **: (gtkstylecascade.c:256):gtk_style_cascade_lookup: code should not be reached
...several of these....
尽管有警告,但似乎永远不会调用get_style_property()
方法,因此无法提供自定义样式。
用“普通”CSS提供程序替换DerivedStyleProvider
可以正常工作。
实现自定义GtkStyleProvider
(使用任何语言)的正确方法是什么?
答案 0 :(得分:2)
查看GtkCssProvider
的实现,它似乎不仅使用GtkStyleProviderInterface
而且还使用GtkStyleProviderPrivateInterface
,以及许多复杂的自定义绕过(显然出于效率原因,根据友好情况而定)关于GTK + IRC频道的人,我决定只使用普通的CSS方法,只是手工构建CSS作为字符串。
机制是:
GtkCssProvider
gtk_style_context_add_provider()
(或全球gtk_style_context_add_provider_for_screen()
)GtkCssProvider
生成新的CSS字符串gtk_css_provider_load_from_data()
。我想问题可能是我不完全理解GTK +如何在其下工作。如果您将CSS视为 规范样式" oracle"对于UI,我认为真正更新CSS 实际上是正确的方法,并且我期待可能在技术上可行的低级访问,但不是"正确"在GTK +方式。
这种低级访问是我对其他框架的期望,在这些框架中,您(仅)可以直接控制诸如"背景颜色"之类的事物的样式。小部件,并没有CSS层来抽象它,但不是它在GTK +中的工作方式(更多)。
至少,这就是我的理解!