qgis/QGIS — pull request #1518 by nyalldawson (2014-07-26 12:22:32+00:00)
Title: Improved color button

This started off as a rebase of QgsColorButton to derive from QToolButton, but grew considerably!

Features are
- context menu items have been moved to the attached menu button
- new gui widget QgsColorSwatchGrid, which displays a grid of colors. See "recent colors" section in the screenshot below:

![image](https://cloud.githubusercontent.com/assets/1829991/3711006/ed9f9f0c-14b8-11e4-8912-925b43cbc830.png)

- new class for QgsColorScheme, which generates colors to show in a color swatch grid (see below for examples)
- built in QgsColorScheme for recently used colors
- new class QgsColorSchemeRegistry, with a global instance containing default color schemes.
- QgsColorButtonV2 accepts a color scheme registry (defaults to the global instance), to control which schemes to show in the popup menu as color swatch grids.
- color button can have an optional default color
- color button can also be quickly set to a totally transparent color:

![image](https://cloud.githubusercontent.com/assets/1829991/3711009/6e34cc3c-14b9-11e4-8c13-ccbe9cb7642e.png)

- c++ and python unit tests for all core components

Ok, that's the basics... here's the cool stuff. It's really easy to create new QgsColorSchemes using python plugins. Eg, creating a scheme for a set of preset colors (eg, standard company colors):

class QgsCgaLightColorScheme(QgsColorScheme):
def __init__(self, parent=None):
QgsColorScheme.__init__(self)

def schemeName(self):
return "CGA Colors!"

def fetchColors(self,context='', basecolor=QColor()):
return [[QColor('#555555'),'Gray'],
[QColor('#5555FF'),'Light Blue'],
[QColor('#55FF55'),'Light Green'],
[QColor('#55FFFF'),'Light Cyan'],
[QColor('#FF5555'),'Light Red'],
[QColor('#FF55FF'),'Light Magenta'],
[QColor('#FFFF55'),'Yellow'],
[QColor('#FFFFFF'),'White']]

def clone(self):
return QgsCgaLightColorScheme()

QgsColorSchemeRegistry.instance().addColorScheme( QgsCgaLightColorScheme() )

This scheme will now appear in all QgsColorButtonV2 menus:

![image](https://cloud.githubusercontent.com/assets/1829991/3711033/a1720c62-14ba-11e4-811d-6e12b873cc61.png)

QgsColorSchemes can also utilise a "base color" when generating their color list. Here's a sample color scheme which generates random colors similar to the base color:

import random
class QgsRandomColorScheme(QgsColorScheme):
def __init__(self, parent=None):
QgsColorScheme.__init__(self)

def schemeName(self):
return "Random colors!"

def fetchColors(self,context='', basecolor=QColor()):
noColors = random.randrange(30)
minVal = 130;
maxVal = 255;
colorList = []
for i in range(noColors):
if basecolor.isValid():
h = basecolor.hue()
else:
#generate random hue
h = random.randrange(360);

s = random.randrange(100,255)
v = random.randrange(100,255)

colorList.append( [ QColor.fromHsv( h, s, v), "random color! " + str(i) ] )

return colorList

def clone(self):
return QgsRandomColorScheme()

QgsColorSchemeRegistry.instance().addColorScheme( QgsRandomColorScheme() )

Here's how it looks:

![image](https://cloud.githubusercontent.com/assets/1829991/3711045/0b63cf7e-14bc-11e4-8d09-9619ae12df3a.png)

One final fun example... here's a color scheme which grabs its colors using the Color Lovers API to fetch a random popular palette:

from xml.etree import ElementTree
import urllib2
import random

class colorLoversScheme(QgsColorScheme):

def __init__(self, parent=None):
QgsColorScheme.__init__(self)
xmlurl = 'http://www.colourlovers.com/api/palettes/top'

headers = { 'User-Agent' : 'Mozilla/5.0' }
req = urllib2.Request(xmlurl, None, headers)
doc = ElementTree.parse(urllib2.urlopen(req)).getroot()

palettes = doc.findall('palette')
palette = random.choice(palettes)

title = palette.find('title').text
username = palette.find('userName').text
attrString = title + ' by ' + username
colors = ['#'+c.text for c in palette.find('colors').findall('hex')]

self.color_list = [[QColor(c), attrString] for c in colors]

def schemeName(self):
return "Color lovers popular palette"

def fetchColors(self,context='', basecolor=QColor()):
return self.color_list

def clone(self):
return colorLoversScheme()

loversScheme = colorLoversScheme()
QgsColorSchemeRegistry.instance().addColorScheme( loversScheme )

![image](https://cloud.githubusercontent.com/assets/1829991/3711084/0b551350-14bf-11e4-8c63-92c4ae06ab4a.png)

This pull request only switches a few buttons to QgsColorButtonV2 for testing - the two color buttons from the project properties (selection color and background color) (these implement the new default color option), and the fill and outline color buttons from the simple fill symbol widget (which implement the new transparent color shortcut).

One major change from QgsColorButton is that labels on the buttons are no longer supported - only the icon is shown.