【问题标题】:How to make buttons different colours in Python GTK3 (using gi)?如何在 Python GTK3 中制作不同颜色的按钮(使用 gi)?
【发布时间】:2012-08-09 07:08:31
【问题描述】:

我最近的头疼事是使用 GTK3 在 Python3 中构建一个愚蠢的小应用程序,按钮上的颜色不是雾灰色。在过去的几天里,我一直在谷歌上搜索如何做到这一点,到目前为止,我所尝试的一切都失败了。不仅失败了,而且默默地失败了,没有任何错误消息可以让我知道发生了什么。

这是我的测试应用:

from gi.repository import Gtk, Gdk

class ButtonWindow(Gtk.Window):

    def __init__(self):
        super().__init__(title="Button Test")
        self.set_border_width(10)
        hbox = Gtk.Box(spacing=10)
        self.add(hbox)
        hbox.set_homogeneous(False)

        # make the button
        button = Gtk.Button('Test Button')
        hbox.pack_start(button, True, True, 0)

        # try to change its colour ....

#        button.modify_base(Gtk.StateType.NORMAL, Gdk.color_parse('green'))
#        button.override_background_color(Gtk.StateType.NORMAL, Gdk.RGBA(0, 1, 0, 1))
#        button.override_background_color(Gtk.StateType.NORMAL, Gdk.RGBA(0x00ff00))
#        button.modify_bg(Gtk.StateType.NORMAL, Gdk.color_parse("green"))
#        button.modify_bg(Gtk.StateType.ACTIVE, Gdk.color_parse("green"))
#        button.modify_bg(Gtk.StateType.SELECTED, Gdk.color_parse("green"))

        # attempt to change the style ....

#        style = button.get_style().copy()
#        style.bg[Gtk.StateType.NORMAL] = Gdk.color_parse('green')
#        style.bg[Gtk.StateType.ACTIVE] = Gdk.color_parse('red')
#        style.bg[Gtk.StateType.SELECTED] = Gdk.color_parse('blue')
#        style.bg[Gtk.StateType.PRELIGHT] = Gdk.color_parse('black')
#        button.set_style(style)

        # ok, let's try changing the box ....

#        hbox.modify_base(Gtk.StateType.NORMAL, Gdk.color_parse('green'))
#        hbox.override_background_color(Gtk.StateType.NORMAL, Gdk.RGBA(0,1,0,1))
#        hbox.override_background_color(Gtk.StateType.NORMAL, Gdk.RGBA(0x00ff00ff))
#        hbox.modify_bg(Gtk.StateType.NORMAL, Gdk.color_parse('green'))

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

我将失败的尝试保留为 cmets。如上所述,就应用程序而言,它似乎已经工作,因为上述变体都不会生成任何错误消息。但是,没有它们似乎对我有用,因为按钮仍然是陈旧的洗碗水的颜色。

仅供参考,我在 Ubuntu 12.04 下使用 Python 3.2.3,并从标准存储库安装了 python3-gi 和 python3-gi-cairo。

有人可以指点我正确的方向吗?

编辑:以下是根据@mike 的回答重新设计的示例。这可行,但它存在一些问题,可能需要在一些后续问题中解决。问题是:

  1. 为什么在 Ubuntu 上必须使用 background 而不是 background-color,然后只用于按钮?
  2. 我仍然无法让字体样式正常工作,但至少现在我有一个可以使用的示例。
  3. 可以将不同的样式/颜色应用于不同的按钮,例如基于文本或其他属性?

所以,代码:-

from gi.repository import Gtk, Gdk

class ButtonWindow(Gtk.Window):

    def __init__(self):
        super().__init__(title="Button Test")
        self.set_border_width(10)

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

        # make the button
        button = Gtk.Button('Test Button')
        hbox.pack_start(button, True, True, 0)

# get the style from the css file and apply it
cssProvider = Gtk.CssProvider()
cssProvider.load_from_path('gtkStyledButtonTest.css')
screen = Gdk.Screen.get_default()
styleContext = Gtk.StyleContext()
styleContext.add_provider_for_screen(screen, cssProvider,
                                     Gtk.STYLE_PROVIDER_PRIORITY_USER)

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

css 文件如下所示:-

GtkWindow {
    background-color: #0000ff;
}

GtkButton {
    color: #ff0000;
    background: #00ff00;
}

我希望有人觉得这很有用。

【问题讨论】:

  • 你需要用事件框包装它...stackoverflow.com/questions/7127093/…
  • 感谢您的提示,@boosth。我实际上已经放弃了 GTK 并开始使用 tkinter/ttk 实现我的应用程序,但现在我可能会再尝试一次 GTK!

标签: button colors python-3.x gtk3


【解决方案1】:

尽管这是一个老问题,但我想添加一个关于问题 3 的答案,仅供参考。

