Curs10 Python Gui
Curs10 Python Gui
1. Introducere
wxPython API conţine un set de funcţii şi controale pentru construirea interfeţelor grafice în
python, fiind construit peste framework-ul C++ GUI, denumit wxWidgets. La randul lui, wxWidgets
este un wrapper peste funcţiile native ale sistemului de operare folosit. De exemplu, pe Windows,
este un wrapper peste Winapi. O aplicaţie wxWidgets nu „desenează” controalele folosite (cum face
QT, de exemplu), ci foloseşte chiar controalele native. Pe Unix/Linux, cea mai stabila versiune este
un wrapper peste GTK 2.x.
wxWidgets a fost dezvoltat in C++, dar există şi diverse binding-uri pentru limbaje precum
Python sau Perl. Aceste binding-uri prezinta diverse nivele de integrare cu codul C++, cel mai
dezvoltat fiind cel de Python (cunoscut sub numele de wxPython).
Structura framework-ului wxWidgets, precum şi modul in care este folosit, prezinta
similaritati cu framework-ul MFC (Microsoft Foundation Classes).
1
import wx
Instanţierea unei aplicaţii de tip GUI se realizează prin apelarea funcţiei App():
app=wx.App()
frame.Show()
Pentru ca aplicaţia să fie funcţională, trebuie introdusă funcţia MainLoop(). Această funcţie
creează o buclă continuă care recepţionează toate evenimentele aplicaţiei. MainLoop reprezintă o
parte integrantă a oricărei aplicaţii de tip GUI.
app.MainLoop()
import wx
app = wx.App()
app.MainLoop()
2.1 wx.Window
2
wx.Window reprezintă clasa de bază din care sunt derivate toate controalele. De exemplu,
controlul wx.Frame moşteneşte clasa wx.Window, ceea ce înseamnă că metodele clasei wx.Window
pot fi apelate de către clasa wx.Frame.
În exemplul următor sunt apelate o serie de metode ale clasei wx.Window:
#ex2.py
import wx
app = wx.App()
app.MainLoop()
2.2 wx.Frame
wx.Frame este un container de widget-uri, având următorul constructor:
wx.Frame (wx.Window parent, id, string title, wx.Point pos=wx.DefaultPosition,
wx.Size size=wx.DefaultSize, style=wx.DEFAULT_FRAME_STYLE, string name='frame')
Dacă se omit o parte dintre parametri, trebuie specificaţi toţi parametri care urmează. De
exemplu, dacă se omite parametrul pos, atunci trebui specificat în mod explicit parametrul size:
frame = wx.Frame(None, 100, 'Title', size = wx.Size(100,100))
2.3 wx.MenuBar
Clasa wx.MenuBar este folosită atunci când se doreşte crearea unei bare de meniu. Opţiunile
unui meniu pot fi elemente simple, elemente de selecţie (check) sau elemente de tip radio.
Mai întâi, pentru a crea o bară de meniu, se instanţiază clasa wx.MenuBar():
baraMeniu = wx.MenuBar()
Pentru a separa logic un grup de opţiuni din cadrul unui meniu, se poate folosi un separator:
meniuFisier.AppendSeparator()
Pentru a introduce icon-uri în cadrul meniului, elementele meniului trebuie create manual.
Icon-urile pot fi doar imagini de tip bitmap, orice alt tip trebuie convertit la bitmap. De exemplu:
meniuIesire = wx.MenuItem(meniuFisier, 13, '&Iesire\tCtrl+Q', 'Parasire aplicatie')
meniuIesire.SetBitmap(wx.Image('icon_name.png', wx.BITMAP_TYPE_PNG).ConvertToBitmap())
meniuFisier.AppendItem(meniuIesire)
Meniurile de mai sus conţin elemente simple. Pentru a crea meniuri care să conţine elemente de
tip check sau radio, se foloseşte parametrul kind. Valorile posibile ale parametrului wx.ItemKind
sunt:
• wx.ITEM_NORMAL – element simplu
• wx.ITEM_CHECK – element de tip check
• wx.ITEM_RADIO – element de tip radio
Exemplele de mai jos descriu modul în care sunt create meniurile de tip check sau radio.
meniuEditare.Append(21, 'Selecteaza optiune 1', '', wx.ITEM_CHECK)
meniuEditare.Append(22, 'Selecteaza optiune 2', '', kind=wx.ITEM_CHECK)
Submeniurile sunt la rândul lor meniuri. Astfel, pentru a crea un submeniu, trebuie declarat
astfel:
submeniu = wx.Menu()
baraMeniu.Append(meniuFisier, '&Fisier')
4
baraMeniu.Append(meniuEditare, '&Editare')
baraMeniu.Append(meniuAjutor, '&Ajutor')
self.SetMenuBar(baraMeniu)
#ex3.py
import wx
class Meniu(wx.Frame):
def __init__(self, parent, id, title):
wx.Frame.__init__(self, parent, id, title, wx.DefaultPosition,
wx.Size(300, 150))
baraMeniu = wx.MenuBar()
meniuFisier = wx.Menu()
meniuEditare = wx.Menu()
meniuAjutor = wx.Menu()
meniuFisier.AppendSeparator()
submeniu = wx.Menu()
submeniu.Append(231, 'Element de tip radio 1', kind=wx.ITEM_RADIO)
submeniu.Append(232, 'Element de tip radio 2', kind=wx.ITEM_RADIO)
submeniu.Append(233, 'Element de tip radio 3', kind=wx.ITEM_RADIO)
meniuEditare.Append(23, 'Submeniu', submeniu)
baraMeniu.Append(meniuFisier, '&Fisier')
baraMeniu.Append(meniuEditare, '&Editare')
baraMeniu.Append(meniuAjutor, '&Ajutor')
self.SetMenuBar(baraMeniu)
self.CreateStatusBar()
class Aplicatie(wx.App):
def OnInit(self):
frame = Meniu(None, -1, 'Bara de meniu simpla')
frame.Show(True)
return True
app = Aplicatie()
app.MainLoop()
5
În continuare, trebuie definite acţiunile utilizatorilor. În momentul în care utilizatorul
selectează o opţiune din meniu este generat un eveniment. Pentru a realiza o anumită operaţie la
selectarea unei opţiuni a meniului, trebuie implementat un manager de evenimente. Pentru aceasta se
foloseşte clasa wx.EVT_MENU.
De exemplu, pentru a adăuga un eveniment opţiunii Iesire din cadrul meniului Fisier, trebuie
furnizate 3 informaţii:
- obiectul de care legăm evenimentul respectiv (obiectul aplicaţiei principale – self);
- id-ul elementului din meniu (13 – id-ul opţiunii Iesire);
- numele metodei care execută acţiunea (OnQuit).
wx.EVT_MENU(self, 13, self.OnQuit )
Metoda apelată la apariţia evenimentului are doi parametri: obiectul în cadrul căruia este
definită metoda şi evenimentul generat.
O altă modalitate de a lega evenimentul de o acţiune, este apelarea metodei Bind():
Exemplul de mai jos defineşte o metodă care închide frame-ul, precum şi o metodă care
afişează o fereastră de tip About.
#ex4.py
import wx
class Meniu(wx.Frame):
def __init__(self, parent, id, title):
wx.Frame.__init__(self, parent, id, title, wx.DefaultPosition,
wx.Size(300, 150))
baraMeniu = wx.MenuBar()
meniuFisier = wx.Menu()
meniuEditare = wx.Menu()
meniuAjutor = wx.Menu()
meniuFisier.AppendSeparator()
submeniu = wx.Menu()
submeniu.Append(231, 'Element de tip radio 1', kind=wx.ITEM_RADIO)
submeniu.Append(232, 'Element de tip radio 2', kind=wx.ITEM_RADIO)
submeniu.Append(233, 'Element de tip radio 3', kind=wx.ITEM_RADIO)
meniuEditare.AppendMenu(23, 'Submeniu', submeniu)
baraMeniu.Append(meniuFisier, '&Fisier')
6
baraMeniu.Append(meniuEditare, '&Editare')
baraMeniu.Append(meniuAjutor, '&Ajutor')
self.SetMenuBar(baraMeniu)
self.CreateStatusBar()
def OnHelp(self,event):
info = wx.AboutDialogInfo()
info.Name = "Hello World"
info.Version = "1.0"
info.Copyright = "(C) 2010"
info.Description = "Aici va aparea descrierea aplicatiei"
info.WebSite = ("http://www.domeniu.com", "Adresa web site")
info.Developers = [ "Popescu A.",
"Ionescu G.",
"Georgescu H." ]
wx.AboutBox(info)
class Aplicatie(wx.App):
def OnInit(self):
frame = Meniu(None, -1, 'Bara de meniu simpla')
frame.Show(True)
return True
app = Aplicatie()
app.MainLoop()
#ex5.py
import wx
class MyFrame(wx.Frame):
def __init__(self, parent, id, title):
wx.Frame.__init__(self, parent, id, title, wx.DefaultPosition,
wx.Size(250, 50))
class MyApp(wx.App):
def OnInit(self):
frame = MyFrame(None, -1, 'Panou cu layout fix')
frame.Show(True)
frame.Centre()
return True
app = MyApp(0)
app.MainLoop()
7
În această situaţie, dacă fereastra este redimensionată, dimensiunea şi poziţia butoanelor nu
se va schimba.
b) Cea de-a doua metodă este folosirea unor managere pentru aspect. Cele mai folosit sunt
obiectele de tip Sizer:
• wx.BoxSizer
• wx.StaticBoxSizer
• wx.GridSizer
• wx.GridBagSizer
3.1 wx.BoxSizer
Utilizarea unui sizer permite ca aplicaţia precedentă să poată fi modificată astfel încât
redimensionând fereastra, vor fi redimensionate automat şi butoanele:
#ex6.py
import wx
class MyFrame(wx.Frame):
def __init__(self, parent, id, title):
wx.Frame.__init__(self, parent, id, title, (-1, -1), wx.Size(250, 50))
class MyApp(wx.App):
def OnInit(self):
frame = MyFrame(None, -1, 'Exemplu de obiect BoxSizer')
frame.Show(True)
return True
app = MyApp(0)
app.MainLoop()
Într-un BoxSizer, controalele pot fi plasate pe orizontală sau pe verticală. Sintaxa este:
box = wx.BoxSizer(integer orientation)
8
#ex7.py
import wx
class MyFrame(wx.Frame):
def __init__(self, parent, id, title):
wx.Frame.__init__(self, parent, id, title, (-1, -1), wx.Size(250, 50))
panel = wx.Panel(self, -1)
box = wx.BoxSizer(wx.HORIZONTAL)
box.Add(wx.Button(panel, -1, 'Buton1'), 0 )
box.Add(wx.Button(panel, -1, 'Buton2'), 1 )
box.Add(wx.Button(panel, -1, 'Buton3'), 2 )
panel.SetSizer(box)
self.Centre()
class MyApp(wx.App):
def OnInit(self):
frame = MyFrame(None, -1, 'Exemplu de utilizare a parametrului
"proportion"')
frame.Show(True)
return True
app = MyApp(0)
app.MainLoop()
Parametrul flag permite configurarea dimensiunilor marginilor (padding). Acesta poate lua
următoarele valori:
• wx.LEFT
• wx.RIGHT
• wx.BOTTOM
• wx.TOP
• wx.ALL
Aceste valori pot fi combinate cu ajutorul operatorului |. De exemplu: wx.LEFT | wx.TOP.
Folosirea flag-ului wx.EXPAND permite ca un control să ocupe tot spaţiu disponibil în direcţia
perpendiculară pe direcţia de orientare a sizer-ului.
De asemenea poate fi stabilită alinierea controalelor faţă de marginile ferestrei, folosind
următoarele flag-uri:
• wx.ALIGN_LEFT
• wx.ALIGN_RIGHT
• wx.ALIGN_TOP
• wx.ALIGN_BOTTOM
• wx.ALIGN_CENTER_VERTICAL
• wx.ALIGN_CENTER_HORIZONTAL
• wx.ALIGN_CENTER
Exemplu: aplicarea flag-urilor prezentate mai sus
#ex8.py
import wx
class MyFrame(wx.Frame):
def __init__(self, parent, id, title):
wx.Frame.__init__(self, parent, id, title, (-1, -1), wx.Size(450, 300))
9
box.Add(wx.Button(panel, -1, 'Buton3'), 0, wx.ALIGN_CENTER)
box.Add(wx.Button(panel, -1, 'Buton4'), 0, wx.TOP | wx.RIGHT | wx.LEFT,
50)
panel.SetSizer(box)
class MyApp(wx.App):
def OnInit(self):
frame = MyFrame(None, -1, 'Utilizarea flag-urilor pentru margini si pentru
aliniere')
frame.Show(True)
return True
app = MyApp(0)
app.MainLoop()
Crearea unei interfeţe mai complexe necesită ca obiectele de tip BoxSizer să poată fi
combinate, incluzând un BoxSizer în alt BoxSizer.
#ex9.py
import wx
class MyForm(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, wx.ID_ANY, title='Controale imbricate')
sizerPrincipal = wx.BoxSizer(wx.VERTICAL)
sizerTitlu = wx.BoxSizer(wx.HORIZONTAL)
sizerNume = wx.BoxSizer(wx.HORIZONTAL)
sizerPrenume = wx.BoxSizer(wx.HORIZONTAL)
sizerTelefon = wx.BoxSizer(wx.HORIZONTAL)
sizerEmail = wx.BoxSizer(wx.HORIZONTAL)
btnSizer = wx.BoxSizer(wx.HORIZONTAL)
sizerTitlu.Add(lblTitlu, 0, wx.ALL, 5)
sizerNume.Add(lblNume, 0, wx.ALL, 5)
sizerNume.Add(txtNume, 1, wx.ALL|wx.EXPAND, 5)
10
sizerPrenume.Add(lblPrenume, 0, wx.ALL, 5)
sizerPrenume.Add(txtPrenume, 1, wx.ALL|wx.EXPAND, 5)
sizerTelefon.Add(lblTelefon, 0, wx.ALL, 5)
sizerTelefon.Add(txtTelefon, 1, wx.ALL|wx.EXPAND, 5)
sizerEmail.Add(lblEmail, 0, wx.ALL, 5)
sizerEmail.Add(txtEmail, 1, wx.ALL|wx.EXPAND, 5)
btnSizer.Add(btnOK, 0, wx.ALL, 5)
btnSizer.Add(btnCancel, 0, wx.ALL, 5)
sizerPrincipal.Add(sizerTitlu, 0, wx.CENTER)
sizerPrincipal.Add(wx.StaticLine(self.panel), 0, wx.ALL|wx.EXPAND, 5)
sizerPrincipal.Add(sizerNume, 0, wx.ALL|wx.EXPAND, 5)
sizerPrincipal.Add(sizerPrenume, 0, wx.ALL|wx.EXPAND, 5)
sizerPrincipal.Add(sizerTelefon, 0, wx.ALL|wx.EXPAND, 5)
sizerPrincipal.Add(sizerEmail, 0, wx.ALL|wx.EXPAND, 5)
sizerPrincipal.Add(wx.StaticLine(self.panel), 0, wx.ALL|wx.EXPAND, 5)
sizerPrincipal.Add(btnSizer, 0, wx.ALL|wx.CENTER, 5)
self.panel.SetSizer(sizerPrincipal)
sizerPrincipal.Fit(self)
if __name__ == '__main__':
app = wx.PySimpleApp()
frame = MyForm().Show()
app.MainLoop()
4. wxDialogs
În wxPython se pot folosi ferestre de dialog predefinite sau programatorii îşi pot crea propriile
ferestre de dialog.
Există două tipuri de ferestre de dialog: modale şi nemodale. Cele modale nu permit ca
utilizatorul să mai interacţioneze cu restul aplicaţiei până când acestea sunt distruse. Sunt create cu
ajutorul funcţiei ShowModal().
Ferestrele de dialog nemodale sunt apelate cu metoda Show().
În ambele cazuri, metoda Destroy() este obligatorie. Ea şterge obiectul din memorie, iar dacă
nu este distrus, scriptul nu va funcţiona corect.
Metoda CreateTextSizer() creează un sizer ce afişează un text şi care poate conţine butoane
paticularizate.
#ex10.py
11
import wx
class MyDialog(wx.Dialog):
def __init__(self, parent, id, title):
wx.Dialog.__init__(self, parent, id, title, size=(300,300))
class MyFrame(wx.Frame):
def __init__(self, parent, id, title):
wx.Frame.__init__(self, parent, id, title, size=(400,400))
class MyApp(wx.App):
def OnInit(self):
frame = MyFrame(None, -1, 'TextSizer')
frame.Show(True)
frame.Centre()
return True
app = MyApp(0)
app.MainLoop()
#ex11.py
import wx
class MyDialog(wx.Dialog):
def __init__(self, parent, id, title):
wx.Dialog.__init__(self, parent, id, title)
vbox = wx.BoxSizer(wx.VERTICAL)
stline = wx.StaticText(self, 11, 'Aceasta fereastra de dialog contine
butoane predefinite')
vbox.Add(stline, 1, wx.ALIGN_CENTER|wx.TOP, 45)
sizer = self.CreateButtonSizer(wx.NO|wx.YES|wx.HELP)
vbox.Add(sizer, 0, wx.ALIGN_CENTER)
self.SetSizer(vbox)
self.Bind(wx.EVT_BUTTON, self.OnYes, id=wx.ID_YES)
12
def OnYes(self, event):
self.Close()
class MyFrame(wx.Frame):
def __init__(self, parent, id, title):
wx.Frame.__init__(self, parent, id, title)
panel = wx.Panel(self, -1)
wx.Button(panel, 1, 'Afiseaza fereastra de dialog', (50,50))
self.Bind(wx.EVT_BUTTON, self.OnButtonSizer, id=1)
class MyApp(wx.App):
def OnInit(self):
frame = MyFrame(None, -1, 'ButtonTextSizer')
frame.Show(True)
frame.Centre()
return True
app = MyApp(0)
app.MainLoop()
#ex12.py
import wx
import os, sys
class MyFrame(wx.Frame):
def __init__(self, parent, id, title):
wx.Frame.__init__(self, parent, id, title)
self.CreateStatusBar()
menuBar = wx.MenuBar()
menu = wx.Menu()
menu.Append(99, "&Message Dialog", "Shows a Message Dialog")
menu.Append(100, "&Color Dialog", "Shows a Color Dialog")
menu.Append(101, "&File Dialog", "Shows a File Dialog")
menu.Append(102, "&Page Setup Dialog", "Shows a Page Setup Dialog")
menu.Append(103, "&Font Dialog", "Shows a Font Dialog")
menu.Append(104, "&Directory Dialog", "Shows a Directory Dialog")
menu.Append(105, "&SingleChoice Dialog", "Shows a SingleChoice Dialog")
menu.Append(106, "&TextEntry Dialog", "Shows a TextEntry Dialog")
13
menuBar.Append(menu, "&Dialogs")
self.SetMenuBar(menuBar)
14
def opendir(self, event):
dlg = wx.DirDialog(self, "Choose a directory:", style=wx.DD_DEFAULT_STYLE
| wx.DD_NEW_DIR_BUTTON)
if dlg.ShowModal() == wx.ID_OK:
self.SetStatusText('You selected: %s\n' % dlg.GetPath())
dlg.Destroy()
class MyApp(wx.App):
def OnInit(self):
myframe = MyFrame(None, -1, "Ferestre de dialog standard")
myframe.CenterOnScreen()
myframe.Show(True)
return True
app = MyApp(0)
app.MainLoop()
import wx
import random
APP_SIZE_X = 300
APP_SIZE_Y = 200
class MyButtons(wx.Dialog):
def __init__(self, parent, id, title):
wx.Dialog.__init__(self, parent, id, title, size=(APP_SIZE_X,
APP_SIZE_Y))
15
self.Centre()
self.ShowModal()
self.Destroy()
app = wx.App(0)
MyButtons(None, -1, Butoane')
app.MainLoop()
6.2 wx.ToggleButton
Butoanele de tip ToggleButton sunt butoane care au două stări: activat sau neactivat.
Un exemplu este prezentat în scriptul de mai jos:
#ex14.py
import wx
class ToggleButtons(wx.Dialog):
def __init__(self, parent, id, title):
wx.Dialog.__init__(self, parent, id, title, size=(300, 200))
self.culoare = wx.Colour(0, 0, 0)
self.Centre()
self.ShowModal()
self.Destroy()
16
self.culoare.Set(culoareRosie, 0, culoareAlbastra)
else:
self.culoare.Set(culoareRosie, 255, culoareAlbastra)
self.panel.SetBackgroundColour(self.culoare)
self.panel.Refresh()
app = wx.App(0)
ToggleButtons(None, -1, 'Combinatii intre culori')
app.MainLoop()
6.3 wx.StaticBox
wx.StaticBox este un control pentru decorarea frame-urilor, dar este folosit şi pentru a grupa
diferite controale. El trebuie creat înainte de a crea obiectele pe care le conţine. Controalele grupate
într-un StaticBox nu trebuie să fie controale de tip child.
#ex15.py
import wx
class MyDialog(wx.Dialog):
def __init__(self, parent, id, title):
wx.Dialog.__init__(self, parent, id, title, size=(270, 270))
self.Centre()
self.ShowModal()
self.Destroy()
app = wx.App(0)
MyDialog(None, -1, 'StaticBox')
app.MainLoop()
6.4 wx.ComboBox
Controlul wx.ComboBox reprezintă o combinaţie între un buton, un câmp de tip text şi un
listbox. Utilizatorii pot selecta o singură opţiune dintr-o listă de tip string.
Constructorul clasei wx.ComboBox este:
17
wx.ComboBox(int id, string value='', wx.Point pos=wx.DefaultPosition, wx.Size
size=wx.DefaultSize, wx.List choices=wx.EmptyList, int style=0, wx.Validator
validator=wx.DefaultValidator, string name=wx.ComboBoxNameStr)
#ex16.py
import wx
class MyDialog(wx.Dialog):
def __init__(self, parent, id, title):
wx.Dialog.__init__(self, parent, id, title, size=(250, 250))
self.Centre()
class MyApp(wx.App):
def OnInit(self):
dlg = MyDialog(None, -1, 'Lunile anului')
dlg.ShowModal()
dlg.Destroy()
return True
app = MyApp(0)
app.MainLoop()
6.5 wx.CheckBox
Controlul wx.CheckBox poate avea două stări: On şi Off.
#ex17.py
import wx
class MyCheckBox(wx.Frame):
def __init__(self, parent, id, title):
wx.Frame.__init__(self, parent, id, title, size=(300, 170))
18
self.cb.SetValue(True)
self.Show()
self.Centre()
app = wx.App(0)
MyCheckBox(None, -1, 'Acesta este titlul ferestrei')
app.MainLoop()
6.6 wx.RadioButton
Controlul wx.RadioButton permite ca utilizatorul să aleagă o singură opţiune dintr-un grup
de opţiuni. Un grup de buoane radio este definit prin aplicarea stilului wx.RB_GROUP primului
buton radio din cadrul grupului. Toate celelalte botoane radio din cadrul grupului se definesc după
acesta. Prin declararea unui nou buton cu stilul wx.RB_GROUP se va crea un nou grup de butoane
radio.
#ex18.py
import wx
class MyFrame(wx.Frame):
def __init__(self, parent, id, title):
wx.Frame.__init__(self, parent, id, title, wx.DefaultPosition,
wx.Size(200, 150))
panel = wx.Panel(self, -1)
self.rb1 = wx.RadioButton(panel, -1, 'Valoare A', (10, 10),
style=wx.RB_GROUP)
self.rb2 = wx.RadioButton(panel, -1, 'Valoare B', (10, 30))
self.rb3 = wx.RadioButton(panel, -1, 'Valoare C', (10, 50))
self.Bind(wx.EVT_RADIOBUTTON, self.SetVal, id=self.rb1.GetId())
self.Bind(wx.EVT_RADIOBUTTON, self.SetVal, id=self.rb2.GetId())
self.Bind(wx.EVT_RADIOBUTTON, self.SetVal, id=self.rb3.GetId())
self.statusbar = self.CreateStatusBar(3)
self.SetVal(True)
class MyApp(wx.App):
def OnInit(self):
frame = MyFrame(None, -1, 'Butoane Radio')
frame.Show(True)
frame.Center()
return True
app = MyApp(0)
app.MainLoop()
19
6.7 wx.ListBox
Controlul wx.Listbox poate fi creat în două moduri: cu o singură selecţie sau cu selecţie
multiplă.
#ex18.py
import wx
class MyFrame(wx.Frame):
def __init__(self, parent, id, title):
wx.Frame.__init__(self, parent, id, title, wx.DefaultPosition, (550,
350))
vbox = wx.BoxSizer(wx.VERTICAL)
hbox1 = wx.BoxSizer(wx.HORIZONTAL)
hbox2 = wx.BoxSizer(wx.HORIZONTAL)
hbox3 = wx.BoxSizer(wx.HORIZONTAL)
self.timer = wx.Timer(self, 1)
self.diff = 0
panel = wx.Panel(self, -1)
self.time_zones = wx.ListBox(panel, 26, wx.DefaultPosition, (170, 130),
zone_list, wx.LB_SINGLE)
self.time_zones.SetSelection(0)
self.text = wx.TextCtrl(panel, -1, 'Europa centrala', size=(200, 130),
style=wx.TE_MULTILINE)
self.time = wx.StaticText(panel, -1, '')
btn = wx.Button(panel, wx.ID_CLOSE, 'Inchide')
hbox1.Add(self.time_zones, 0, wx.TOP, 40)
hbox1.Add(self.text, 1, wx.LEFT | wx.TOP, 40)
hbox2.Add(self.time, 1, wx.ALIGN_CENTRE)
hbox3.Add(btn, 0, wx.ALIGN_CENTRE)
vbox.Add(hbox1, 0, wx.ALIGN_CENTRE)
vbox.Add(hbox2, 1, wx.ALIGN_CENTRE)
vbox.Add(hbox3, 1, wx.ALIGN_CENTRE)
panel.SetSizer(vbox)
self.timer.Start(100)
20
def OnClose(self, event):
self.Close()
class MyApp(wx.App):
def OnInit(self):
frame = MyFrame(None, -1, 'Ora exacta pe diverse meridiane')
frame.Centre()
frame.Show(True)
return True
app = MyApp(0)
app.MainLoop()
6.8 wx.ListCtrl
wx.ListCtrl se foloseşte pentru crearea listelor în următoarele formate:
• report view
• list view
• icon view
#ex19.py
import wx
class MyDialog(wx.Dialog):
def __init__(self, parent, id, title):
wx.Dialog.__init__(self, parent, id, title, size=(600,500),
style=wx.DEFAULT_DIALOG_STYLE)
hbox = wx.BoxSizer(wx.HORIZONTAL)
vbox1 = wx.BoxSizer(wx.VERTICAL)
vbox2 = wx.BoxSizer(wx.VERTICAL)
vbox3 = wx.GridSizer(2,2,0,0)
vbox4 = wx.BoxSizer(wx.VERTICAL)
pnl1 = wx.Panel(self, -1, style=wx.SIMPLE_BORDER)
pnl2 = wx.Panel(self, -1, style=wx.SIMPLE_BORDER)
self.lc = wx.ListCtrl(self, -1, style=wx.LC_REPORT)
self.lc.InsertColumn(0, 'Nume si prenume')
self.lc.InsertColumn(1, 'Telefon')
self.lc.SetColumnWidth(0, 140)
self.lc.SetColumnWidth(1, 153)
vbox1.Add(pnl1, 1, wx.EXPAND | wx.ALL, 3)
vbox1.Add(pnl2, 1, wx.EXPAND | wx.ALL, 3)
vbox2.Add(self.lc, 1, wx.EXPAND | wx.ALL, 3)
self.tc1 = wx.TextCtrl(pnl1, -1)
self.tc2 = wx.TextCtrl(pnl1, -1)
vbox3.AddMany([ (wx.StaticText(pnl1, -1, 'Nume si prenume'),0,
wx.ALIGN_CENTER),
(self.tc1, 0, wx.ALIGN_LEFT|wx.ALIGN_CENTER_VERTICAL),
(wx.StaticText(pnl1, -1, 'Telefon'),0,
wx.ALIGN_CENTER_HORIZONTAL),
21
(self.tc2,0)])
pnl1.SetSizer(vbox3)
vbox4.Add(wx.Button(pnl2, 10, 'Adauga'), 0, wx.ALIGN_CENTER| wx.TOP,
45)
vbox4.Add(wx.Button(pnl2, 11, 'Sterge'), 0, wx.ALIGN_CENTER|wx.TOP, 15)
vbox4.Add(wx.Button(pnl2, 12, 'Goleste lista'), 0, wx.ALIGN_CENTER|
wx.TOP, 15)
vbox4.Add(wx.Button(pnl2, 13, 'Iesire'), 0, wx.ALIGN_CENTER| wx.TOP, 15)
pnl2.SetSizer(vbox4)
self.Bind (wx.EVT_BUTTON, self.OnAdd, id=10)
self.Bind (wx.EVT_BUTTON, self.OnRemove, id=11)
self.Bind (wx.EVT_BUTTON, self.OnClear, id=12)
self.Bind (wx.EVT_BUTTON, self.OnClose, id=13)
hbox.Add(vbox1, 1, wx.EXPAND)
hbox.Add(vbox2, 1, wx.EXPAND)
self.SetSizer(hbox)
class MyApp(wx.App):
def OnInit(self):
dia = MyDialog(None, -1, 'Lista persoane')
dia.ShowModal()
dia.Destroy()
return True
app = MyApp(0)
app.MainLoop()
22