wxPython - Guida rapida

wxPython è un wrapper Python per wxWidgets(che è scritto in C ++), un popolare toolkit GUI multipiattaforma. Sviluppato da Robin Dunn insieme a Harri Pasanen, wxPython è implementato come un modulo di estensione Python.

Proprio come wxWidgets, anche wxPython è un software gratuito. Può essere scaricato dal sito ufficialehttp://wxpython.org. I binari e il codice sorgente per molte piattaforme di sistemi operativi sono disponibili per il download su questo sito.

I moduli principali nell'API wxPython includono un modulo principale. Consiste inwxObjectclass, che è la base per tutte le classi nell'API. Il modulo di controllo contiene tutti i widget utilizzati nello sviluppo di applicazioni GUI. Ad esempio, wx.Button, wx.StaticText (analogo a un'etichetta), wx.TextCtrl (controllo del testo modificabile), ecc.

L'API wxPython ha il modulo GDI (Graphics Device Interface). È un insieme di classi utilizzate per disegnare sui widget. Classi come font, color, brush, ecc. Ne fanno parte. Tutte le classi della finestra del contenitore sono definite nel modulo Windows.

Il sito web ufficiale di wxPython ospita anche Project Phoenix, una nuova implementazione di wxPython per Python 3. *. Si concentra sul miglioramento della velocità, della manutenibilità e dell'estensibilità. Il progetto è iniziato nel 2012 ed è ancora in fase beta.

finestre

I binari predefiniti per il sistema operativo Windows (sia a 32 bit che a 64 bit) sono disponibili su http://www.wxpython.org/download.phppagina. Le ultime versioni dei programmi di installazione disponibili sono: wxPython3.0-win32-3.0.2.0-py27.exe per Python 2.7 a 32 bit wxPython3.0-win64-3.0.2.0-py27.exe per Python 2.7 a 64 bit

La demo di wxPython, gli esempi e la documentazione di wxWidgets sono anche disponibili per il download sulla stessa pagina.

wxPython3.0-win32-docs-demos.exe

Linux

I binari di wxPython per molte distribuzioni Linux possono essere trovati nei rispettivi repository. Per il download e l'installazione dovranno essere utilizzati i gestori di pacchetti corrispondenti. Ad esempio su Debian Linux, il seguente comando dovrebbe essere in grado di installare wxPython.

sudo apt-get install python-wxgtk3.0

Mac OS

I binari predefiniti per MacOS sotto forma di immagini del disco sono disponibili nella pagina di download del sito Web ufficiale.

Una semplice applicazione GUI che mostra il messaggio Hello World viene creata utilizzando i seguenti passaggi:

  • Importa modulo wx.

  • Definisci un oggetto della classe Application.

  • Crea una finestra di primo livello come oggetto della classe wx.Frame. I parametri di didascalia e dimensione sono forniti nel costruttore.

  • Sebbene altri controlli possano essere aggiunti nell'oggetto Frame, il loro layout non può essere gestito. Quindi, metti un oggetto Panel nel Frame.

  • Aggiungi un oggetto StaticText per visualizzare "Hello World" nella posizione desiderata all'interno della finestra.

  • Attiva la finestra frame con il metodo show ().

  • Immettere il ciclo di eventi principale dell'oggetto Application.

import wx 
 
app = wx.App() 
window = wx.Frame(None, title = "wxPython Frame", size = (300,200)) 
panel = wx.Panel(window) 
label = wx.StaticText(panel, label = "Hello World", pos = (100,50)) 
window.Show(True) 
app.MainLoop()

Il codice precedente produce il seguente output:

wxFrame objectè la finestra di primo livello più comunemente utilizzata. È derivato dawxWindow class. Una cornice è una finestra le cui dimensioni e posizione possono essere modificate dall'utente. Ha una barra del titolo e pulsanti di controllo. Se necessario, è possibile abilitare altri componenti come la barra dei menu, la barra degli strumenti e la barra di stato. Una finestra wxFrame può contenere qualsiasi frame che non sia una finestra di dialogo o un altro frame.

La creazione di una buona GUI mediante la codifica manuale può essere noiosa. Uno strumento di progettazione grafica GUI visiva è sempre utile. Sono disponibili molti IDE di sviluppo GUI mirati a wxPython. Di seguito sono riportati alcuni di loro:

  • wxFormBuilder
  • wxDesigner
  • wxGlade
  • BoaConstructor
  • gui2py

wxFormBuilderè un generatore di GUI WYSIWYG multipiattaforma open source in grado di tradurre il design della GUI wxWidget in formato C ++, Python, PHP o XML. Di seguito viene fornita una breve introduzione all'uso di wxFormBuilder.

Prima di tutto è necessario scaricare e installare l'ultima versione di wxFormBuilder da http://sourceforge.net/projects/wxformbuilder/. All'apertura dell'applicazione, viene visualizzato un nuovo progetto con un'area grigia vuota al centro.

Assegna un nome appropriato al progetto e scegli Python come linguaggio di generazione del codice. Questo viene fatto nella finestra Proprietà oggetto come mostrato nell'immagine seguente:

Quindi dalla scheda "Moduli" della tavolozza dei componenti, scegli Cornice.

Aggiungi un wxBoxSizer verticale dalla scheda "Layout".

Aggiungi i controlli necessari nella casella con didascalie adeguate. Qui vengono aggiunti uno StaticText (etichetta), due oggetti TextCtrl (caselle di testo) e un oggetto wxButton. La cornice assomiglia alla seguente immagine:

Abilita Espandi e Allunga su questi tre controlli. Nelle proprietà dell'oggetto per l'oggetto wxButton, assegnare una funzione findquare () all'evento OnButtonClick.

Salvare il progetto e premere F8 per generare il codice Python per la GUI sviluppata. Lascia che il file generato sia denominato Demo.py

Nello script Python eseguibile, importa demo.py e definisci la funzione FindSquare (). Dichiarare l'oggetto Application e avviare un ciclo di eventi principale. Di seguito è riportato il codice eseguibile -

import wx 
  
#import the newly created GUI file 
import demo  
class CalcFrame(demo.MyFrame1): 
   def __init__(self,parent): 
      demo.MyFrame1.__init__(self,parent)  
		
   def FindSquare(self,event): 
      num = int(self.m_textCtrl1.GetValue()) 
      self.m_textCtrl2.SetValue (str(num*num)) 
        
app = wx.App(False) 
frame = CalcFrame(None) 
frame.Show(True) 
#start the applications 
app.MainLoop()

Il codice precedente produce il seguente output:

L'originale wxWidgets (scritto in C ++) è un'enorme libreria di classi. Le classi GUI di questa libreria vengono portate su Python con il modulo wxPython, che cerca di rispecchiare la libreria wxWidgets originale il più vicino possibile. Quindi, la classe wx.Frame in wxPython si comporta in modo molto simile alla classe wxFrame nella sua versione C ++.

wxObject è la base per la maggior parte delle classi. Un oggetto di wxApp (wx.App in wxPython) rappresenta l'applicazione stessa. Dopo aver generato la GUI, l'applicazione entra in un ciclo di eventi con il metodo MainLoop (). I seguenti diagrammi illustrano la gerarchia delle classi delle classi GUI più comunemente usate incluse in wxPython.

SN Classi e descrizione
1 wx.Frame

wx.Frame La classe ha un costruttore predefinito senza argomenti.

2 wx.Panel

La classe wx.Panel viene solitamente inserita in un oggetto wxFrame. Questa classe è anche ereditata dalla classe wxWindow.

3 wx.StaticText

L'oggetto classe wx.StaticText presenta un controllo che contiene tale testo di sola lettura. Può essere definito un controllo passivo poiché non produce alcun evento.

4 TextCtrl

In wxPython, un oggetto della classe wx.TextCtrl serve a questo scopo. È un controllo in cui il testo può essere visualizzato e modificato.

5 RadioButton e RadioBox

Ogni pulsante, un oggetto della classe wx.RadioButton, porta un'etichetta di testo accanto a un pulsante rotondo. L'API wxPython consiste anche nella classe wx.RadioBox. Il suo oggetto offre un bordo e un'etichetta al gruppo.

6 wx.CheckBox

Una casella di controllo mostra una piccola casella rettangolare etichettata. Quando si fa clic, all'interno del rettangolo viene visualizzato un segno di spunta per indicare che è stata effettuata una scelta.

7 ComboBox e classe di scelta

Un oggetto wx.ComboBox presenta un elenco di elementi tra cui selezionare. Può essere configurato per essere un elenco a discesa o con visualizzazione permanente. L'API wxPython contiene una classe wx.Choice, il cui oggetto è anche un elenco a discesa, che è permanentemente di sola lettura.

8 Wx.Gauge

L'oggetto della classe Wx.Gauge mostra una barra verticale o orizzontale, che mostra graficamente la quantità crescente.

9 wx. slider

L'API wxPython contiene la classe wx.Slider. Offre le stesse funzionalità di quella di Scrollbar. Slider offre un modo conveniente per gestire il trascinamento della maniglia tramite il raccoglitore di eventi wx.EVT_SLIDER specifico dello slider.

10 wx.MenuBar

Una barra orizzontale appena sotto la barra del titolo di una finestra di primo livello è riservata alla visualizzazione di una serie di menu. È un oggetto della classe wx.MenuBar nell'API wxPython.

11 wx.Toolbar

Se il parametro di stile dell'oggetto wx.Toolbar è impostato su wx.TB_DOCKABLE, diventa ancorabile. Una barra degli strumenti mobile può anche essere costruita utilizzando la classe AUIToolBar di wxPython.

12 Wx.Dialog

Sebbene un oggetto della classe Dialog appaia come un Frame, viene normalmente utilizzato come una finestra a comparsa sopra un frame principale. L'obiettivo di una finestra di dialogo è raccogliere alcuni dati dall'utente e inviarli al frame principale.

13 wx.Notebook

Il widget wx.Notebook presenta un controllo a schede. Un oggetto Notebook in una cornice ha una o più schede (chiamate Pagine), ciascuna con un pannello che mostra il layout dei controlli.

14 wx.SplitterWindow

L'oggetto di questa classe è un layout manager, che contiene due sottofinestre la cui dimensione può essere modificata dinamicamente trascinando i confini tra di loro. Il controllo Splitter fornisce una maniglia che può essere trascinata per ridimensionare i controlli.

15 HTMLWindow

La libreria wxHTML contiene classi per l'analisi e la visualizzazione del contenuto HTML. Sebbene questo non sia inteso come un browser completo, l'oggetto wx.HtmlWindow è un visualizzatore HTML generico.

16 ListBox e ListCtrl

Un widget wx.ListBox presenta un elenco di stringhe scorrevole verticalmente. Per impostazione predefinita, è selezionabile un singolo elemento nell'elenco. Il widget ListCtrl è uno strumento di visualizzazione e selezione di elenchi altamente migliorato. È possibile visualizzare un elenco di più colonne nella visualizzazione Report, nella visualizzazione Elenco o nella visualizzazione Icone.

A differenza di un'applicazione in modalità console, che viene eseguita in modo sequenziale, un'applicazione basata su GUI è guidata dagli eventi. Le funzioni oi metodi vengono eseguiti in risposta alle azioni dell'utente come fare clic su un pulsante, selezionare un elemento dalla raccolta o fare clic del mouse, ecc., Chiamati eventi.

I dati relativi a un evento che si verifica durante il runtime dell'applicazione vengono memorizzati come oggetto di una sottoclasse derivata da wx.Event. Un controllo di visualizzazione (come Button) è l'origine dell'evento di un tipo particolare e produce un oggetto della classe Event ad esso associato. Ad esempio, il clic di un pulsante emette un wx.CommandEvent. Questi dati dell'evento vengono inviati al metodo del gestore eventi nel programma. wxPython ha molti raccoglitori di eventi predefiniti. UnEvent binder incapsula la relazione tra un widget specifico (controllo), il tipo di evento associato e il metodo del gestore di eventi.

Ad esempio, per chiamare OnClick() method del programma sull'evento clic di un pulsante, è richiesta la seguente dichiarazione:

self.b1.Bind(EVT_BUTTON, OnClick)

Bind() methodviene ereditato da tutti gli oggetti di visualizzazione dalla classe wx.EvtHandler. EVT_.BUTTON qui è il raccoglitore, che associa l'evento clic del pulsante al metodo OnClick ().

Esempio

Nell'esempio seguente, il MoveEvent, causato dal trascinamento della finestra di primo livello, in questo caso un oggetto wx.Frame, è connesso a OnMove() methodutilizzando il raccoglitore wx.EVT_MOVE. Il codice visualizza una finestra. Se viene spostato con il mouse, le sue coordinate istantanee vengono visualizzate sulla console.

import wx
  
class Example(wx.Frame): 
            
   def __init__(self, *args, **kw): 
      super(Example, self).__init__(*args, **kw)  
      self.InitUI() 
           
   def InitUI(self): 
      self.Bind(wx.EVT_MOVE, self.OnMove) 
      self.SetSize((250, 180)) 
      self.SetTitle('Move event') 
      self.Centre() 
      self.Show(True)
		   
   def OnMove(self, e): 
      x, y = e.GetPosition() 
      print "current window position x = ",x," y= ",y 
         
ex = wx.App() 
Example(None) 
ex.MainLoop()

Il codice precedente produce il seguente output:

posizione corrente della finestra x = 562 y = 309

posizione corrente della finestra x = 562 y = 309

posizione corrente della finestra x = 326 y = 304

posizione corrente della finestra x = 384 y = 240

posizione corrente della finestra x = 173 y = 408

posizione corrente della finestra x = 226 y = 30

posizione corrente della finestra x = 481 y = 80

Alcune delle sottoclassi ereditate da wx.Event sono elencate nella tabella seguente:

SN Eventi e descrizione
1

wxKeyEvent

Si verifica quando un tasto viene premuto o rilasciato

2

wxPaintEvent

Viene generato ogni volta che il contenuto della finestra deve essere ridisegnato

3

wxMouseEvent

Contiene dati su qualsiasi evento dovuto all'attività del mouse come il pulsante del mouse premuto o trascinato

4

wxScrollEvent

Associato a controlli scorrevoli come wxScrollbar e wxSlider

5

wxCommandEvent

Contiene i dati degli eventi provenienti da molti widget come pulsanti, finestre di dialogo, appunti, ecc.

6

wxMenuEvent

Diversi eventi relativi al menu escluso il clic del pulsante di comando del menu

7

wxColourPickerEvent

wxColourPickerCtrl ha generato eventi

8

wxDirFilePickerEvent

Eventi generati da FileDialog e DirDialog

Gli eventi in wxPython sono di due tipi. Eventi di base ed eventi di comando. Un evento di base rimane locale rispetto alla finestra in cui ha origine. La maggior parte dei wxWidgets genera eventi di comando. UNcommand event può essere propagato alla finestra o alle finestre, che si trovano sopra la finestra di origine nella gerarchia di classi.

Esempio

Di seguito è riportato un semplice esempio di propagazione degli eventi. Il codice completo è:

import wx
  
class MyPanel(wx.Panel): 
     
   def __init__(self, parent): 
      super(MyPanel, self).__init__(parent)
		
      b = wx.Button(self, label = 'Btn', pos = (100,100)) 
      b.Bind(wx.EVT_BUTTON, self.btnclk) 
      self.Bind(wx.EVT_BUTTON, self.OnButtonClicked) 
		
   def OnButtonClicked(self, e): 
         
      print 'Panel received click event. propagated to Frame class' 
      e.Skip()  
		
   def btnclk(self,e): 
      print "Button received click event. propagated to Panel class" 
      e.Skip()
		
class Example(wx.Frame):

   def __init__(self,parent): 
      super(Example, self).__init__(parent)  
         
      self.InitUI() 

   def InitUI(self):
	
      mpnl = MyPanel(self) 
      self.Bind(wx.EVT_BUTTON, self.OnButtonClicked)
		
      self.SetTitle('Event propagation demo') 
      self.Centre() 
      self.Show(True)
		
   def OnButtonClicked(self, e): 
         
      print 'click event received by frame class' 
      e.Skip()
		
ex = wx.App() 
Example(None) 
ex.MainLoop()

Nel codice sopra, ci sono due classi. MyPanel, una sottoclasse wx.Panel e Example, una sottoclasse wx.Frame che è la finestra di primo livello per il programma. Un pulsante è posizionato nel pannello.

Questo oggetto Button è associato a un gestore di eventi btnclk () che lo propaga alla classe genitore (MyPanel in questo caso). Il clic del pulsante genera un fileCommandEvent che può essere propagato al suo genitore con il metodo Skip ().

L'oggetto classe MyPanel associa anche l'evento ricevuto a un altro gestore OnButtonClicked (). Questa funzione a sua volta trasmette al suo genitore, la classe Example. Il codice precedente produce il seguente output:

Button received click event. Propagated to Panel class. 
Panel received click event. Propagated to Frame class. 
Click event received by frame class.

Un widget GUI può essere posizionato all'interno della finestra del contenitore specificando le sue coordinate assolute misurate in pixel. Le coordinate sono relative alle dimensioni della finestra definite dall'argomento size del suo costruttore. La posizione del widget all'interno della finestra è definita dapos argomento del suo costruttore.

import wx  

app = wx.App() 
window = wx.Frame(None, title = "wxPython Frame", size = (300,200)) 
panel = wx.Panel(window) 
label = wx.StaticText(panel, label = "Hello World", pos = (100,50)) 
window.Show(True) 
app.MainLoop()

Questo Absolute Positioning tuttavia non è adatto per i seguenti motivi:

  • La posizione del widget non cambia anche se la finestra viene ridimensionata.

  • L'aspetto potrebbe non essere uniforme su diversi dispositivi di visualizzazione con risoluzioni diverse.

  • La modifica del layout è difficile in quanto potrebbe essere necessario ridisegnare l'intero modulo.

L'API wxPython fornisce classi Layout per una gestione più elegante del posizionamento dei widget all'interno del contenitore. I vantaggi dei gestori di layout rispetto al posizionamento assoluto sono:

  • I widget all'interno della finestra vengono ridimensionati automaticamente.
  • Assicura un aspetto uniforme su dispositivi di visualizzazione con diverse risoluzioni.
  • È possibile aggiungere o rimuovere widget in modo dinamico senza dover riprogettare.

Il gestore del layout si chiama Sizer in wxPython. Wx.Sizer è la classe base per tutte le sottoclassi sizer. Parliamo di alcuni dei dimensionatori importanti come wx.BoxSizer, wx.StaticBoxSizer, wx.GridSizer, wx.FlexGridSizer e wx.GridBagSizer.

SN Misuratori e descrizione
1 BoxSizer

Questo sizer consente di disporre i controlli in modo riga o colonna. Il layout di BoxSizer è determinato dal suo argomento di orientamento (wxVERTICAL o wxHORIZONTAL).

2 GridSizer

Come suggerisce il nome, un oggetto GridSizer presenta una griglia bidimensionale. I controlli vengono aggiunti nello slot della griglia nell'ordine da sinistra a destra e dall'alto verso il basso.

3 FlexiGridSizer

Questo misuratore ha anche una griglia bidimensionale. Tuttavia, fornisce un po 'più di flessibilità nella disposizione dei controlli nelle celle.

4 GridBagSizer

GridBagSizer è un misuratore versatile. Offre più miglioramenti rispetto a FlexiGridSizer. Il widget figlio può essere aggiunto a una cella specifica all'interno della griglia.

5 StaticBoxSizer

Un StaticBoxSizer inserisce un box sizer in un box statico. Fornisce un bordo attorno alla scatola insieme a un'etichetta nella parte superiore.

Il widget del pulsante è ampiamente utilizzato in qualsiasi interfaccia GUI. Cattura l'evento clic generato dall'utente. Il suo utilizzo più ovvio è attivare una funzione gestore ad essa associata.

La libreria di classi wxPython fornisce diversi tipi di pulsanti. C'è un semplice pulsante tradizionale,wx.Buttonoggetto di classe, che contiene del testo come didascalia. È disponibile anche un pulsante a due stati, denominatowx.ToggleButton. Il suo stato premuto o depresso può essere identificato dalla funzione gestore di eventi.

Un altro tipo di pulsante, wx.BitmapButton mostra una bitmap (immagine) come icona sulla sua faccia.

Il costruttore per la classe wx.Button e la classe wx.ToggleButton accetta i seguenti argomenti:

Wx.Button(parent, id, label, pos, size, style)

Questi sono alcuni metodi importanti della classe wx.Button -

SN Metodi e descrizione
1

SetLabel()

Imposta la didascalia del pulsante a livello di codice

2

GetLabel()

Restituisce la didascalia del pulsante

3

SetDefault()

Il pulsante è impostato sul valore predefinito per la finestra di primo livello. Emula l'evento clic alla pressione del tasto Invio

Due metodi importanti della classe wx.ToggleButton sono:

SN Metodi e descrizione
1

GetValue()

Restituisce lo stato del pulsante di attivazione / disattivazione (on / off)

2

SetValue()

Imposta lo stato del pulsante a livello di codice

Per creare un pulsante bitmap, in primo luogo, un oggetto bitmap deve essere costruito da un file immagine.

La seguente variazione del costruttore di classi wx.Bitmap è più comunemente usata:

Wx.Bitmap(fiiename, wx.BITMAP_TYPE)

Alcune delle costanti di tipo bitmap predefinite sono:

wx.BITMAP_TYPE_BMP
wx.BITMAP_TYPE_ICO
wx.BITMAP_TYPE_CUR
wx.BITMAP_TYPE_TIFF
wx.BITMAP_TYPE_TIF
wx.BITMAP_TYPE_GIF
wx.BITMAP_TYPE_PNG
wx.BITMAP_TYPE_JPEG
wx.BITMAP_TYPE_PCX
wx.BITMAP_TYPE_ICON
wx.BITMAP_TYPE_ANY

Questo oggetto bitmap viene utilizzato come uno dei parametri per il costruttore della classe wx.BitmapButton.

Wx.BitmapButton(parent, id, bitmap, pos, size, style)

Su alcune piattaforme OS, il pulsante bitmap può visualizzare sia bitmap che etichetta. I metodi SetLabel () assegnano la didascalia. Su altre piattaforme, funge da etichetta interna.

Anche il pulsante normale e il pulsante bitmap emettono un wx.CommandEvent. Il binder EVT_BUTTON gli associa una funzione di gestore.

Il pulsante di attivazione / disattivazione d'altra parte utilizza il raccoglitore wx.TOGGLEBUTTON per la gestione degli eventi.

Nell'esempio seguente, i pulsanti di tutti e tre i tipi sono posizionati in un misuratore di riquadro verticale di un pannello.

L'oggetto pulsante semplice viene creato utilizzando l'istruzione -

self.btn = wx.Button(panel, -1, "click Me")

Il pulsante di attivazione / disattivazione è costruito dalla seguente istruzione:

self.tbtn = wx.ToggleButton(panel , -1, "click to on")

Questi pulsanti vengono aggiunti al dimensionamento verticale utilizzando le seguenti istruzioni:

vbox.Add(self.btn,0,wx.ALIGN_CENTER) 
vbox.Add(self.tbtn,0,wx.EXPAND|wx.ALIGN_CENTER)

Note - A causa del flag wx.EXPAND, il pulsante di attivazione / disattivazione occupa l'intera larghezza del frame.

Utilizzando i raccoglitori EVT_BUTTON e EVT_TOGGLEBUTTON vengono associati ai rispettivi gestori.

self.btn.Bind(wx.EVT_BUTTON,self.OnClicked) 
self.tbtn.Bind(wx.EVT_TOGGLEBUTTON,self.OnToggle)

Tre pulsanti bitmap vengono aggiunti in un ridimensionatore di riquadro orizzontale. Questi pulsanti visualizzano un'immagine come icona come didascalia.

bmp = wx.Bitmap("NEW.BMP", wx.BITMAP_TYPE_BMP) 
self.bmpbtn = wx.BitmapButton(panel, id = wx.ID_ANY, bitmap = bmp,
   size = (bmp.GetWidth()+10, bmp.GetHeight()+10))
  
bmp1 = wx.Bitmap("OPEN.BMP", wx.BITMAP_TYPE_BMP) 
self.bmpbtn1 = wx.BitmapButton(panel, id = wx.ID_ANY, bitmap = bmp1,
   size = (bmp.GetWidth()+10, bmp.GetHeight()+10))
  
bmp2 = wx.Bitmap("SAVE.BMP", wx.BITMAP_TYPE_BMP) 
self.bmpbtn2 = wx.BitmapButton(panel, id = wx.ID_ANY, bitmap = bmp2,
   size = (bmp.GetWidth()+10, bmp.GetHeight()+10))

L'evento di clic di questi tre pulsanti è diretto al metodo OnClicked ().

self.bmpbtn.Bind(wx.EVT_BUTTON, self.OnClicked) 
self.bmpbtn1.Bind(wx.EVT_BUTTON, self.OnClicked) 
self.bmpbtn2.Bind(wx.EVT_BUTTON, self.OnClicked)

Le etichette interne di questi pulsanti sono impostate rispettivamente su NEW, OPEN e SAVE.

La funzione del gestore di eventi OnClicked () recupera l'etichetta del pulsante di origine, che ha causato l'evento clic. Quell'etichetta è stampata sulla console.

def OnClicked(self, event): 
   btn = event.GetEventObject().GetLabel() 
   print "Label of pressed button = ",btn

Il gestore di eventi OnToggle () viene attivato quando si fa clic sul pulsante di attivazione / disattivazione. Il suo stato viene letto dal metodo GetValue () e di conseguenza viene impostata la didascalia del pulsante.

def OnToggle(self,event): 
   state = event.GetEventObject().GetValue() 
   if state == True: 
      print "off" 
      event.GetEventObject().SetLabel("click to off") 
   else: 
      print "on" 
      event.GetEventObject().SetLabel("click to on")

L'elenco completo del codice è il seguente:

import wx 
class Mywin(wx.Frame): 
   def __init__(self, parent, title): 
      super(Mywin, self).__init__(parent, title = title,size = (200,150))  
      panel = wx.Panel(self) 
      vbox = wx.BoxSizer(wx.VERTICAL) 
         
      self.btn = wx.Button(panel,-1,"click Me") 
      vbox.Add(self.btn,0,wx.ALIGN_CENTER) 
      self.btn.Bind(wx.EVT_BUTTON,self.OnClicked) 
         
      self.tbtn = wx.ToggleButton(panel , -1, "click to on") 
      vbox.Add(self.tbtn,0,wx.EXPAND|wx.ALIGN_CENTER) 
      self.tbtn.Bind(wx.EVT_TOGGLEBUTTON,self.OnToggle) 
         
      hbox = wx.BoxSizer(wx.HORIZONTAL) 
         
      bmp = wx.Bitmap("NEW.BMP", wx.BITMAP_TYPE_BMP) 
      self.bmpbtn = wx.BitmapButton(panel, id = wx.ID_ANY, bitmap = bmp,
         size = (bmp.GetWidth()+10, bmp.GetHeight()+10)) 
			
      hbox.Add(self.bmpbtn,0,wx.ALIGN_CENTER) 
      self.bmpbtn.Bind(wx.EVT_BUTTON,self.OnClicked) 
      self.bmpbtn.SetLabel("NEW") 
         
      bmp1 = wx.Bitmap("OPEN.BMP", wx.BITMAP_TYPE_BMP) 
      self.bmpbtn1 = wx.BitmapButton(panel, id = wx.ID_ANY, bitmap = bmp1,
         size = (bmp.GetWidth()+10, bmp.GetHeight()+10)) 
			
      hbox.Add(self.bmpbtn1,0,wx.ALIGN_CENTER) 
      self.bmpbtn1.Bind(wx.EVT_BUTTON,self.OnClicked) 
      self.bmpbtn1.SetLabel("OPEN") 
         
      bmp2 = wx.Bitmap("SAVE.BMP", wx.BITMAP_TYPE_BMP) 
      self.bmpbtn2 = wx.BitmapButton(panel, id = wx.ID_ANY, bitmap = bmp2,
         size = (bmp.GetWidth()+10, bmp.GetHeight()+10))
			
      hbox.Add(self.bmpbtn2,0,wx.ALIGN_CENTER) 
      self.bmpbtn2.Bind(wx.EVT_BUTTON,self.OnClicked)
      self.bmpbtn2.SetLabel("SAVE") 
         
      vbox.Add(hbox,1,wx.ALIGN_CENTER) 
      panel.SetSizer(vbox) 
        
      self.Centre() 
      self.Show() 
      self.Fit()  
		
   def OnClicked(self, event): 
      btn = event.GetEventObject().GetLabel() 
      print "Label of pressed button = ",btn 
		
   def OnToggle(self,event): 
      state = event.GetEventObject().GetValue() 
		
      if state == True: 
         print "Toggle button state off" 
         event.GetEventObject().SetLabel("click to off") 
      else: 
         print " Toggle button state on" 
         event.GetEventObject().SetLabel("click to on") 
             
app = wx.App() 
Mywin(None,  'Button demo') 
app.MainLoop()

Il codice precedente produce il seguente output:

Etichetta del pulsante premuto = fare clic su Me

Disattiva lo stato del pulsante

Attiva / disattiva lo stato del pulsante

Etichetta del pulsante premuto = NUOVO

Etichetta del pulsante premuto = APERTO

Etichetta del pulsante premuto = SALVA

wxAuiè una libreria dell'interfaccia utente avanzata incorporata nell'API wxWidgets. Wx.aui.AuiManager la classe centrale nel framework AUI.

AuiManagergestisce i riquadri associati a un particolare frame utilizzando le informazioni di ciascun riquadro nell'oggetto wx.aui.AuiPanelInfo. Impariamo a conoscere le varie proprietà dell'aggancio e del comportamento fluttuante del controllo degli oggetti PanelInfo.

Mettere le finestre agganciabili nel frame di primo livello comporta i seguenti passaggi:

Innanzitutto, crea un oggetto AuiManager.

self.mgr = wx.aui.AuiManager(self)

Quindi, viene progettato un pannello con i controlli richiesti.

pnl = wx.Panel(self) 
pbox = wx.BoxSizer(wx.HORIZONTAL) 
text1 = wx.TextCtrl(pnl, -1, "Dockable", style = wx.NO_BORDER | wx.TE_MULTILINE) 
pbox.Add(text1, 1, flag = wx.EXPAND) 
pnl.SetSizer(pbox)

Vengono impostati i seguenti parametri di AuiPanelInfo.

  • Direction - In alto, in basso, a sinistra, a destra o al centro

  • Position- È possibile posizionare più di un riquadro all'interno di un'area agganciabile. A ciascuno viene assegnato un numero di posizione.

  • Row- Più di un riquadro viene visualizzato in una riga. Proprio come più di una barra degli strumenti che appare nella stessa riga.

  • Layer - I pannelli possono essere posizionati a strati.

Usando questo PanelInfo, il pannello progettato viene aggiunto all'oggetto manager.

info1 = wx.aui.AuiPaneInfo().Bottom() 
self.mgr.AddPane(pnl,info1)

Il resto della finestra di primo livello potrebbe avere altri controlli come al solito.

Il codice completo è il seguente:

import wx 
import wx.aui
  
class Mywin(wx.Frame):
  
   def __init__(self, parent, title): 
      super(Mywin, self).__init__(parent, title = title, size = (300,300)) 
		
      self.mgr = wx.aui.AuiManager(self)
		
      pnl = wx.Panel(self) 
      pbox = wx.BoxSizer(wx.HORIZONTAL)
      text1 = wx.TextCtrl(pnl, -1, "Dockable", style = wx.NO_BORDER | wx.TE_MULTILINE) 
      pbox.Add(text1, 1, flag = wx.EXPAND) 
      pnl.SetSizer(pbox) 
         
      info1 = wx.aui.AuiPaneInfo().Bottom() 
      self.mgr.AddPane(pnl, info1) 
      panel = wx.Panel(self) 
      text2 = wx.TextCtrl(panel, size = (300,200), style =  wx.NO_BORDER | wx.TE_MULTILINE) 
      box = wx.BoxSizer(wx.HORIZONTAL) 
      box.Add(text2, 1, flag = wx.EXPAND) 
         
      panel.SetSizerAndFit(box) 
      self.mgr.Update() 
		
      self.Bind(wx.EVT_CLOSE, self.OnClose) 
      self.Centre() 
      self.Show(True) 
		
   def OnClose(self, event): 
      self.mgr.UnInit() 
      self.Destroy() 
		
app = wx.App()
Mywin(None,"Dock Demo")  
app.MainLoop()

Il codice precedente produce il seguente output:

Una tipica applicazione GUI può avere più finestre. I widget a schede e in pila consentono di attivare una di queste finestre alla volta. Tuttavia, molte volte questo approccio potrebbe non essere utile poiché la visualizzazione di altre finestre è nascosta.

Un modo per visualizzare più finestre contemporaneamente è crearle come finestre indipendenti. Questo è chiamato SDI (Single Document Interface). Ciò richiede più risorse di memoria poiché ogni finestra può avere il proprio sistema di menu, barra degli strumenti, ecc.

Il framework MDI in wxPython fornisce una classe wx.MDIParentFrame. Il suo oggetto funge da contenitore per più finestre figlie, ciascuna delle quali è un oggetto della classe wx.MDIChildFrame.

Le finestre figlio risiedono nell'area MDIClientWindow del frame padre. Non appena viene aggiunto un frame figlio, la barra dei menu del frame padre mostra un menu Finestra contenente pulsanti per disporre i figli in modo a cascata o affiancato.

Esempio

L'esempio seguente illustra gli usi di MDIParentFrame come finestra di primo livello. Un pulsante Menu chiamato NewWindow aggiunge una finestra figlia nell'area client. È possibile aggiungere più finestre e quindi disporre in un ordine a cascata o affiancato.

Il codice completo è il seguente:

import wx 
 
class MDIFrame(wx.MDIParentFrame): 
   def __init__(self): 
      wx.MDIParentFrame.__init__(self, None, -1, "MDI Parent", size = (600,400)) 
      menu = wx.Menu() 
      menu.Append(5000, "&New Window") 
      menu.Append(5001, "&Exit") 
      menubar = wx.MenuBar() 
      menubar.Append(menu, "&File") 
		
      self.SetMenuBar(menubar) 
      self.Bind(wx.EVT_MENU, self.OnNewWindow, id = 5000) 
      self.Bind(wx.EVT_MENU, self.OnExit, id = 5001) 
		
   def OnExit(self, evt): 
      self.Close(True)  
		
   def OnNewWindow(self, evt): 
      win = wx.MDIChildFrame(self, -1, "Child Window")
      win.Show(True) 
		
app = wx.App() 
frame = MDIFrame() 
frame.Show() 
app.MainLoop()

Il codice precedente produce il seguente output:

GDI+ (Interfaccia di disegno grafico), CoreGraphics e Cairo librariesformano il framework dell'API di disegno in wxPython. wx.GraphicsContext è l'oggetto drawable principale, utilizzando il quale vengono creati vari oggetti Device Context.

wx.DC è una classe astratta. Le sue classi derivate vengono utilizzate per eseguire il rendering di grafica e testo su dispositivi diversi. Le classi Device Context sono:

  • wx.ScreenDC - Usa questo per dipingere sullo schermo, al contrario di una singola finestra.

  • wx.ClientDC - Usalo per dipingere nell'area client della finestra (la parte senza bordi e altre decorazioni), ma non usarlo dall'interno di un wxPaintEvent.

  • wx.PaintDC- Usalo per disegnare nell'area client della finestra, ma solo dall'interno di un wxPaintEvent.

  • wx.WindowDC- Usalo per dipingere su tutta l'area della finestra, comprese le decorazioni. Potrebbe non essere disponibile su piattaforme non Windows.

L'API di disegno di wxPython offre diverse funzioni per disegnare forme, testo e immagini. Gli oggetti necessari per il disegno, come Colore, Penna, Pennello e Carattere possono anche essere costruiti utilizzando le classi GDI.

wx.Colour Class

L'oggetto colore rappresenta una combinazione di valori di intensità RGB (ROSSO, verde e blu), ciascuno su una scala da 0 a 255. Ci sono alcuni oggetti di colore predefiniti come:

  • wxBLACK
  • wxBLUE
  • wxCYAN
  • wxGREEN
  • wxYELLOW
  • wxLIGHT_GREY
  • wxRED
  • wxWHITE

Il colore con una combinazione personalizzata di valori RGB è formato come wx.Colour object.

wx.Colour(r,g,b)

wx.Pen Class

L'oggetto penna determina il colore, la larghezza e lo stile della forma della grafica come linea, rettangolo, cerchio, ecc.

Predefined Pen objects sono -

wxBLACK_DASHED_PEN
wxBLACK_PEN
wxBLUE_PEN
wxCYAN_PEN
wxGREEN_PEN
wxYELLOW_PEN
wxGREY_PEN
wxLIGHT_GREY_PEN
wxMEDIUM_GREY_PEN
wxRED_PEN
wxTRANSPARENT_PEN
wxWHITE_PEN

Predefined Pen styles sono -

wx.SOLID
wx.DOT
wx.LONG_DASH
wx.SHORT_DASH
wx.DOT_DASH
wx TRASPARENTE

wx.Brush Class

Il pennello è un altro oggetto grafico elementare necessario per riempire gli sfondi di forme come rettangolo, ellisse, cerchio ecc.

Un oggetto Brush personalizzato richiede i parametri di stile wx.Colour e Brush. Di seguito è riportato un elenco di stili di pennello predefiniti:

wx.SOLID
wx.STIPPLE
wx.BDIAGONAL_HATCH
wx.CROSSDIAG_HATCH
wx.FDIAGONAL_HATCH
wx.CROSS_HATCH
wx.HORIZONTAL_HATCH
wx.VERTICAL_HATCH
wx TRASPARENTE

wxPython ha una serie di funzioni che facilitano il disegno di forme, testo e immagini differenti.

SN Funzioni e descrizione
1

DrawRectangle()

Disegna un rettangolo di dimensioni date

2

DrawCircle()

Disegna un cerchio nel punto dato come centro e raggio

3

DrawEllipse()

Disegna un'ellisse con i raggi xey dati

4

DrawLine()

Disegna una linea tra due oggetti wx.Point

5

DrawBitmap()

Disegna un'immagine nella posizione data

6

DrawText()

Visualizza il testo specificato nella posizione specificata

Esempio

Le funzioni di cui sopra sono implementate nel seguente esempio, facendo uso di oggetti Pen, Brush, Color e Font.

Il codice completo è il seguente:

import wx 
 
class Mywin(wx.Frame): 
            
   def __init__(self, parent, title): 
      super(Mywin, self).__init__(parent, title = title,size = (500,300))  
      self.InitUI() 
         
   def InitUI(self): 
      self.Bind(wx.EVT_PAINT, self.OnPaint) 
      self.Centre() 
      self.Show(True)
		
   def OnPaint(self, e): 
      dc = wx.PaintDC(self) 
      brush = wx.Brush("white")  
      dc.SetBackground(brush)  
      dc.Clear() 
        
      dc.DrawBitmap(wx.Bitmap("python.jpg"),10,10,True) 
      color = wx.Colour(255,0,0)
      b = wx.Brush(color) 
		
      dc.SetBrush(b) 
      dc.DrawCircle(300,125,50) 
      dc.SetBrush(wx.Brush(wx.Colour(255,255,255))) 
      dc.DrawCircle(300,125,30) 
		
      font = wx.Font(18, wx.ROMAN, wx.ITALIC, wx.NORMAL) 
      dc.SetFont(font) 
      dc.DrawText("Hello wxPython",200,10) 
		
      pen = wx.Pen(wx.Colour(0,0,255)) 
      dc.SetPen(pen) 
      dc.DrawLine(200,50,350,50) 
      dc.SetBrush(wx.Brush(wx.Colour(0,255,0), wx.CROSS_HATCH)) 
      dc.DrawRectangle(380, 15, 90, 60) 
		
ex = wx.App() 
Mywin(None,'Drawing demo') 
ex.MainLoop()

Il codice precedente produce il seguente output:

Fornitura di drag and dropè molto intuitivo per l'utente. Si trova in molte applicazioni desktop in cui l'utente può copiare o spostare oggetti da una finestra all'altra semplicemente trascinandoli con il mouse e rilasciandoli su un'altra finestra.

L'operazione di trascinamento della selezione prevede i seguenti passaggi:

  • Dichiara un obiettivo di rilascio
  • Crea oggetto dati
  • Crea wx.DropSource
  • Eseguire l'operazione di trascinamento
  • Annulla o accetta il rilascio

In wxPython, ci sono due destinazioni di rilascio predefinite:

  • wx.TextDropTarget
  • wx.FileDropTarget

Molti widget wxPython supportano l'attività di trascinamento della selezione. Il controllo del codice sorgente deve avere il trascinamento abilitato, mentre il controllo di destinazione deve essere in grado di accettare (o rifiutare) il trascinamento.

I dati di origine che l'utente sta trascinando vengono posizionati sull'oggetto di destinazione. OnDropText () dell'oggetto di destinazione consuma i dati. Se lo si desidera, è possibile eliminare i dati dall'oggetto di origine.

Esempio

Nell'esempio seguente, due oggetti ListCrl vengono posizionati orizzontalmente in un Box Sizer. L'elenco a sinistra è popolato con i dati delle lingue []. È designato come fonte di trascinamento. Quello a destra è il bersaglio.

languages = ['C', 'C++', 'Java', 'Python', 'Perl', 'JavaScript', 'PHP', 'VB.NET','C#'] 
self.lst1 = wx.ListCtrl(panel, -1, style = wx.LC_LIST) 
self.lst2 = wx.ListCtrl(panel, -1, style = wx.LC_LIST) 

   for lang in languages: 
      self.lst1.InsertStringItem(0,lang)

Il secondo controllo elenco è vuoto ed è un argomento per l'oggetto della classe TextDropTarget.

class MyTextDropTarget(wx.TextDropTarget):
   def __init__(self, object): 
      wx.TextDropTarget.__init__(self) 
      self.object = object
		
   def OnDropText(self, x, y, data): 
      self.object.InsertStringItem(0, data)

Il metodo OnDropText () aggiunge i dati di origine nel controllo dell'elenco di destinazione.

L'operazione di trascinamento viene inizializzata dal raccoglitore di eventi.

wx.EVT_LIST_BEGIN_DRAG(self, self.lst1.GetId(), self.OnDragInit)

La funzione OnDragInit () inserisce i dati di trascinamento sulla destinazione ed elimina dall'origine.

def OnDragInit(self, event): 
   text = self.lst1.GetItemText(event.GetIndex()) 
   tobj = wx.PyTextDataObject(text) 
   src = wx.DropSource(self.lst1) 
   src.SetData(tobj) 
   src.DoDragDrop(True) 
   self.lst1.DeleteItem(event.GetIndex())

Il codice completo è il seguente:

import wx
  
class MyTarget(wx.TextDropTarget): 
   def __init__(self, object): 
      wx.TextDropTarget.__init__(self) 
      self.object = object  
		
   def OnDropText(self, x, y, data): 
      self.object.InsertStringItem(0, data)  
		
class Mywin(wx.Frame): 
            
   def __init__(self, parent, title): 
      super(Mywin, self).__init__(parent, title = title,size = (-1,300))   
      panel = wx.Panel(self) 
      box = wx.BoxSizer(wx.HORIZONTAL)  
      languages = ['C', 'C++', 'Java', 'Python', 'Perl', 'JavaScript',
         'PHP', 'VB.NET','C#']
			
      self.lst1 = wx.ListCtrl(panel, -1, style = wx.LC_LIST) 
      self.lst2 = wx.ListCtrl(panel, -1, style = wx.LC_LIST) 
      for lang in languages: 
      self.lst1.InsertStringItem(0,lang) 
             
      dt = MyTarget(self.lst2) 
      self.lst2.SetDropTarget(dt) 
      wx.EVT_LIST_BEGIN_DRAG(self, self.lst1.GetId(), self.OnDragInit)
		
      box.Add(self.lst1,0,wx.EXPAND) 
      box.Add(self.lst2, 1, wx.EXPAND) 
		
      panel.SetSizer(box) 
      panel.Fit() 
      self.Centre() 
      self.Show(True)  
     
   def OnDragInit(self, event): 
      text = self.lst1.GetItemText(event.GetIndex()) 
      tobj = wx.PyTextDataObject(text) 
      src = wx.DropSource(self.lst1) 
      src.SetData(tobj) 
      src.DoDragDrop(True) 
      self.lst1.DeleteItem(event.GetIndex()) 
		
ex = wx.App() 
Mywin(None,'Drag&Drop Demo') 
ex.MainLoop()

Il codice precedente produce il seguente output: