无法将 CSS 应用于 GtkEntry 小部件(GTK3 / gi / Python)不工作
Posted
技术标签:
【中文标题】无法将 CSS 应用于 GtkEntry 小部件(GTK3 / gi / Python)不工作【英文标题】:Cannot apply CSS to GtkEntry Widget (GTK3 / gi / Python) Not Working 【发布时间】:2019-11-25 22:55:56 【问题描述】:我一直无法弄清楚我做错了什么。我敢肯定,这很简单,但却让我无法接受。即使在以下示例中,我也无法使其正常工作。我似乎无法将 CSS 样式应用于单个 GtkWindow 中的 GtkEntry 小部件。我只是想把输入框的背景变成红色。
我查看过的所有内容和看到的示例都如下所示,似乎没有其他人被难倒。
这是我的 Python:
import gi
gi.require_version('Gtk', '3.0')
gi.require_version('Gdk', '3.0')
from gi.repository import Gtk
from gi.repository import Gdk
builder = Gtk.Builder()
builder.add_from_file("entry.glade")
window = builder.get_object('window1')
window.connect('destroy', Gtk.main_quit)
css = "#red background-image: linear-gradient(red); "
provider = Gtk.CssProvider()
provider.load_from_data(css)
Gtk.StyleContext().add_provider_for_screen(Gdk.Screen.get_default(), provider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION)
entry = builder.get_object('entry1')
entry_style_context = entry.get_style_context()
entry_style_context.add_class("red")
window.show_all()
Gtk.main()
这里是 Glade XML:
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<requires lib="gtk+" version="3.0"/>
<!-- interface-naming-policy project-wide -->
<object class="GtkWindow" id="window1">
<property name="can_focus">False</property>
<child>
<object class="GtkVBox" id="vbox1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkEntry" id="entry1">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="invisible_char">●</property>
<property name="primary_icon_activatable">False</property>
<property name="secondary_icon_activatable">False</property>
<property name="primary_icon_sensitive">True</property>
<property name="secondary_icon_sensitive">True</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
</object>
</child>
</object>
</interface>
如果我将 CSS 设置为 .entry background-image: linear-gradient(red);
它可以工作,但是所有 GtkEntry 框都会是红色的(我不想要)。
我到底错过了什么?
【问题讨论】:
相关Import CSS file in Python GTK3 program created using Glade,看注释"如果没有设置背景图片" 另外值得注意的是问题:将
CSS
应用到GtkEntry
小部件
正如 ptomato 在他的回答中所描述的,如果您没有为您的小部件定义 name
,则不能使用 css = "#red ...
。
定义一个小部件name
,使用:
glade
文件中:<property name="name">red</property>
在脚本中:entry = builder.get_object('entry1')
entry.set_name('red')
Gtk.CssProvider, Gtk.CssProvider.load_from_data Gtk.StyleContext, Gtk.StyleContext.add_provider_for_screen
方法一:使用小部件名称,
css = b"#entry ...
:
-
将
glade
文件中的小部件name
设置为entry
<child>
<object class="GtkEntry" id="entry1">
<property name="name">entry</property>
使用小部件名称 entry
定义您的 CSS
:
css = b"#entry background-image: linear-gradient(red, orange); color: white;"
工作示例,使用小部件名称:
class App:
def __init__(self):
super().__init__()
builder = Gtk.Builder()
builder.add_from_file("entry.glade")
window = builder.get_object('window1')
window.connect('destroy', Gtk.main_quit)
css = b"#entry background-image: linear-gradient(red, orange);"
provider = Gtk.CssProvider()
provider.load_from_data(css)
Gtk.StyleContext()\
.add_provider_for_screen(Gdk.Screen.get_default(),
provider,
Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION)
window.show_all()
if __name__ == "__main__":
main = App()
Gtk.main()
方法2:使用小部件样式类,
css = b".entry.red ...
:
Gtk.Widget.get_style_context, Gtk.StyleContext.add_class
-
使用嵌套样式类
.entry
、.red
、.blue
定义您的CSS
:
css = b"""
.entry color: white;
.entry.red background-image: linear-gradient(red, orange);
.entry.blue background-image: linear-gradient(blue, lightblue);
-
将命名的样式类添加到小部件:
entry1 = builder.get_object('entry1')
entry1.get_style_context().add_class("entry")
entry1.get_style_context().add_class("red")
# the same for `entry2`
...
使用小部件样式类的工作示例:
class App:
def __init__(self):
super().__init__()
builder = Gtk.Builder()
builder.add_from_file("entry.glade")
window = builder.get_object('window1')
window.connect('destroy', Gtk.main_quit)
css = b"""
.entry color: white;
.entry.red background-image: linear-gradient(red, orange);
.entry.blue background-image: linear-gradient(blue, lightblue);
"""
provider = Gtk.CssProvider()
provider.load_from_data(css)
Gtk.StyleContext()\
.add_provider_for_screen(Gdk.Screen.get_default(),
provider,
Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION)
entry1 = builder.get_object('entry1')
entry1.set_text('TEST')
entry1.get_style_context().add_class("entry")
entry1.get_style_context().add_class("red")
entry2 = builder.get_object('entry2')
entry2.set_text('TEST')
entry2.get_style_context().add_class("entry")
entry2.get_style_context().add_class("blue")
window.show_all()
if __name__ == "__main__":
main = App()
Gtk.main()
使用 Python 测试:3.5 - gi.__version__:3.22.0 - Glade 3.20.0
【讨论】:
【参考方案2】:在常规浏览器 CSS 中,#foo
指的是 ID 为 foo
的 html 元素(设置为,例如id="foo"
),.foo
指的是具有样式类的元素(设置为,例如@987654325 @,或多个类,例如class="foo bar"
。)
在 GTK CSS 中,ID 转换为小部件名称(例如在 XML 文件中设置为 entry.set_name('foo')
或 <property name="name">foo</property>
;不幸的是不与 XML 文件中的 id="foo"
相同) 并且该类仍然是样式类(但在 GTK 中它设置为,例如 entry.get_style_context().add_class('foo')
。由于您的小部件具有样式类但没有名称,这就是您必须使用点语法的原因。
【讨论】:
“转换为小部件名称”:为了澄清,您能否使用完整的entry.set_name('entry1')
示例编辑您的答案。 <object class="GtkEntry" id="entry1">
,entry1
中不是widget的名字吗?
希望如何在 XML 文件中设置它的示例应该澄清它。【参考方案3】:
好的,好吧,用一个新鲜的头脑再看一遍,我想我已经弄明白了。我不确定它为什么会这样工作,但希望有人比我更聪明。
无论出于何种原因,我都需要以点表示法指定小部件类型和类名,因为哈希表示法在 CSS/HTML 领域中无法正常工作。
这不工作:css = "#foo background-image: linear-gradient(red);
这个可以工作:css = "entry.foo background-image: linear-gradient(red);
我已通过向 Glade 添加第二个输入框并执行以下操作来验证这一点:
css = """
.entry.red background-image: linear-gradient(red);
.entry.blue background-image: linear-gradient(blue);
"""
provider = Gtk.CssProvider()
provider.load_from_data(css)
Gtk.StyleContext().add_provider_for_screen(Gdk.Screen.get_default(), provider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION)
builder.get_object('entry1').get_style_context().add_class("red")
builder.get_object('entry2').get_style_context().add_class("blue")
现在我有一个红色和一个蓝色的输入框。
【讨论】:
获取以下信息:provider.load_from_data(css) TypeError: Item 0: Must be number, not str
和 tk-WARNING : Theme parsing error: <data>:2:58: Using one color stop with linear-gradient() is deprecated.
。不,背景颜色。以上是关于无法将 CSS 应用于 GtkEntry 小部件(GTK3 / gi / Python)不工作的主要内容,如果未能解决你的问题,请参考以下文章
GTK3 使用带有 ID 的 CSS 从 GtkEntry 中删除蓝框