Button 如何在Python GTK3中制作不同颜色的按钮(使用gi)?

Button 如何在Python GTK3中制作不同颜色的按钮(使用gi)?,button,colors,python-3.x,gtk3,Button,Colors,Python 3.x,Gtk3,我最新的一个难题是使用GTK3在Python3中构建一个愚蠢的小应用程序,按钮上的颜色不是雾灰色。过去几天我一直在谷歌上搜索如何做到这一点,到目前为止,我尝试的一切都失败了。不仅失败了,而且默默地失败了,没有错误消息给我任何关于发生了什么的线索 这是我的测试应用程序: from gi.repository import Gtk, Gdk class ButtonWindow(Gtk.Window): def __init__(self): super().__init

我最新的一个难题是使用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()
我已将失败的尝试作为评论留在了中。如上所述,就应用程序而言,它似乎已经工作了,因为上面的任何变体都不会生成任何错误消息。然而,它们似乎对我都不起作用,因为按钮仍然是陈腐的洗碗水的颜色

仅供参考,我正在使用Ubuntu12.04下的python3.2.3,并从标准存储库安装了python3 gi和python3 gi cairo

有人能给我指一下正确的方向吗

编辑:下面是一个基于@mike的答案重新设计的示例。这是可行的,但也存在一些问题,可能需要在后续问题中加以解决。这些问题是:

  • 为什么必须在Ubuntu上使用背景色而不是背景色,然后只用于按钮
  • 我仍然有一些问题,让字体样式的工作,但至少现在我有一个工作的例子来玩
  • 不同的按钮是否可以应用不同的样式/颜色,例如基于文本或其他属性
  • 因此,守则:-

    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;
    }
    

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

    受@boosth的启发,这是经过修改的代码(包装按钮,并将颜色应用于包装器-请参阅用
    #注释的行GTK3中的首选方式是使用CSS进行样式设置。在Ubuntu 12.04下,您可能需要使用背景而不是背景颜色。但我不懂Python,所以我只提供一个链接


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

    GTK3增加了样式类的概念。因此,要获得不同颜色的按钮,您可以直接用名称来称呼它们,或者将样式类添加到上下文中。mike在回答中提供的链接中解释了所有这些

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

    从gi.repository导入Gtk、Gdk
    类主窗口(Gtk.Window):
    定义初始化(自):
    super()。\uuuu init\uuuuu()
    vbox=Gtk.Box(间距=10,方向=Gtk.orientation.VERTICAL)
    self.add(vbox)
    self.entries=[Gtk.Entry()表示范围(3)中的i]
    对于e in self.entries:
    vbox.pack_start(e,真,真,0)
    e、 连接(“已更改”,输入时自行更改)
    e、 设置文本('123')
    button=Gtk.button('ok',name='ok-button')
    vbox.pack_end(按钮,真,真,0)
    输入时的def更改(自身,输入):
    ctx=entry.get\u style\u context()
    如果不是输入项,则获取文本().isnumeric():
    ctx.add_类(“无效”)
    其他:
    ctx.remove_类(“无效”)
    cssProvider=Gtk.cssProvider()
    cssProvider.load\u from\u路径('style.css'))
    screen=Gdk.screen.get_default()
    styleContext=Gtk.styleContext()
    为屏幕(屏幕、cssProvider、,
    Gtk.样式(提供者优先用户)
    窗口=主窗口()
    window.connect(“删除事件”,Gtk.main_退出)
    window.show_all()
    Gtk.main()
    
    使用style.css:

    GtkEntry.invalid{
    背景色:#ffaaa;
    背景:#ffaaa;
    }
    GTK按钮#确定按钮{
    背景颜色:绿色;
    背景:绿色;
    }
    
    你需要用一个事件框来包装它…谢谢你的提示,@boosth。我实际上已经放弃了GTK,开始用tkinter/ttk来实现我的应用程序,但现在我可能会再试试GTK!非常感谢Mike!我查看了你的链接,这看起来非常像我一直在寻找的内容。我仍然不太理解CSS,但我还是不太理解一个see(我看过的GTK教程中没有提到的内容)理解CSS对于使用GTK做任何事情都是必要的。我在基于这个答案的原始问题中添加了一个工作示例。当您有多个相同类型的小部件时,要单独设置它们的样式,您需要使用GTK_widget_set_name()来命名它们或者Python中的等效名称。然后在CSS中使用其名称前加英镑符号,这在CSS中称为ID选择器。我的示例使用C而不是Python,但您可能会发现它们很有用。再次感谢!很有趣,Python中的编码提高了我的C技能:)然而,我想这是Gtk内省的最大好处,它与您使用的主要语言无关。答案中的这些链接实际上都没有指向任何有用的内容:(另一个相关链接提到了一些建议按钮和破坏性按钮的标准类,它们不需要定制CSS,并使用默认的Adwaita主题分别以蓝色和红色突出显示。绿色是一个不错的主题,因此感谢您指出它只需在CSS中添加
    背景
    规则即可…现在我所要做的就是我想知道如何在GTKmm下加载CSS文件,除非有办法在代码中添加CSS规则?如果可以避免的话,我宁愿不依赖外部文件。
    
    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()