giovedì 24 gennaio 2013

Widgets - seconda parte

 Salve!

Continuo la rassegna dei widgets (window's objects) iniziata qui.

wx.ComboBox:
Permette di selezionare una e una sola opzione da una lista (combo.py):

#!/usr/bin/python
# -*- coding: utf-8 -*-

import wx

class Example(wx.Frame):
    def __init__(self, *args, **kw):
        super(Example, self).__init__(*args, **kw) 
        
        pnl = wx.Panel(self)
        distros = ['Ubuntu', 'Arch', 'Fedora', 'Debian', 'Mint']
        cb = wx.ComboBox(pnl, pos=(50, 30), choices=distros, 
            style=wx.CB_READONLY)

        self.st = wx.StaticText(pnl, label='', pos=(50, 140))
        cb.Bind(wx.EVT_COMBOBOX, self.OnSelect)
        
        self.SetSize((250, 230))
        self.SetTitle('wx.ComboBox')
        self.Centre()
        self.Show(True)          
        
    def OnSelect(self, e):
        i = e.GetString()
        self.st.SetLabel(i)
        
def main():
    ex = wx.App()
    Example(None)
    ex.MainLoop()    

if __name__ == '__main__':
    main()   

wx.CheckBox
È un widget con due stati: on e off, in una box con un'etichetta (check.py):
#!/usr/bin/python
# -*- coding: utf-8 -*-

import wx

class Example(wx.Frame):
    def __init__(self, *args, **kw):
        super(Example, self).__init__(*args, **kw) 
        

        pnl = wx.Panel(self)

        cb = wx.CheckBox(pnl, label='Show title', pos=(20, 20))
        cb.SetValue(True)

        cb.Bind(wx.EVT_CHECKBOX, self.ShowOrHideTitle)

        self.SetSize((250, 170))
        self.SetTitle('wx.CheckBox')
        self.Centre()
        self.Show(True)    

    def ShowOrHideTitle(self, e):
        sender = e.GetEventObject()
        isChecked = sender.GetValue()
        
        if isChecked:
            self.SetTitle('wx.CheckBox')            
        else: 
            self.SetTitle('')        
                       
def main():
    ex = wx.App()
    Example(None)
    ex.MainLoop()    

if __name__ == '__main__':
    main()   

wx.StatusBar
Usata per visualizzare informazioni sullo stato dell'applicazione. Può essere divisa in più parti (stbar.py):
#!/usr/bin/python
# -*- coding: utf-8 -*-

import wx

class Example(wx.Frame):
           
    def __init__(self, *args, **kw):
        super(Example, self).__init__(*args, **kw) 
        
        pnl = wx.Panel(self)

        button = wx.Button(pnl, label='Button', pos=(20, 20))
        text = wx.CheckBox(pnl, label='CheckBox', pos=(20, 90))
        combo = wx.ComboBox(pnl, pos=(120, 22), choices=['Python', 'Ruby'])
        slider = wx.Slider(pnl, 5, 6, 1, 10, (120, 90), (110, -1))        

        pnl.Bind(wx.EVT_ENTER_WINDOW, self.OnWidgetEnter)
        button.Bind(wx.EVT_ENTER_WINDOW, self.OnWidgetEnter)
        text.Bind(wx.EVT_ENTER_WINDOW, self.OnWidgetEnter)
        combo.Bind(wx.EVT_ENTER_WINDOW, self.OnWidgetEnter)
        slider.Bind(wx.EVT_ENTER_WINDOW, self.OnWidgetEnter)

        self.sb = self.CreateStatusBar()

        self.SetSize((330, 230))
        self.SetTitle('wx.Statusbar')
        self.Centre()
        self.Show(True)     

    def OnWidgetEnter(self, e):
        
        name = e.GetEventObject().GetClassName()
        self.sb.SetStatusText(name + ' widget')
        e.Skip()               
        
def main():
    ex = wx.App()
    Example(None)
    ex.MainLoop()    

if __name__ == '__main__':
    main()   
con il metodo OnWidgetEnter determiniamo su che oggetto è il puntatore del mouse.

 wx.RadioButton
Permette di scegliere un solo elemento da un gruppo. Per definire il gruppo di pulsanti mettere wx.RB_GROUP, tutti gli altri vengono aggregati al gruppo. Per definire un altro gruppo basta rimettere quell'opzione (radio.py):
#!/usr/bin/python
# -*- coding: utf-8 -*-

import wx

class Example(wx.Frame):
           
    def __init__(self, *args, **kw):
        super(Example, self).__init__(*args, **kw) 
        
        pnl = wx.Panel(self)

        self.rb1 = wx.RadioButton(pnl, label='Value A', pos=(10, 10), 
            style=wx.RB_GROUP)
        self.rb2 = wx.RadioButton(pnl, label='Value B', pos=(10, 30))
        self.rb3 = wx.RadioButton(pnl, label='Value C', pos=(10, 50))
        
        self.rb1.Bind(wx.EVT_RADIOBUTTON, self.SetVal)
        self.rb2.Bind(wx.EVT_RADIOBUTTON, self.SetVal)
        self.rb3.Bind(wx.EVT_RADIOBUTTON, self.SetVal)

        self.sb = self.CreateStatusBar(3)
        
        self.sb.SetStatusText("True", 0)
        self.sb.SetStatusText("False", 1)
        self.sb.SetStatusText("False", 2)   

        self.SetSize((210, 210))
        self.SetTitle('wx.RadioButton')
        self.Centre()
        self.Show(True)     

    def SetVal(self, e):
        
        state1 = str(self.rb1.GetValue())
        state2 = str(self.rb2.GetValue())
        state3 = str(self.rb3.GetValue())

        self.sb.SetStatusText(state1, 0)
        self.sb.SetStatusText(state2, 1)
        self.sb.SetStatusText(state3, 2)            
        
def main():
    
    ex = wx.App()
    Example(None)
    ex.MainLoop()    

if __name__ == '__main__':
    main()   

wx.Gauge
Usato per le operazioni che richiedono tempo; indica a che punto è. La cosa più difficile è pronunciarne bene il nome, i 'mericani dicono ghèic (la "g" finale come quella di gioco, Google translaor sbaglia).
(gauge.py):
#!/usr/bin/python
# -*- coding: utf-8 -*-

import wx

TASK_RANGE = 50

class Example(wx.Frame):
           
    def __init__(self, *args, **kw):
        super(Example, self).__init__(*args, **kw) 
        
        self.timer = wx.Timer(self, 1)
        self.count = 0

        self.Bind(wx.EVT_TIMER, self.OnTimer, self.timer)

        pnl = wx.Panel(self)
        vbox = wx.BoxSizer(wx.VERTICAL)
        hbox1 = wx.BoxSizer(wx.HORIZONTAL)
        hbox2 = wx.BoxSizer(wx.HORIZONTAL)
        hbox3 = wx.BoxSizer(wx.HORIZONTAL)

        self.gauge = wx.Gauge(pnl, range=TASK_RANGE, size=(250, 25))
        self.btn1 = wx.Button(pnl, wx.ID_OK)
        self.btn2 = wx.Button(pnl, wx.ID_STOP)
        self.text = wx.StaticText(pnl, label='Task to be done')

        self.Bind(wx.EVT_BUTTON, self.OnOk, self.btn1)
        self.Bind(wx.EVT_BUTTON, self.OnStop, self.btn2)

        hbox1.Add(self.gauge, proportion=1, flag=wx.ALIGN_CENTRE)
        hbox2.Add(self.btn1, proportion=1, flag=wx.RIGHT, border=10)
        hbox2.Add(self.btn2, proportion=1)
        hbox3.Add(self.text, proportion=1)
        vbox.Add((0, 30))
        vbox.Add(hbox1, flag=wx.ALIGN_CENTRE)
        vbox.Add((0, 20))
        vbox.Add(hbox2, proportion=1, flag=wx.ALIGN_CENTRE)
        vbox.Add(hbox3, proportion=1, flag=wx.ALIGN_CENTRE)

        pnl.SetSizer(vbox)
        
        self.SetSize((300, 200))
        self.SetTitle('wx.Gauge')
        self.Centre()
        self.Show(True)     

    def OnOk(self, e):
        
        if self.count >= TASK_RANGE:
            return

        self.timer.Start(100)
        self.text.SetLabel('Task in Progress')

    def OnStop(self, e):
        if self.count == 0 or self.count >= TASK_RANGE or not self.timer.IsRunning():
            return

        self.timer.Stop()
        self.text.SetLabel('Task Interrupted')
        
    def OnTimer(self, e):
        self.count = self.count + 1
        self.gauge.SetValue(self.count)
        
        if self.count == TASK_RANGE:

            self.timer.Stop()
            self.text.SetLabel('Task Completed')
                      
def main():
    ex = wx.App()
    Example(None)
    ex.MainLoop()    

if __name__ == '__main__':
    main()   
In questo caso l'aggiornamento avviene in base al tempo (OnTimer()), probabilmente nei casi reali l'aggiornamento SetValue() sarà funzione di altri evanti.

wx.Slider
Il cursore che può essere spostato sulla barra di riferimento (slider.py):
#!/usr/bin/python
# -*- coding: utf-8 -*-

import wx

class Example(wx.Frame):
           
    def __init__(self, *args, **kw):
        super(Example, self).__init__(*args, **kw) 
        
        pnl = wx.Panel(self)

        sld = wx.Slider(pnl, value=200, minValue=150, maxValue=500, pos=(20, 20), 
            size=(250, -1), style=wx.SL_HORIZONTAL)
        
        sld.Bind(wx.EVT_SCROLL, self.OnSliderScroll)
        
        self.txt = wx.StaticText(pnl, label='200', pos=(20, 90))               
        
        self.SetSize((290, 200))
        self.SetTitle('wx.Slider')
        self.Centre()
        self.Show(True)    

    def OnSliderScroll(self, e):
        obj = e.GetEventObject()
        val = obj.GetValue()
        
        self.txt.SetLabel(str(val))        
                      
def main():
    ex = wx.App()
    Example(None)
    ex.MainLoop()    

if __name__ == '__main__':
    main()   

wx.SpinCtrl
Permette di incrementare o decrementare un valore, i geek scrivono direttamente il valore dentro la box (spin.py):
#!/usr/bin/python
# -*- coding: utf-8 -*-

import wx

class Example(wx.Frame):
           
    def __init__(self, *args, **kw):
        super(Example, self).__init__(*args, **kw) 
        
        pnl = wx.Panel(self)
        
        wx.StaticText(self, label='Convert Fahrenheit temperature to Celsius', 
            pos=(20,20))
        wx.StaticText(self, label='Fahrenheit: ', pos=(20, 80))
        wx.StaticText(self, label='Celsius: ', pos=(20, 150))
        
        self.celsius = wx.StaticText(self, label='', pos=(150, 150))
        self.sc = wx.SpinCtrl(self, value='0', pos=(150, 75), size=(60, -1))
        self.sc.SetRange(-459, 1000)
        
        btn = wx.Button(self, label='Compute', pos=(70, 230))
        btn.SetFocus()
        cbtn = wx.Button(self, label='Close', pos=(185, 230))

        btn.Bind(wx.EVT_BUTTON, self.OnCompute)
        cbtn.Bind(wx.EVT_BUTTON, self.OnClose)
           
        self.SetSize((350, 310))
        self.SetTitle('wx.SpinCtrl')
        self.Centre()
        self.Show(True)          
        
    def OnClose(self, e):
        self.Close(True)    
        
    def OnCompute(self, e):
        fahr = self.sc.GetValue()
        cels = round((fahr - 32) * 5 / 9.0, 2)
        self.celsius.SetLabel(str(cels))        
                      
def main():
    ex = wx.App()
    Example(None)
    ex.MainLoop()    

if __name__ == '__main__':
    main()          
Basta widget! Chi ha seguito le lezioni fino a oggi sarà diventato così esperto che i commenti sono quasi superflui. Per questo li ho ridotti al minimo. Protestate se necessario.

Il caro Juhan

L'indice di "Mission Python" qui.

Alla prossima!

Nessun commento:

Posta un commento