title: How to change pygtk gtk.Button color PROPERLY
body: <p>In my application, I have about 500 buttons which all update their labels and colors when specific actions are taken. I was running into crashes and performance issues when I noticed (by using cProfile and pdb) that the problem was caused by changing the button color:</p>
  
  <pre><code>self.button.modify_bg(gtk.STATE_PRELIGHT, color)
  self.button.modify_bg(gtk.STATE_NORMAL, color)
  </code></pre>
  
  <p>500 calls like this need an eternity of 5 seconds (which also freezes GUI) and it gets even slower the longer the application runs. In case someone wonders, I have a powerful processor and lots of free memory.</p>
  
  <p>Previously I was trying to use EventBox as recommended in the <a href="http://faq.pygtk.org/index.py?req=edit&amp;file=faq04.016.htp" rel="nofollow noreferrer">docs</a>. However this only changes the color behind the button, not on its surface:</p>
  
  <pre><code>import gtk
  
  win = gtk.Window()
  win.connect("destroy", gtk.main_quit)
  
  btn = gtk.Button("test")
  eb = gtk.EventBox()
  eb.add(btn)
  eb.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse("red"))
  
  win.add(eb)
  win.show_all()
  
  gtk.main()
  </code></pre>
  
  <p>Result:</p>
  
  <p><a href="https://i.stack.imgur.com/2UzO0.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/2UzO0.png" alt="button is not red"></a></p>
  
  <p>I also tried the alternative which involves retrieving and modifying the the style. This led to the same slowness as with <code>modify_bg</code>. In addition I also got random crashes at random places, usually with low level memory allocation errors such as double freeing from gtk.</p>
  
  <pre><code>import gtk
  
  win = gtk.Window()
  win.connect("destroy", gtk.main_quit)
  
  btn = gtk.Button("test")
  #copy the current style and replace the background
  style = btn.get_style().copy()
  style.bg[gtk.STATE_NORMAL] = gtk.gdk.color_parse("red")
  
  #set the button's style to the one you created
  btn.set_style(style)
  
  win.add(btn)
  win.show_all()
  
  gtk.main()
  </code></pre>
  
  <p>It seems that the color of the button is managed by the operating system and I can't find a way around it without slowness, crashes or undesired results. I badly need to convey by color important information about the button.</p>
  
  <p>So how do I change the button color properly?</p>