【问题标题】:Copy style from one widget to another in python3 gtk3在python3 gtk3中将样式从一个小部件复制到另一个小部件
【发布时间】:2026-02-01 17:05:02
【问题描述】:

我有一个 GtkFontButton,用户可以使用它来选择字体。按钮设置为在选择后更改其字体样式(名称、重量和大小),并显示新的字体和大小。我想将此“字体样式”复制到一个标签上。没有复杂的代码可以做到这一点吗?我可以从 GtkFontButton 获取新的字体和大小,使用 widget.get_font_name()(它返回一个字符串,如“Sans Bold Italic 11”)。

import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk

class LabelWindow(Gtk.Window):

    def __init__(self):
        Gtk.Window.__init__(self, title="Label Example")

        hbox = Gtk.Box(spacing=10)
        hbox.set_homogeneous(False)

        label = Gtk.Label("This is a normal label")
        hbox.pack_start(label, True, True, 0)

        self.labeltochange = Gtk.Label()
        self.labeltochange.set_text("This is a special label left-justified label.\nWith multiple lines.")
        hbox.pack_start(self.labeltochange, True, True, 0)

        label = Gtk.Label(
            "This is another label.\nWith multiple lines.")
        hbox.pack_start(label, True, True, 0)

        fb = Gtk.FontButton()
        fb.connect("font-set",self.test)
        hbox.pack_start(fb, True, True, 0)

        self.add(hbox)

    def test(self, widget):
        print(widget.get_font_name())

window = LabelWindow()
window.connect("delete-event", Gtk.main_quit)
window.show_all()
Gtk.main()

这会在终端上打印选定的字体和大小。我想做一些类似 self.labeltochange.set_style(widget.get_font_name()) 为了在每次用户通过单击按钮选择新字体时更改 self.labeltochange 的字体和大小以匹配字体和大小。我认为由于 get_font_name() 返回一个字体和大小 set_font_name (返回的字符串)可以解决问题,但这不是一个正确的想法。

【问题讨论】:

  • 请分享一个 MCVE。
  • 我不确定 V(在 MCVE 中)是什么意思。我的问题是如何将“字体样式”从任何 GtkFontButton 复制到 any gtk 窗口中的众多标签之一,以便在用户选择后,只有这个标签将具有 GtkFontButton 所具有的字体.不是关于一些带有 Verifiable 错误的代码。
  • V 在这种情况下并不适用,是吗?无论如何,我想看看你的一些代码,所以我确切地知道你已经尝试了什么。
  • 那里没有显示我的任何尝试。这不是实际代码(我从 glade 文件加载几乎所有内容)。我只是被“强迫”写了一个样本。我尝试了各种print(dir(someobject)) 来找到任何可以接受widget.get_font_name() 返回的字符串但没有成功的东西。

标签: python-3.x fonts widget gtk3


【解决方案1】:

Google 想出了这种使用 CSS 的方法(这是 Gtk3 中推荐的方式):

import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk, Gdk

class LabelWindow(Gtk.Window):

    def __init__(self):
        Gtk.Window.__init__(self, title="Label Example", name = 'Window')

        self.style_provider = Gtk.CssProvider()

        css = """
        #Label{
            background-color: red;
            border-radius: 10px;
            outline:none;
            font: Sans Bold 12;
        }
        """
        self.style_provider.load_from_data(bytes(css.encode()))
        Gtk.StyleContext.add_provider_for_screen(
            Gdk.Screen.get_default(), self.style_provider,
            Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION
        )

        hbox = Gtk.Box(spacing=10)
        hbox.set_homogeneous(False)

        label = Gtk.Label("This is a normal label")
        hbox.pack_start(label, True, True, 0)

        self.labeltochange = Gtk.Label(name = 'Label')
        self.labeltochange.set_text("This is a special label left-justified label.\nWith multiple lines.")
        hbox.pack_start(self.labeltochange, True, True, 0)

        label = Gtk.Label(
            "This is another label.\nWith multiple lines.")
        hbox.pack_start(label, True, True, 0)

        fb = Gtk.FontButton()
        fb.connect("font-set",self.test)
        hbox.pack_start(fb, True, True, 0)

        self.add(hbox)

    def test(self, widget):
        font = widget.get_font_name()
        css = """
        #Label{
            font: %s;
        }
        """ % font
        self.style_provider.load_from_data(bytes(css.encode()))



window = LabelWindow()
window.connect("delete-event", Gtk.main_quit)
window.show_all()
Gtk.main()

【讨论】:

  • 我试图避免一大堆代码。 self.style_provider 为所有标签加载 css,而不仅仅是我临时选择更改的那个。所以为了使用这种方式,我还得写很多,error prune,code。
  • Pango 标记不是很有用,因为文本包含格式错误的 html 代码。所以我(暂时)使用GObject.markup_escape_text 来避免它。
【解决方案2】:

愚蠢但几乎可以工作(愚蠢因为在标签的样式提供程序中添加了样式色调,几乎因为它可能有副作用,例如向子对象添加样式):

def on_buttonforselectfont_clicked(self, widget, *args):  
    font = widget.get_font_name()
    self.set_object_general_style(self.thelabelforsampleobject, 'font',font)

def set_object_general_style(self, theobject, var, val):
    css = '''*{''' + var + ''':''' + val + ''';}'''
    style_provider = Gtk.CssProvider()
    style_provider.load_from_data(css.encode('utf-8'))
    context = theobject.get_style_context()
    context.add_provider(style_provider,Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION)

【讨论】:

    最近更新 更多