GTK3 增加了样式类的概念。因此,要获得不同颜色的按钮,您可以直接将它们命名为名称或将样式类添加到其上下文中。所有这些都在他的答案中提供的链接中进行了解释。

这是一个简单的示例,如何使用样式类突出显示条目中的无效文本:

from gi.repository import Gtk, Gdk

class MainWindow(Gtk.Window):

    def __init__(self):
        super().__init__()
        vbox = Gtk.Box(spacing=10,orientation=Gtk.Orientation.VERTICAL)
        self.add(vbox)

        self.entries = [ Gtk.Entry() for i in range(3) ]
        for e in self.entries:
            vbox.pack_start(e, True, True, 0)
            e.connect("changed", self.on_entry_changed)
            e.set_text('123')

        button=Gtk.Button('ok',name='ok-button')
        vbox.pack_end(button,True,True,0)


    def on_entry_changed(self,entry):
        ctx = entry.get_style_context()
        if not entry.get_text().isnumeric():
            ctx.add_class('invalid')
        else:
            ctx.remove_class('invalid')


cssProvider = Gtk.CssProvider()
cssProvider.load_from_path('style.css')
screen = Gdk.Screen.get_default()
styleContext = Gtk.StyleContext()
styleContext.add_provider_for_screen(screen, cssProvider,
                                     Gtk.STYLE_PROVIDER_PRIORITY_USER)

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

使用 style.css:

GtkEntry.invalid {
    background-color: #ffaaaa;
    background: #ffaaaa;
}

GtkButton#ok-button {
    background-color: green;
    background: green;
}

【讨论】:

  • 另一个相关链接是wiki.gnome.org/HowDoI/Buttons,它提到了一些用于suggested破坏性按钮的标准类,它们不需要自定义CSS并被突出显示蓝色和红色分别使用默认的 Adwaita 主题。绿色是一个不错的选择,所以感谢您指出它就像在 CSS 中添加 background 规则一样简单......现在我所要做的就是弄清楚如何在 GTKmm 下加载 CSS 文件,除非有办法添加 CSS 规则在代码中?如果可以避免的话,我宁愿不依赖外部文件。
【解决方案2】:

GTK3 中的首选方式是使用 CSS 进行样式设置。在 Ubuntu 12.04 下,您可能需要使用背景而不是背景颜色。但是我不懂Python,所以我只提供一个链接。

https://thegnomejournal.wordpress.com/2011/03/15/styling-gtk-with-css/

【讨论】:

  • 非常感谢迈克!我检查了您的链接,这看起来非常像我一直在寻找的。我仍然不太了解 CSS,但我可以看到(在我看过的任何 GTK 教程中都没有提到)理解 CSS 对于使用 GTK 做一些非常基本的事情是必要的。跨度>
  • 我根据这个答案在我原来的问题中添加了一个工作示例。
  • 当您有多个相同类型的小部件时,要单独设置它们的样式,您需要使用 gtk_widget_set_name() 或 Python 中的等价物来命名它们。然后在 CSS 中使用它们的名称前面加上井号符号,这在 CSS 中称为 ID 选择器。 w3.org/TR/css3-selectors/#id-selectors 我的例子是 C 而不是 python,但你可能会发现它们很有用。 gtkforums.com/…
  • 再次感谢!有趣的是,Python 编码是如何提升我的 C 技能的 :) 然而,我想这是 Gtk 内省的一大好处,你使用什么主要语言并不重要。
  • 答案中的这些链接实际上都不再指向任何有用的东西:(
【解决方案3】:

受@boosth 的启发,这是修改后的代码(包装按钮,并将颜色应用于包装器 - 参见注释为# <---- 的行)。

然而,虽然它改变了事件框的颜色,但按钮本身保持不变。所以,这不是我想要的,但到目前为止这是最好的答案。

from gi.repository import Gtk, Gdk

class ButtonWindow(Gtk.Window):

    def __init__(self):
        super().__init__(title="Button Test")
        self.set_border_width(10)

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

        # make the button
        button = Gtk.Button('Test Button')
        buttonWrapper = Gtk.EventBox()                  # <----
        buttonWrapper.add(button)                       # <----
        hbox.pack_start(buttonWrapper, True, True, 0)   # <----

        # change the colour of the wrapper ....
        buttonWrapper.modify_bg(Gtk.StateType.NORMAL, Gdk.color_parse("green"))
        buttonWrapper.modify_bg(Gtk.StateType.ACTIVE, Gdk.color_parse("red"))
        buttonWrapper.modify_bg(Gtk.StateType.SELECTED, Gdk.color_parse("blue"))


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

一定有办法做到这一点......

【讨论】:

    猜你喜欢
    • 2014-10-18
    • 1970-01-01
    • 1970-01-01
    • 2019-10-03
    • 2018-08-23
    • 1970-01-01
    • 1970-01-01
    • 2016-04-06
    • 1970-01-01
    相关资源
    最近更新 更多