2012-08-13 73 views
4

我最新的頭腦工作者是使用GTK3在Python3中構建一個愚蠢的小應用程序,其顏色除了按鈕上的霧灰色以外。過去幾天我一直在用Google搜索如何做到這一點,到目前爲止,我所嘗試過的一切都失敗了。不僅失敗了,而且失敗了,沒有任何錯誤消息給我提供關於發生的事情的任何線索。如何在Python GTK3中使用按鈕不同的顏色(使用gi)?

這是我的測試程序:

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() 

我已經離開我的失敗嘗試中作爲註釋。如上所述,就應用而言,它看起來很有效,因爲上述變體都沒有產生任何錯誤消息。然而,沒有他們似乎爲我工作,因爲按鈕仍然是陳舊洗碗水的顏色。

僅供參考我在Ubuntu 12.04下使用Python 3.2.3,並且從標準存儲庫安裝了python3-gi和python3-gi-cairo。

有人可以請指出我在正確的方向嗎?

編輯:以下是基於@邁克的答案重新工作的例子。這可行,但有一些問題,可能在一些後續問題中得到解決。這些問題是:

  1. 爲什麼background要在Ubuntu上,而不是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; 
} 

我希望有人認爲這是有用的。

+0

您需要使用事件盒來包裝它... http://stackoverflow.com/questions/7127093/pygtk-change-background-color-of-gtkhbox-widget – boosth 2012-08-19 12:17:22

+0

感謝您的提示,@boosth。我真的放棄了GTK,並開始用tkinter/ttk實現我的應用程序,但我現在可能會再給GTK一個! – Bobble 2012-08-20 13:21:52

回答

4

的首選方式GTK3是使用CSS樣式。在Ubuntu 12.04下,您可能需要使用背景而不是背景色。但我不知道Python,所以我只是給出一個鏈接。

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

+0

非常感謝邁克!我檢查了你的鏈接,這看起來非常像我一直在尋找的東西。我還是不太瞭解CSS,但是我可以看到(我看過的任何GTK教程中沒有提及的),對於使用GTK來做非常基本的東西來說,理解CSS是必要的。 – Bobble 2012-08-29 02:37:18

+0

我已經添加了一個工作示例到我原來的問題基於這個答案。 – Bobble 2012-08-29 10:20:36

+0

如果您有多個相同類型的窗口小部件,要分別設置它們的樣式,則需要使用gtk_widget_set_name()或Python中的等效命名。然後在CSS中使用它們的名稱前面加上被稱爲CSS中的ID選擇符的磅符號。 http://www.w3.org/TR/css3-selectors/#id-selectors我的例子是用C而不是Python,但你可能會發現它們很有用。 http://www.gtkforums.com/viewtopic.php?f=3&t=988&p=72088=Starting+with+version+3#p72088 – mike 2012-08-29 19:18:23

0

受@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() 

必須有辦法做到這一點....

3

儘管這是一個老問題,我想補充一個答案指只爲參考問題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; 
} 
+0

另一個相關的鏈接是https://wiki.gnome.org/HowDoI/Buttons其中提到_suggested_和_destructive_按鈕的一些標準類,它們不需要自定義CSS並分別以藍色和紅色突出顯示使用默認的Adwaita主題,Green是一個不錯的選擇,所以感謝您指出這很簡單,就像在CSS中添加背景規則一樣簡單......現在我要做的就是弄清楚如何在GTKmm下載入CSS文件,除非一種在代碼中添加CSS規則的方法?如果我可以避免,我寧願不依賴外部文件。 – 2016-06-13 11:18:21

相關問題