Home > wxpython > wx.CheckListBox: background items

wx.CheckListBox: background items

8 Marzo 2011

Quello che vorrei ottenere è una checklistbox
da un dizionario, che ordini i propri valori in base ai
valori del dizionario stesso, ma ne visualizzi le chiavi
e ne colori il background, in base ai valori.

(Che cosa inutile…..)

Il dizionario è così strutturato:

players = {u'AMBROSINI Massimo': 505, u'BENTIVOGLIO Simone': 514,
           u'ASAMOAH Kwadwo': 509, u'AMELIA Marco': 103,
           u'ANTONELLI Luca': 206, u'ARIAUDO Lorenzo': 209,
           u'ABBIATI Christian': 101,.....}

In pratica i giocatori (keys) voglio ordinarli
in base al proprio ID (value).
Se l’id è <200 si tratta di portiere,
se l'id è 200 di difensore e così via.
Vorrei colorare il giocatore nella checklistbox
e mettere in fila, portieri-difensori ecc.

Per come NON vengono ordinati i dati all’interno del dizionario,
devo ordinarli io prima di passarli alla checklistbox.
Sono sicuro ci siano metodi più eleganti e performanti, ma io
ottengo l’ordinamento per chiave così :

>>> players_ord = players.values()
>>> players_ord.sort()
>>> for value in players_ord:
	for item in players:
		if value == players.get(item):
			players_ord[players_ord.index(value)] = item

>>> print players_ord
[u'ABBIATI Christian', u'AGAZZI Micheal', u'AMELIA Marco', u'ABATE Ignazio', u'ACCARDI Pietro', u'AGOSTINI Alessandro', u'ALVAREZ Pablo Sebastian', u'ANTONELLI Luca', u'ANTONINI Luca', u'ARIAUDO Lorenzo', u'ASTORI Davide', u'ALMIRON Sergio Bernardo', u'AMBROSINI Massimo', u'ANTONELLI Filippo', u'ASAMOAH Kwadwo', u'BADU Emmanuel Agyemang', u'BARRIENTOS Pablo', u'BENTIVOGLIO Simone', u'AQUILANI Alberto', u'ADIYIAH Dominic', u'AMAURI Carvalho De Oliveira', u'BAPTISTA Julio', u'BARRETO Gonzalo', u'BERNACCI Marco', u'BOAKYE Yiaodim']

ecco che i dati sono ordinati per valore (value del dizionario) ma
con indicata la chiave.

