| WxPython |
UserPreferences |
| Wiki Python Fr | FrontPage | RecentChanges | TitleIndex | WordIndex | SiteNavigation | HelpContents | moin.sf.net |
Visualisation d'images
Permet de visualiser les images d'un répertoire, de changer de répertoire, d'effectuer quelques manipulations (effacer, retourner).
wxPython
Wrapper pour la bibliothèque wxWidgets (ex wxWindows), toolkit pour construire des interfaces graphiques portable sur unix et windows
Boa Constructor
Interface graphique pour créer de manière visuelle une interface en WxPython (similaire à VB ou Delphi)
wxMozilla Ce module permet d'integrer Mozilla a vos apllications WxPython
La méthode n'existe pas en natif dans wx (ceci n'engage que moi, je ne connais pas les 450 classes à fond...). Par contre, avec un minimum de calcul, elle est facile à remplacer.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | # -*- coding: iso-8859-1 -*-
import wx
class MyApp(wx.App):
def OnInit(self):
#--création fenêtre avec tout par défaut sauf le titre
frame = wx.Frame(None, -1, "Bonjour!")
#--centrage sur l'écran
frame.CenterOnParent(wx.BOTH)
#--récup zone d'affichage bureau (la hauteur est le 4ème élément)
zAffBur= wx.GetClientDisplayRect()
#--extrapole la ligne d'affichage d'après la hauteur de frame
y= zAffBur[3] - frame.GetSizeTuple()[1]
#--la colonne ne change pas dans cet exemple
x= frame.GetPositionTuple()[0]
#--et voilà !
frame.MoveXY(x,y)
#--
frame.Show(1)
return True
app = MyApp(0)
app.MainLoop() |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | # -*- coding: iso-8859-1 -*-
import wx
#----------------------------------------------------------------------
# nb: le fichier jpeg doit être présent
class mainWindow(wx.Frame):
def __init__(self):
wx.Frame.__init__(self,None,wx.ID_ANY,'Affichage images')
#--le sizer va servir à positionner les images et dimensionner la fenêtre
sizerH= wx.BoxSizer(wx.HORIZONTAL)
#--l'image est d'abord affichée telle que...
img= wx.Image('amélie.jpg',wx.BITMAP_TYPE_JPEG)
bmp= wx.BitmapFromImage(img)
staticBmp= wx.StaticBitmap(self,wx.ID_ANY,bmp)
sizerH.Add(staticBmp)
#--...puis modifiée pour ne conserver que du blanc et du noir
data1= img.GetData()
blanc= chr(255)*3
noir= chr(0)*3
choice= (blanc, noir)
seuil= chr(128) # changer la valeur pour un résultat différent (un seuil élevé pour une image pâle)
data2= ''.join([choice[pix < seuil] for pix in data1[::3]])
img.SetData(data2)
bmp= wx.BitmapFromImage(img)
staticBmp= wx.StaticBitmap(self,wx.ID_ANY,bmp)
sizerH.Add(staticBmp)
#--régler la taille de la fenêtre
self.SetSizer(sizerH)
self.SetAutoLayout(1)
sizerH.Fit(self)
#--
self.Show(True)
#----------------------------------------------------------------------
app = wx.PySimpleApp()
frame=mainWindow()
app.MainLoop()
del app
#---------------------------------------------------------------------- |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 | #D'apres un exemple de Mark Hammond
#publié dans son ouvrage Progammation Win32 chez O'Reilly
#Ce programme est loin d'être terminé, n'hésitez pas à vous l'approprier
#et à le modifier selon votre convenance ;-)
#Auteur : Salvatore
from wxPython.wx import *
import time
import types
donnees = {0 : {"nom" : "Tom","prenom":"Edjjery","email":"tom.edjjery@lands.com"},\
1 : {"nom" : "Annie","prenom":"Balle","email":"annie.balle@karpate.org"},\
2 : {"nom" : "Judas","prenom":"Bricaut","email":"judas.bricaut@orange.net"},\
}
#Constantes menu Fichier
ID_NOUVEAU = wxNewId()
ID_OUVRIR = wxNewId()
ID_SAUVER = wxNewId()
ID_SAUVERSOUS = wxNewId()
ID_QUITTER = wxNewId()
#Constante menu Aide
ID_EDITION = wxNewId()
#Identificateur de l'objet Liste
ID_LIST = wxNewId()
class Fenetre(wxMDIParentFrame):
#Dans une application SDI on peut utiliser la classe de base 'wxFrame'
def __init__(self,parent,ID,titre,taille,position):
wxMDIParentFrame.__init__(self,parent,ID,titre,taille,position,\
style=wxFRAME_NO_WINDOW_MENU|wxDEFAULT_FRAME_STYLE|wxMAXIMIZE)
self.Show(true)
self.Center()
self.CreerMenu()
self.CreerBarreEtat()
def CreerMenu(self):
#Definition de menu fichier
self.menufichier = wxMenu()
self.menufichier.Append(ID_NOUVEAU,"Nouveau","Creer un fichier")
self.menufichier.Append(ID_OUVRIR,"Ouvrir","Ouvrir un fichier existant")
self.menufichier.Append(ID_SAUVER,"Sauver","Enregistrer le fichier")
self.menufichier.Append(ID_SAUVERSOUS,"Sauver sous","Enregistrer sous un autre nom")
self.menufichier.Append(ID_QUITTER,"Quitter","Quitter le programme")
#Definition du menu aide
self.menuedition = wxMenu()
self.menuedition.Append(ID_EDITION,"Liste","Listage des informations")
#Definition des gestionnaires d'evenements lies au menu
EVT_MENU(self,ID_NOUVEAU,self.Creation)
EVT_MENU(self,ID_OUVRIR,self.Ouverture)
EVT_MENU(self,ID_SAUVER,self.Sauvegarde)
EVT_MENU(self,ID_SAUVERSOUS,self.SauvegardeSous)
EVT_MENU(self,ID_QUITTER,self.Termine)
EVT_MENU(self,ID_EDITION,self.Liste)
#Definition de la barre de menu et insertion des menus
self.menubar = wxMenuBar()
self.menubar.Show(true)
self.menubar.Append(self.menufichier,"&Fichier")
self.menubar.Append(self.menuedition,"&Edition")
self.SetMenuBar(self.menubar)
def Creation(self, event):
dlg = wxFileDialog(self,"Nom du fichier","","","*.py;*.pyw",wxOPEN)
retour = dlg.ShowModal()
if retour == wxID_OK :
chemin = dlg.GetPath()
self.SetTitle(chemin)
message = wxMessageDialog(self, "Vous etes en phase de creation","Information",\
style=wxICON_INFORMATION|wxCENTRE,pos=wxDefaultPosition)
message.ShowModal()
#Routine de creation
def Ouverture(self, event):
dlg = wxFileDialog(self,"Nom du fichier","","","*.py;*.pyw",wxOPEN)
retour = dlg.ShowModal()
if retour == wxID_OK :
chemin = dlg.GetPath()
self.SetTitle(chemin)
message = wxMessageDialog(self, "Vous etes en phase de creation","Titre de fenêtre",\
style=wxICON_INFORMATION|wxCENTRE,pos=wxDefaultPosition)
message.ShowModal()
#Routine à l'ouverture d'unfichier existant
def Sauvegarde(self, event):
messa = Message(self,"Attention")
def SauvegardeSous(self, event):
pass
def Termine(self, event):
pass
def Liste(self, event):
self.menuedition.Enable(ID_EDITION,FALSE)
self.liste = Liste(self,-1,"",(0,0))
self.liste.Center()
self.SetStatusText("Listage des donnees",0)
print self.GetClientSize()
def Notify(self):
temps = time.localtime(time.time())
stemps = time.strftime("%d-%b-%Y %I:%M:%S",temps)
self.SetStatusText(stemps,1)
def CreerBarreEtat(self):
self.CreateStatusBar(2)
self.SetStatusWidths([-1,150])
#self.timer = wxPyTimer(self.Notify)
#self.timer.Start(10)
#self.Notify()
class Liste(wxMDIChildFrame):
def __init__(self,parent,ID,title,position=(0,0)):
wxMDIChildFrame.__init__(self,parent,ID,"Liste",(0,0),size=(500,400),\
style = wxDEFAULT_FRAME_STYLE)
#permet de recuperer la fenetre principale
self.fenetre_parente = parent
self.lc = wxListCtrl(self,ID_LIST,style=wxLC_REPORT|wxSUNKEN_BORDER)
self.lc.InsertColumn(0, "Nom")
self.lc.InsertColumn(1, "Prenom")
self.lc.InsertColumn(2, "Email")
self.item_courant = 0
self.lig_donnees = ()
#Fixe la largeur des colonnes 1 et 2 en vue de d'en déduire la largeur de la derniere
self.lc.SetColumnWidth(0,100)
self.lc.SetColumnWidth(1,100)
#On remplit la liste
items = donnees.items()
index = 0
for index in range(len(donnees.items())):
self.lc.InsertStringItem(index,donnees[index]["nom"])
self.lc.SetStringItem(index,1,donnees[index]["prenom"])
self.lc.SetStringItem(index,2,donnees[index]["email"])
EVT_LIST_ITEM_SELECTED(self,ID_LIST,self.OnSelection)
EVT_LEFT_DCLICK(self.lc,self.OnDoubleClick)
EVT_CLOSE(self,self.OnClose)
def OnSelection(self, event):
self.item_courant = event.m_itemIndex
self.lig_donnees = donnees[self.item_courant]['nom'],\
donnees[self.item_courant]['prenom'],\
donnees[self.item_courant]['email']
def OnDoubleClick(self, event):
self.ActiveFiche()
def ActiveFiche(self):
fiche = Fiche(self,"Fiche de dialogue",self.lig_donnees)
def OnClose(self, event):
inf = Info(self.fenetre_parente,titre = "Info sur la liste",message = \
"Voulez-vous fermez cette fenetre ?")
self.fenetre_parente.menuedition.Enable(ID_EDITION,TRUE)
self.Destroy()
class Titre_Champ:
def __init__(self,parent,label,valeur,pos_x=0,pos_y=0,largeur=150):
posx = pos_x
posy = pos_y
larg = largeur
wxStaticText(parent,-1,label,(posx,posy),(50,20),style=wxALIGN_RIGHT )
wxTextCtrl(parent,-1,valeur,(posx+55,posy-2),(largeur,20))
class Fiche(wxDialog):
def __init__(self,parent,titre,donnees):
posx = 30;posy = 40;espacev = 30
wxDialog.__init__(self,parent,-1,titre,pos = wxDefaultPosition,size = (300,200))
tc_nom = Titre_Champ(self,"Nom :",donnees[0],posx,posy)
tc_prenom = Titre_Champ(self,"Prenom :",donnees[1],posx,posy + espacev)
tc_age = Titre_Champ(self,"Email :",donnees[2],posx,posy + 2*espacev)
(sx,sy) = self.GetClientSize()
box = wxStaticBox(self,-1,"",(0,0),(sx,sy))
self.ShowModal()
class Info(wxMessageDialog):
def __init__(self,parent, message = "Message", titre = "Titre"):
wxMessageDialog.__init__(self,parent, message, titre, wxOK | wxCANCEL)
if self.ShowModal() == wxID_OK:
pass
class Application(wxApp):
def OnInit(self):
fenprinc = Fenetre(NULL,-1,"Application wxPython",(300,300),(500,500))
self.SetTopWindow(fenprinc)
return true
def main():
monappli = Application()
monappli.MainLoop()
if __name__ == '__main__':
main() |
Bricolé à partir de gridcusttable.py provenant de la démo pywx. Le programme est autonome et fonctionne avec python 2.4 et wx 2.6 sous Windows XP. Les démos donnent des tas d'exemples pour créer et modifier des Grid, mais pas pour ajouter des lignes. Or dans le cas du Grid basé sur une Grid table, les fonctions Appendrows et Insertrows ne fonctionnent pas. Le principe retenu ici est de simplement ajouter une ligne à la table et de détruire puis recréer le Grid. Comme le Refresh() ne fonctionne pas non plus, on contourne en faisant un Getsize() suivi d'un Setsize(). Si vous avez des questions, rendez-vous dans le news python.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 | #---------------------------------------------------------------------------
from wxPython.wx import *
from wxPython.grid import *
#---------------------------------------------------------------------------
class CustomDataTable(wxPyGridTableBase):
def __init__(self,data):
self.data= data
wxPyGridTableBase.__init__(self)
self.colLabels = ['ID', 'Description', 'Severity', 'Priority', 'Platform',
'Opened?', 'Fixed?', 'Tested?', 'TestFloat']
self.dataTypes = [wxGRID_VALUE_NUMBER,
wxGRID_VALUE_STRING,
wxGRID_VALUE_CHOICE + ':only in a million years!,wish list,minor,normal,major,critical',
wxGRID_VALUE_NUMBER + ':1,5',
wxGRID_VALUE_CHOICE + ':all,MSW,GTK,other',
wxGRID_VALUE_BOOL,
wxGRID_VALUE_BOOL,
wxGRID_VALUE_BOOL,
wxGRID_VALUE_FLOAT + ':6,2',
]
def GetNumberRows(self):
return len(self.data) + 1
def GetNumberCols(self):
return len(self.data[0])
def IsEmptyCell(self, row, col):
try:
return not self.data[row][col]
except IndexError:
return true
def GetValue(self, row, col):
try:
return self.data[row][col]
except IndexError:
return ''
def SetValue(self, row, col, value):
try:
self.data[row][col] = value
except IndexError:
self.data.append([''] * self.GetNumberCols())
self.SetValue(row, col, value)
msg = wxGridTableMessage(self, # The table
wxGRIDTABLE_NOTIFY_ROWS_APPENDED, # what we did to it
1) # how many
self.GetView().ProcessTableMessage(msg)
self.GetView().MoveCursorDown(false)
def GetColLabelValue(self, col):
return self.colLabels[col]
def GetTypeName(self, row, col):
return self.dataTypes[col]
def CanGetValueAs(self, row, col, typeName):
colType = self.dataTypes[col].split(':')[0]
if typeName == colType:
return true
else:
return False
def CanSetValueAs(self, row, col, typeName):
return self.CanGetValueAs(row, col, typeName)
#---------------------------------------------------------------------------
class CustTableGrid(wxGrid):
def __init__(self, parent, data):
wxGrid.__init__(self, parent, -1)
self.table = CustomDataTable(data)
self.SetTable(self.table, true)
self.SetRowLabelSize(0)
self.SetMargins(0,0)
self.AutoSizeColumns(False)
EVT_GRID_CELL_LEFT_DCLICK(self, self.OnLeftDClick)
def OnLeftDClick(self, evt):
if self.CanEnableCellControl():
self.EnableCellEditControl()
#---------------------------------------------------------------------------
class TestFrame(wxFrame):
def __init__(self, parent):
wxFrame.__init__(self, parent, -1, "Custom Table, data driven Grid Demo", size=(640,480))
self.data = [
[1010, "The foo doesn't bar", "major", 1, 'MSW', 1, 1, 1, 1.12],
[1011, "I've got a wicket in my wocket", "wish list", 2, 'other', 0, 0, 0, 1.50],
[1012, "Rectangle() returns a triangle", "critical", 5, 'all', 0, 0, 0, 1.56]
]
self.initwin()
def initwin(self):
self.ref= None
self.p = wxPanel(self, -1, style=0)
b = wxButton(self.p, -1, "Add line...")
b.SetDefault()
EVT_BUTTON(self, b.GetId(), self.OnButton)
self.bs = wxBoxSizer(wxVERTICAL)
self.grid = CustTableGrid(self.p,self.data)
self.bs.Add(self.grid, 1, wxGROW|wxALL, 5)
self.bs.Add(b)
self.p.SetSizer(self.bs)
def OnButton(self, evt):
self.data.append([1010, "Added line", "major", 1, 'MSW', 1, 1, 1, 1.12])
sz= self.p.GetSize()
self.p.Destroy()
self.initwin()
self.p.SetSize(sz)
print "button selected"
#-------------------------------------------------------------------------------
class mApp(wxApp):
def OnInit(self):
frame= TestFrame(None)
frame.Show(true)
return true
#-------------------------------------------------------------------------------
app = mApp(0)
app.MainLoop()
#------------------------------------------------------------------------------- |
La démo donne un exemple de Drag'n'drop, mais qui n'accepte que du texte ou des noms de fichiers, mais pas les deux sur la même fenêtre. L'exemple qui suit accepte à la fois texte et noms de fichiers sur sa fenêtre. Pour tester, lancez le programme et faites glisser des fichiers (depuis l'explorateur) ou des liens (depuis le navigateur) vers la fenêtre du programme. Le résultat s'affiche dans la console. Si vous avez des questions, rendez-vous dans le news python.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | # -*- coding: iso-8859-1 -*-
import wx
import wx.lib.scrolledpanel as scroll
#----------------------------------------------------------------------
class MyTextDropTarget(wx.TextDropTarget):
def OnDropText(self, x, y, text):
print 'text:',text
#----------------------------------------------------------------------
class MyFileDropTarget(wx.FileDropTarget):
def OnDropFiles(self, x, y, filenames):
print 'filenames:'
for file in filenames:
print file
#----------------------------------------------------------------------
class OtherDropTarget(wx.PyDropTarget):
def __init__(self):
wx.PyDropTarget.__init__(self)
self.setDo()
def setDo(self):
#--permet plusieurs formats dragndrop...
self.do = wx.DataObjectComposite()
#--...noms de fichiers...
self.fdo= wx.FileDataObject()
self.do.Add(self.fdo)
#--...et texte
self.tdo= wx.TextDataObject()
self.do.Add(self.tdo)
#--
self.SetDataObject(self.do)
def OnData(self,*args):
self.GetData()
print 'filenames:',self.fdo.GetFilenames()
print 'text:',self.tdo.GetText()
self.setDo()
#----------------------------------------------------------------------
class MainWindow(wx.Frame):
def __init__(self,parent,id,title):
wx.Frame.__init__(self,parent,wx.ID_ANY, title, pos=wx.Point(10,10), size=wx.Size(800,500), style=wx.DEFAULT_FRAME_STYLE)
#--choisir une des trois possibilités
#dt= MyFileDropTarget() # fichiers seulement
#dt= MyTextDropTarget() # texte seulement
dt= OtherDropTarget() # fichiers + texte
#--
self.SetDropTarget(dt)
nb= wx.Notebook(self,wx.ID_ANY,style=wx.TAB_TRAVERSAL)
panel= scroll.ScrolledPanel(nb,wx.ID_ANY,style=wx.SUNKEN_BORDER|wx.TAB_TRAVERSAL)
panel.SetupScrolling()
nb.AddPage(panel,'dragndrop panel')
sizer= wx.BoxSizer(wx.VERTICAL)
sizer.Add(wx.StaticText(panel, -1, "Drag some files or text here:"),0, wx.EXPAND|wx.ALL, 2)
panel.SetSizer(sizer)
self.Show(1)
#----------------------------------------------------------------------
app = wx.PySimpleApp()
frame=MainWindow(None,-1,'Drop')
app.MainLoop()
del app
#---------------------------------------------------------------------- |
La démo donne un exemple de Wizard, mais qui est un peu compliqué, et ne règle pas le problème des textes anglais sur les boutons.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 | # -*- coding: iso-8859-1 -*-
import wx
import wx.wizard as wiz
import pywin.debugger, sys, time
#----------------------------------------------------------------------
class wizardText:
def __init__(self, parent):
self.wizard = wiz.Wizard(None, -1, "Wizard simple")
page1 = SkipNextPage(self.wizard, "Page 1", 1)
page1.jump= True
page1.sizer.Add(wx.StaticText(page1, -1, """Votre texte est ici."""))
page2 = SkipNextPage(self.wizard, "Page 2", 2)
page2.sizer.Add(wx.StaticText(page2, -1, """page 2."""))
page3 = SkipNextPage(self.wizard, "Page 3", 3)
page3.sizer.Add(wx.StaticText(page3, -1, """page 3."""))
page4 = SkipNextPage(self.wizard, "Page 4", 4)
page4.sizer.Add(wx.StaticText(page4, -1, "Ceci est la dernière page."))
self.page1 = page1
self.wizard.FitToPage(page1)
# Connects the pages
page1.SetNext(page2)
page2.SetPrev(page1)
page2.SetNext(page3)
page3.SetPrev(page2)
page3.SetNext(page4)
page4.SetPrev(page3)
# Connects the events
self.wizard.Bind(wiz.EVT_WIZARD_PAGE_CHANGED, self.OnWizPageChanged)
self.wizard.Bind(wiz.EVT_WIZARD_PAGE_CHANGING, self.OnWizPageChanging)
self.wizard.Bind(wiz.EVT_WIZARD_CANCEL, self.OnWizCancel)
self.wizard.Bind(wiz.EVT_WIZARD_FINISHED, self.OnWizFinished)
# Runs
if self.wizard.RunWizard(page1):
wx.MessageBox("Wizard terminé avec succès", "C'est tout les gars !")
else:
wx.MessageBox("Wizard annulé", "C'est tout les gars !")
def OnWizPageChanged(self, evt):
texts= (('&Next >','&Suivant >'),('&Cancel','&Annuler'),('< &Back','< &Retour'),('&Finish','Finir'))
for o in self.wizard.GetChildren():
if 'Button' in str(type(o)):
for tEng,tFr in texts:
if o.GetLabel() == tEng:
o.SetLabel(tFr)
if evt.GetDirection():
dir = "forward"
else:
dir = "backward"
def OnWizPageChanging(self, evt):
if evt.GetDirection():
dir = "forward"
else:
dir = "backward"
def OnWizCancel(self, evt):
page = evt.GetPage()
# Show how to prevent cancelling of the wizard. The
# other events can be Veto'd too.
if page is self.page1:
wx.MessageBox("Interdit sur cette page.", "Désolé")
evt.Veto()
def OnWizFinished(self, evt):
wx.MessageBox("Fini", "Fini")
#----------------------------------------------------------------------
class SkipNextPage(wiz.PyWizardPage):
def __init__(self, parent, title |