Per il lavoro GUI in generale:
Less is more
lavoro GUI (anche in contesti produttivi) è quanto di più divertente e produttivo come dipingere la Torre Eiffel con uno spazzolino da denti. Scegli un design minimale.
Evitare Stato Like The Plague
si fa a mettere nel vostro stato di GUI, o nel modello? Se lo metti nella GUI, ti confonderai con percorsi di codice ridondanti e inconsistenti. Se lo si inserisce nel modello, si rischia un sistema troppo complesso che non viene sincronizzato quando la GUI non riesce ad aggiornarsi dal modello. Entrambi fanno schifo.
wxPython
Se volete imparare wxPython, qui ci sono alcune trappole che ho notato:
Il tutorial
Utilizzare questo tutorial - http://wiki.wxpython.org/AnotherTutorial
E ' il migliore che ho trovato
Ma ricordarsi di alternare i numeri di riga, per incollare facilmente.
Eventi
Gli eventi sono un po 'come eccezioni, e sono utilizzati per rendere le cose interattivo.
In un programma di vaniglia pitone, si scrive qualcosa di simile:
def doit(i):
print 'Doing i = ',i
for i in range(10):
doit()
print 'Results = ',result
In una GUI, si fa qualcosa di simile:
def doit(event):
print 'An event',event,'just happened!'
event.Skip()
import wx
app = wx.App()
frame = wx.Frame(None, -1, 'The title goes here')
frame.Bind(wx.EVT_KEY_DOWN, doit)
frame.Show()
app.MainLoop()
Ogni volta che l'utente preme un tasto verso il basso, un evento sarà essere sollevato Poiché frame
è legato alla manifestazione (frame.Bind(wx.EVT_KEY_DOWN, doit)
), la funzione doit
verrà chiamata con l'evento come parametro.
Stampa su stderr non è troppo caldo in una GUI, ma doit potrebbe anche richiamare una finestra di dialogo, o fare qualsiasi cosa che si desidera.
Inoltre, è possibile generare i propri eventi utilizzando i timer.
applicazioni, telai, finestre, pannelli, e Sizers
Tutto ha un genitore. Se viene generato un evento e il bambino non lo salta (usando event.Skip()
), anche il genitore dovrà gestire l'evento. Questo è analogo alle eccezioni che portano a funzioni di livello superiore.
Un wx.App
è come la funzione principale.
wx.Window
non è usata. La roba ne eredita e ha tutti i metodi per ridimensionare e impaginare, ma non è necessario saperlo.
wx.Frame
è un frame mobile, come la finestra principale di Firefox. Avrai il frame principale in un'applicazione di base. Se vuoi modificare più file, potresti averne di più. Un wx.Frame di solito non ha genitori.
wx.Panel
fa parte di una finestra padre. Puoi avere diversi pannelli all'interno di una cornice. Un pannello può avere un wx.Frame
come genitore o potrebbe essere figlio di un altro pannello.
wx.Sizers
sono utilizzati per automaticamente pannelli di layout all'interno di frame (o altri pannelli).
Codice:
def doit1(event):
print 'event 1 happened'
def doit2(event):
print 'event 2 happened'
import wx
app = wx.App()
frame = wx.Frame(None, -1, 'The title goes here')
panel_1 = wx.Panel(frame,-1,style=wx.SIMPLE_BORDER)
panel_2 = wx.Panel(frame,-1,style=wx.SIMPLE_BORDER)
panel_1.Bind(wx.EVT_KEY_DOWN, doit1)
panel_2.Bind(wx.EVT_KEY_DOWN, doit2)
panel_1.SetBackgroundColour(wx.BLACK)
panel_2.SetBackgroundColour(wx.RED)
box = wx.BoxSizer(wx.HORIZONTAL)
box.Add(panel_1,1,wx.EXPAND)
box.Add(panel_2,1,wx.EXPAND)
frame.SetSizer(box)
frame.Show()
app.MainLoop()
sono stato davvero male, e non usato pratiche OOP. Ricorda che anche se odi OO nella maggior parte dei contesti, la programmazione GUI è il luogo in cui OOP brilla davvero.
La MCV
non ottengo MCV. Non credo che tu abbia bisogno di un MCV. Penso che un framework MW (model-widget) stia bene.
Per esempio - 2 fotogrammi che modificare lo stesso pezzo di testo:
class Model(object):
def __init__(self):
self.value = 'Enter a value'
self.listeners = []
def Add_listener(self,listener):
self.listeners.append(listener)
def Set(self,new_value):
self.value = new_value
for listener in self.listeners:
listener.Update(self.value)
import wx
app = wx.App()
class CVFrame(wx.Frame):
def __init__(self, parent, id, title, model):
wx.Frame.__init__(self, parent, id, title, size = (100,100))
self.button = wx.Button(self, -1, 'Set model value')
self.textctrl = wx.TextCtrl(self, -1,model.value)
self.button.Bind(wx.EVT_BUTTON,self.OnSet)
self.model = model
model.Add_listener(self)
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add(self.button,0,wx.EXPAND)
sizer.Add(self.textctrl,1,wx.EXPAND)
self.SetSize((300,100))
self.SetSizer(sizer)
self.Center()
self.Show()
def OnSet(self,event):
self.model.Set(self.textctrl.GetValue())
def Update(self,value):
self.textctrl.SetValue(value)
model = Model()
frame1 = CVFrame(None, -1, 'Frame 1',model)
frame2 = CVFrame(None, -1, 'Frame 2',model)
app.MainLoop()
wxPython dispone di un quadro ascoltatore-abbonato, che è una versione migliore del modello ho appena abbozzato (usa arbitri deboli, gli ascoltatori così cancellati non vanno in giro, e così via), ma questo dovrebbe aiutarti a ottenere l'idea.
programmazione grafica in Python? Sul serio? –
@David Lively - Cosa c'è che non va cominciando da lì? Ovviamente è un principiante della grafica e sembra avere solo una conoscenza di base della programmazione (scusate se sbaglio). – gahooa
Con la programmazione grafica, ti riferisci alla programmazione dell'interfaccia utente grafica? O intendi la computer grafica, come nei videogiochi e nei film d'animazione? –