Una volta passata la lista ordinata alla checklistbox, non resta che
colorare il background dell’item della checklistbox (chiave
del dizionario), in base al proprio valore (value del dizionario.
Questa cosa l’ho ottenuta così:

for player in self.view.clb.GetItems():
	index = (self.players_ord.index(player))
        if int(self.players.get(player)) < 200 :
            self.view.clb.SetItemBackgroundColour(index, 'yellow')
        elif int(self.players.get(player)) < 500 and int(self.players.get(player)) > 200:
            self.view.clb.SetItemBackgroundColour(index, 'pink')
        elif int(self.players.get(player)) < 800 and int(self.players.get(player)) > 500:
            self.view.clb.SetItemBackgroundColour(index, 'cyan')
        else:
            self.view.clb.SetItemBackgroundColour(index, 'white')

In pratica, invece di iterare con il “for”, la lista passata alla
checklistbox, itero direttamente sulla lista generata dal metodo
GetItems() della checklistbox, così sono sicuro di utilizzare
l’indice giusto per la colorazione del background dell’item.
Poi, siccome il valore ‘player’ del ciclo for, è anche per forza di
cose una chiave del dizionario, ne ricavo il suo valore
(metodo dict.get(k)).
Lo testo, ed in base all’esito coloro il background grazie
all’indice immagazzinato durante l’iterazione.

Senz’altro ci sono metodi migliori di questo, ma l’esito è quello che cercavo:

Come si nota nei centrocampisti (azzurri), ‘Aquilani’ viene per ultimo.
Questo è dovuto al suo valore id maggiore, dovuto ad un post-tesseramento,
ma queste sono cose da Fantacalcisti…

Ilcodice di esempio, quindi….

import wx

class CLBColorModel():
    '''Model per la consegna delle formazioni'''
    def __init__(self):
        self.players = {u'AMBROSINI Massimo': 505, u'BENTIVOGLIO Simone': 514,
                        u'ASAMOAH Kwadwo': 509, u'AMELIA Marco': 103, u'ANTONELLI Luca': 206,
                        u'ARIAUDO Lorenzo': 209, u'ABBIATI Christian': 101, u'BERNACCI Marco': 814,
                        u'ACCARDI Pietro': 202, u'AGOSTINI Alessandro': 203, u'BAPTISTA Julio': 810,
                        u'BADU Emmanuel Agyemang': 510, u'AGAZZI Micheal': 102, u'ALMIRON Sergio Bernardo': 503,
                        u'ALVAREZ Pablo Sebastian': 204, u'ADIYIAH Dominic': 803, u'ANTONINI Luca': 207,
                        u'BARRIENTOS Pablo': 512, u'ASTORI Davide': 211, u'AQUILANI Alberto': 706,
                        u'BARRETO Gonzalo': 812, u'BOAKYE Yiaodim': 816, u'ABATE Ignazio': 201,
                        u'ANTONELLI Filippo': 507, u'AMAURI Carvalho De Oliveira': 806}
    def getSortedPlayers(self):
        '''ottiene la rosa di una squadra, passandone il
        nome come parametro'''
        players_ord = self.players.values()
        players_ord.sort()
        for value in players_ord:
            for item in self.players:
                if value == self.players.get(item):
                    players_ord[players_ord.index(value)] = item
        return self.players, players_ord

class CLBColorView(wx.Frame):
    '''GUI per la creazione della squadra'''
    def __init__(self, parent):
        '''Costruttore del frame'''
        wx.Frame.__init__(self, None, -1, 'Team manager', size=(300, 500))
    def createWidgets(self, players):
        '''crea i widgets necessari alla creazione della squadra'''
        self.panel = wx.Panel(self, -1)
        self.clb = wx.CheckListBox(self.panel, -1, size = ( 200, 400 ), choices = players, style = wx.LB_HSCROLL )
        self.btn_exit = wx.Button(self.panel, wx.ID_ANY, 'Exit')
    def SizerizeWidgets(self):
        '''posiziona i vari widgets nella posizione stabilita'''
        self.vbox = wx.BoxSizer(wx.VERTICAL)
        self.vbox.Add(self.clb, 0, wx.ALL|wx.CENTER, 5)
        self.vbox.Add(wx.StaticLine(self.panel,), 0, wx.ALL|wx.EXPAND, 5)
        self.vbox.Add(self.btn_exit, 0, wx.CENTER)
        self.panel.SetSizer(self.vbox)
        self.Centre()
        
class CLBColorController:
    def __init__(self):
        '''Costruttore controller'''
        self.model = CLBColorModel()
        self.players, self.players_ord = self.model.getSortedPlayers()
        self.createView()

    def createView(self):
        '''crea la view e la rende visibile'''
        self.view = CLBColorView(None)
        self.view.createWidgets(self.players_ord)
        self.view.SizerizeWidgets()
        self.view.Show()
        for player in self.view.clb.GetItems():
            index = (self.players_ord.index(player)) # indice per la colorazione del player
            if int(self.players.get(player)) < 200 : # qui controllo il 'value' legato alla 'key'
                self.view.clb.SetItemBackgroundColour(index, 'yellow') #lo coloro in base al valore
            elif int(self.players.get(player)) < 500 and int(self.players.get(player)) > 200:
                self.view.clb.SetItemBackgroundColour(index, 'pink')
            elif int(self.players.get(player)) < 800 and int(self.players.get(player)) > 500:
                self.view.clb.SetItemBackgroundColour(index, 'cyan')
            else:
                self.view.clb.SetItemBackgroundColour(index, 'white')
        self.view.btn_exit.Bind(wx.EVT_BUTTON, self.onExit)
        self.view.clb.Bind(wx.EVT_CHECKLISTBOX, self.onPlayers )

    def onPlayers(self, evt):
        '''handler click checklistbox Portieri'''
        pass
    
    def onExit(self, evt):
        '''handler button di uscita'''
        self.view.Close()
        
if __name__ == '__main__':
    app = wx.App(False)
    controller = CLBColorController()
    app.MainLoop()
Categorie:wxpython Tag:
I commenti sono chiusi.