Tableau avec wxpython (wxgrid) - version 1.5

Soyez le premier à donner votre avis sur cette source.

Vue 17 477 fois - Téléchargée 1 000 fois

Description

Ce programme permet de créé un tableau comme sous Excel, d'insérer autant de colonne et de lignes qu'il veut, puis sauvegarder et restituer son document. Il a été conçu avec WxPython. Des améliorations on été apporté depuis la version 1.0 tel que la gestion des fichiers (explications dans l'aide du programme), et la modifications possibles des lignes et colonnes.

Source / Exemple :


# -*- coding: cp1252 -*-

### Importations ###

import wx
import  wx.grid as  gridlib
import sys
import os
import help_tableau

### Variables générales : Version du programme ###

Version_Programme = "1.5"
Version_Fichier = u"2.0"
Extensions_ouvrir = u"Fichier de sauvegarde Tableau (.savtx)|*.savtx|" + \
            "Fichier de sauvegarde Tableau (version 1) (.savt)|*.savt|Tout les fichiers|*.*"
Extensions_save = u"Fichier de sauvegarde Tableau (.savtx)|*.savtx|" + \
            "Tout les fichiers|*.*"

### Fonctions Prélimières : Création de listes automatiques ###

def titre_auto_col_lig(col,lig):
    liste_col = []
    liste_lig = []
    for i in range(col):
        liste_col.append(u"Colone " + str(i+1))
    for i in range(lig):
        liste_lig.append(u"Ligne " + str(i+1))
    return (liste_col,liste_lig)

### Classes Prélimières : Création d'une base de données ###

class Cellule_Donnees:
    def __init__(self,col,lig,contenu):
        self.col = col
        self.lig = lig
        self.contenu = contenu

    def sauvegarde(self):
        texte = u"Cellule\n"
        texte = texte + str(self.col) + u"\n"
        texte = texte + str(self.lig) + u"\n"
        texte = texte + self.contenu + u"\n"
        texte = texte + u"/Cellule\n"
        return texte

class Base_Donnees:
    def __init__(self,nb_lig,nb_col,nom_col,nom_lig):
        self.liste_cellules = []
        self.nb_lig = nb_lig
        self.nb_col = nb_col

        self.nom_col = nom_col
        self.nom_lig = nom_lig

    def ajouter_cellule(self,cellule):
        self.liste_cellules.append(cellule)

    def return_cellule(self,lig,col):
        for cellule in self.liste_cellules:
            if cellule.col == col and cellule.lig == lig:
                return cellule
        return 0

    def return_valeur(self,lig,col): # Inutile
        test = self.return_cellule(lig,col)
        if test != 0:
            return u''
        else:
            return test.contenu

    def supprimer_cellule(self,lig,col):
        test = self.return_cellule(lig,col)
        if test != 0:
            self.liste_cellules.remove(test)

    def change_contenu(self,lig,col,contenu):
        test = self.return_cellule(lig,col)
        if contenu == u"":
            self.supprimer_cellule(lig,col)
        elif test != 0:
            test.contenu = contenu
        else:
            cel = Cellule_Donnees(col,lig,contenu)
            self.ajouter_cellule(cel)

    def change_nom(self,num,col,nom):
        if col:
            self.nom_col.pop(num)
            self.nom_col.insert(num,nom)
        else:
            self.nom_lig.pop(num)
            self.nom_lig.insert(num,nom)

    def sauvegarder(self):
        texte = u"Tableau\n"
        texte = texte + str(Version_Fichier) + u"\n"
        texte = texte + str(self.nb_col) + u"\n"
        texte = texte + str(self.nb_lig) + u"\n"
        texte = texte + u"Nom_Lignes\n"
        for element in self.nom_lig:
            texte = texte + element + u"\n"
        texte = texte + u"/Nom_Lignes\nNom_Colones\n"
        for element in self.nom_col:
            texte = texte + element + u"\n"
        texte = texte + u"/Nom_Colones\n"
        for cellule in self.liste_cellules:
            texte = texte + cellule.sauvegarde()
        texte = texte + u"/Tableau\n"
        return texte

### Classes Graphique : Du pure wxPython ###

class Dialogue_Selecte(wx.Dialog):
    def __init__(self, parent, titre,lig,col):
        pre = wx.PreDialog()
        pre.Create(parent, -1, titre)

        self.parent=parent
        self.col = 1
            
        self.PostCreate(pre)

        sizer = wx.BoxSizer(wx.VERTICAL)
        
        box = wx.BoxSizer(wx.HORIZONTAL)
        radio1 = wx.RadioButton( self, -1, "Éditer la colone n°", style = wx.RB_GROUP )
        box.Add(radio1, 0, wx.ALIGN_CENTRE|wx.ALL, 5)
        self.nb_col_entree = wx.SpinCtrl(self, -1, "", size=(70,-1))
        self.nb_col_entree.SetRange(1,col)
        self.nb_col_entree.SetValue(1)
        box.Add(self.nb_col_entree, 0, wx.ALIGN_CENTRE|wx.ALL, 5)

        box2 = wx.BoxSizer(wx.HORIZONTAL)
        radio2 = wx.RadioButton( self, -1, "Éditer la ligne n°")
        box2.Add(radio2, 0, wx.ALIGN_CENTRE|wx.ALL, 5)
        self.nb_lig_entree = wx.SpinCtrl(self, -1, "", size=(70,-1))
        self.nb_lig_entree.SetRange(1,lig)
        self.nb_lig_entree.SetValue(1)
        box2.Add(self.nb_lig_entree, 0, wx.ALIGN_CENTRE|wx.ALL, 5)

        l = wx.StaticText(self, -1, u"Vous pouvez également modifier le nom en double cliquant sur la ligne ou la colone")
        l.SetFont(wx.Font(8, wx.SWISS, wx.ITALIC, wx.NORMAL))

        b = wx.Button(self, -1, u"Éditer la ligne ou la colone sélectionnée")
        b.SetDefault()

        sizer.Add(box, 0, wx.ALIGN_LEFT|wx.ALL, 5)
        sizer.Add(box2, 0, wx.ALIGN_LEFT|wx.ALL, 5)
        sizer.Add(l, 0, wx.ALIGN_CENTER|wx.ALL, 5)
        sizer.Add(b, 0, wx.CENTER|wx.ALL, 5)

        self.Bind(wx.EVT_RADIOBUTTON, self.select_lig, radio2)
        self.Bind(wx.EVT_RADIOBUTTON, self.select_col, radio1)
        self.Bind(wx.EVT_BUTTON, self.valide, b)

        btnsizer = wx.StdDialogButtonSizer()
            
        btn = wx.Button(self, wx.ID_CANCEL,u"Fermer cette fenêtre")

        sizer.Add(btn, 0, wx.ALL|wx.CENTER, 5)

        sizer.Add(btnsizer, 0, wx.ALL|wx.CENTER, 5)

        self.SetSizer(sizer)
        sizer.Fit(self)
        self.nb_lig_entree.Enable(False)

    def select_lig(self,evt=None):
        self.col = 0
        self.nb_lig_entree.Enable(True)
        self.nb_col_entree.Enable(False)

    def select_col(self,evt=None):
        self.col = 1
        self.nb_lig_entree.Enable(False)
        self.nb_col_entree.Enable(True)

    def valide(self,evt=None):
        if self.col:
            nom =  u"Colone"
            i = self.nb_col_entree.GetValue() - 1
            ancien = self.parent.base_de_donnees.nom_col[i]
        else:
            nom =  u"Ligne"
            i = self.nb_lig_entree.GetValue() - 1
            ancien = self.parent.base_de_donnees.nom_lig[i]

        self.Destroy()
        dlg = Dialogue_Change_Nom(self.parent,u'Modifier le nom de la ' + nom + ' ' + str(i + 1), i, nom, ancien)
        dlg.CenterOnScreen()
        val = dlg.ShowModal()

class Dialogue_Change_Nombre(wx.Dialog):
    def __init__(self, parent, titre):
        pre = wx.PreDialog()
        pre.Create(parent, -1, titre)

        self.parent=parent
            
        self.PostCreate(pre)

        sizer = wx.BoxSizer(wx.VERTICAL)

        l = wx.StaticText(self, -1, u"Si vous supprimer des lignes ou des colones il se peut que vous détruisiez de manière définitive certaines données")
        l.SetFont(wx.Font(8, wx.SWISS, wx.ITALIC, wx.NORMAL))
        
        box = wx.BoxSizer(wx.HORIZONTAL)
        label = wx.StaticText(self, -1, u"Nombre Colones : ")
        box.Add(label, 0, wx.ALIGN_CENTRE|wx.ALL, 5)
        self.nb_col_entree = wx.SpinCtrl(self, -1, "", size=(70,-1))
        self.nb_col_entree.SetRange(1,9999)
        self.nb_col_entree.SetValue(self.parent.colones)
        box.Add(self.nb_col_entree, 0, wx.ALIGN_CENTRE|wx.ALL, 5)

        box2 = wx.BoxSizer(wx.HORIZONTAL)
        label = wx.StaticText(self, -1, u"Nombre Lignes : ")
        box2.Add(label, 0, wx.ALIGN_CENTRE|wx.ALL, 5)
        self.nb_lig_entree = wx.SpinCtrl(self, -1, "", size=(70,-1))
        self.nb_lig_entree.SetRange(1,9999)
        self.nb_lig_entree.SetValue(self.parent.lignes)
        box2.Add(self.nb_lig_entree, 0, wx.ALIGN_CENTRE|wx.ALL, 5)

        self.statue = wx.StaticText(self, -1, u"Aucune modifications des données")
        self.statue.SetForegroundColour(wx.GREEN)

        b = wx.Button(self, -1, u"Modifier le nombre de lignes et de colones")
        b.SetDefault()

        sizer.Add(l, 0, wx.ALIGN_LEFT|wx.ALL, 5)
        sizer.Add(box, 0, wx.ALIGN_LEFT|wx.ALL, 5)
        sizer.Add(box2, 0, wx.ALIGN_LEFT|wx.ALL, 5)
        sizer.Add(self.statue, 0, wx.ALIGN_CENTER|wx.ALL, 5)
        sizer.Add(b, 0, wx.CENTER|wx.ALL, 5)

        self.Bind(wx.EVT_SPINCTRL, self.changement, self.nb_col_entree)
        self.Bind(wx.EVT_SPINCTRL, self.changement, self.nb_lig_entree)
        self.Bind(wx.EVT_BUTTON, self.valide, b)

        btnsizer = wx.StdDialogButtonSizer()
            
        btn = wx.Button(self, wx.ID_CANCEL,u"Fermer cette fenêtre")

        sizer.Add(btn, 0, wx.ALL|wx.CENTER, 5)

        sizer.Add(btnsizer, 0, wx.ALL|wx.CENTER, 5)

        self.SetSizer(sizer)
        sizer.Fit(self)

    def changement(self,evt=None):
        nb_lig = self.nb_lig_entree.GetValue()
        nb_col = self.nb_col_entree.GetValue()

        data = self.parent.base_de_donnees
        nb = 0
        for element in data.liste_cellules:
            if element.col >= nb_col or element.lig >= nb_lig:
                nb = nb + 1

        if nb > 0:
            self.statue.SetLabel(u"Destruction de " + str(nb) + u" cellule(s) contenant des données")
            self.statue.SetForegroundColour(wx.RED)
        else:
            self.statue.SetLabel(u"Aucune modifications des données")
            self.statue.SetForegroundColour(wx.GREEN)

    def valide(self,evt=None):
        nb_lig = self.nb_lig_entree.GetValue()
        nb_col = self.nb_col_entree.GetValue()

        data = self.parent.base_de_donnees
        supp = []
        i = 0
        for element in data.liste_cellules:
            if element.col >= nb_col or element.lig >= nb_lig:
                i = i+ 1
                supp.append(element)

        for element in supp:
            data.liste_cellules.remove(element)
        print i
        
        nom_col = []
        nom_lig = []
        
        for i in range(nb_col):
            if i < len(data.nom_col):
                nom_col.append(data.nom_col[i])
            else:
                nom_col.append(u"Colone " + str(i+1))

        for i in range(nb_lig):
            if i < len(data.nom_lig):
                nom_lig.append(data.nom_lig[i])
            else:
                nom_lig.append(u"Ligne " + str(i+1))

        data.nb_lig = nb_lig
        data.nb_col = nb_col

        data.nom_col = nom_col
        data.nom_lig = nom_lig

        self.parent.ajuster_tableau(nb_lig,nb_col)
        for cellule in data.liste_cellules:
            self.parent.tableau.SetCellValue(cellule.lig,cellule.col,cellule.contenu)
        self.Destroy()
                

class Dialogue_Change_Nom(wx.Dialog):
    def __init__(self, parent, titre, num, nom, contenu):
        pre = wx.PreDialog()
        pre.Create(parent, -1, titre)

        self.parent=parent
        self.contenu = contenu
        self.numero = num
        self.nom = nom
            
        self.PostCreate(pre)

        sizer = wx.BoxSizer(wx.VERTICAL)        
        box = wx.BoxSizer(wx.HORIZONTAL)

        label = wx.StaticText(self, -1, u"Texte de la " + self.nom + u" " + str(self.numero + 1) + u' : ')
        box.Add(label, 0, wx.ALIGN_CENTRE|wx.ALL, 5)
        self.text = wx.TextCtrl(self, -1, self.contenu, size=(200,-1))
        box.Add(self.text, 1, wx.ALIGN_CENTRE|wx.ALL, 5)

        b = wx.Button(self, -1, u"Modifier le nom")
        b.SetDefault()

        sizer.Add(box, 0, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5)
        sizer.Add(b, 0, wx.CENTER|wx.ALL, 5)
        self.Bind(wx.EVT_BUTTON, self.valide, b)

        btnsizer = wx.StdDialogButtonSizer()
            
        btn = wx.Button(self, wx.ID_CANCEL,u"Fermer cette fenêtre")

        sizer.Add(btn, 0, wx.ALL|wx.CENTER, 5)

        sizer.Add(btnsizer, 0, wx.ALL|wx.CENTER, 5)

        self.SetSizer(sizer)
        sizer.Fit(self)

    def valide(self,evt):
        entree = self.text.GetValue().strip()
        if entree == u"":
            dal = wx.MessageDialog(self, u"Veuillez rentrer un nom à la " + self.nom,
                                   u'Erreur de saisie',wx.OK | wx.ICON_EXCLAMATION)
            dal.ShowModal()
            dal.Destroy()
        elif entree == u"/Nom_Colones" or entree == u"/Nom_Lignes":
            dal = wx.MessageDialog(self, u"Vous avez rentré un nom interdit.\n Il est interdit de rentrer '/Nom_Colones' ou '/Nom_Lignes'",
                                   u'Erreur de saisie',wx.OK | wx.ICON_EXCLAMATION)
            dal.ShowModal()
            dal.Destroy()
        else:
            if self.nom == "Colone":
                a = 1
            else:
                a = 0
            self.parent.base_de_donnees.change_nom(self.numero,a,entree)
            self.parent.titre_col_lig()
            self.parent.enr = 1
            self.parent.message_save()
            self.Destroy()

class Fenetre(wx.Frame):
    def __init__(self, parent, title,nb_lig=5,nb_col=5):
        wx.Frame.__init__(self, parent, -1, title, size=(800, 400))
        self.SetIcon(wx.Icon("Data\\icone_tableau.ico", wx.BITMAP_TYPE_ICO))
        self.Bind(wx.EVT_CLOSE, self.quitter)

        BarreMenu = wx.MenuBar()
        
        fichier = wx.Menu()
        fichier.Append(11, u"&Nouveau\tCtrl+N", u"Charger un document vierge")
        fichier.Append(12, u"Nouvelle &fenêtre", u"Créer une nouvelle fenêtre de tableau")
        fichier.AppendSeparator()
        fichier.Append(13, u"&Ouvrir\tCtrl+O", u"Ouvrir le tableau précédement sauvegardé")
        fichier.Append(14, u"&Enregistrer\tCtrl+S", u"Sauvegarder le tableau")
        fichier.Append(15, u"&Enregistrer sous ...\tCtrl+Shift+S", u"Sauvegarder le tableau dans un fichier particuier")
        fichier.AppendSeparator()
        fichier.Append(16, u"&Quitter\tAlt+F4", u"Quitter le programme d'exemple")
        BarreMenu.Append(fichier, u"&Fichier")

        option = wx.Menu()
        option.Append(21, u"Changer le &nom des lignes et colones", u"Permet de sélectionner la ligne ou la colone a renomer")
        option.Append(22, u"Configurer le nom&bre des lignes et colones", u"Permet de changer le nombre de lignes et/ou de colones")
        BarreMenu.Append(option, u"&Options")

        aide = wx.Menu()
        aide.Append(31, u"&Aide\tF1", u"Optenir de l'aide sur le programme")
        aide.Append(32, u"À &propos de ...\tF2", u"Informations divers sur le programme")
        BarreMenu.Append(aide, u"&Aide")

        self.Bind(wx.EVT_MENU, self.nouveau, id=11)
        self.Bind(wx.EVT_MENU, self.new_fenetre, id=12)
        self.Bind(wx.EVT_MENU, self.pre_ouvrir, id=13)
        self.Bind(wx.EVT_MENU, self.save, id=14)
        self.Bind(wx.EVT_MENU, self.pre_save, id=15)
        self.Bind(wx.EVT_MENU, self.quitter, id=16)

        self.Bind(wx.EVT_MENU, self.select_edit, id=21)
        self.Bind(wx.EVT_MENU, self.modif_nb, id=22)

        self.Bind(wx.EVT_MENU, self.aide, id=31)
        self.Bind(wx.EVT_MENU, self.about, id=32)
        
        self.SetMenuBar(BarreMenu)

        self.sb = wx.StatusBar(self)
        self.sb.SetFieldsCount(2)
        self.sb.SetStatusWidths([-1, -1])
        
        self.SetStatusBar(self.sb)

        self.lignes = nb_lig
        self.colones = nb_col
        self.enr = 0
        self.chemain_fichier = u"Pas encore enregistré"
        
        l_col,l_lig = titre_auto_col_lig(self.colones,self.lignes)        
        self.base_de_donnees = Base_Donnees(self.lignes,self.colones,l_col,l_lig)

        
        panel = wx.Panel(self)

        self.tableau = gridlib.Grid(panel,-1,size=(800,300))
        self.tableau.CreateGrid(self.lignes,self.colones)

        self.titre_col_lig()        
        self.tableau.Bind(gridlib.EVT_GRID_CELL_CHANGE, self.changement)
        self.tableau.Bind(gridlib.EVT_GRID_LABEL_LEFT_DCLICK, self.edite)

        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(self.tableau, 1, wx.ALL|wx.GROW, 10)
        panel.SetSizer(sizer)
        panel.Layout()
        self.Centre()

        self.message_save()

    def quitter(self,evt=None):
        if self.enr:
            dal = wx.MessageDialog(self, u"Vous n'avais pas sauvegarder les modifications de ce fichier.\nVoullez vous enregistrer avant de quitter ?",
                                       u"Confirmation de fermeture",wx.YES_NO|wx.CANCEL| wx.ICON_QUESTION)
            test = dal.ShowModal()
            dal.Destroy()
            if test == wx.ID_YES:
                test = self.save()
                if test:
                    self.Destroy()
            elif test == wx.ID_NO:
                self.Destroy()
        else:
            self.Destroy()

    def message_save(self,evt=None):
        if self.enr:
            texte = u"*" + self.chemain_fichier
        else:
            texte = self.chemain_fichier
        self.sb.SetStatusText(texte, 1)

    def nouveau(self,evt=None):
        ok = 0
        if self.enr:
            dal = wx.MessageDialog(self, u"Vous n'avais pas sauvegarder les modifications de ce fichier.\nVoullez vous enregistrer avant de réinitialiser ?",
                                       u"Confirmation de réinitialisation",wx.YES_NO|wx.CANCEL| wx.ICON_QUESTION)
            test = dal.ShowModal()
            dal.Destroy()
            if test == wx.ID_YES:
                test = self.save()
                if test:
                    ok = 1
            elif test == wx.ID_NO:
                ok = 1
        else:
            ok = 1

        if ok:
            self.ajuster_tableau(5,5)
            
            l_col,l_lig = titre_auto_col_lig(self.colones,self.lignes)        
            self.base_de_donnees = Base_Donnees(self.lignes,self.colones,l_col,l_lig)
            self.titre_col_lig()
            self.enr = 0
            self.chemain_fichier = u"Pas encore enregistré"
            self.message_save()

    def new_fenetre(self,evt=None):
        frame = Fenetre(None, u"Démonstration de sauvegarde & de wxGrid")
        frame.Show(True)

    def changement(self,evt):
        lig = evt.GetRow()
        col = evt.GetCol()
        valeur = self.tableau.GetCellValue(lig,col)
        self.base_de_donnees.change_contenu(lig,col,valeur)
        self.enr = 1
        self.message_save()

    def select_edit(self,evt=None):
        dlg = Dialogue_Selecte(self,u'Sélectionner la ligne ou la colone à modifier',self.lignes,self.colones)
        dlg.CenterOnScreen()
        val = dlg.ShowModal()

    def edite(self,evt):
        lig,col = evt.GetRow(), evt.GetCol()
        if lig == -1 and not (col == -1):
            nom =  u"Colone"
            i = col
            ancien = self.base_de_donnees.nom_col[i]
        elif col == -1 and not (lig == -1):
            nom =  u"Ligne"
            i = lig
            ancien = self.base_de_donnees.nom_lig[i]
        else:
            return

        dlg = Dialogue_Change_Nom(self,u'Modifier le nom de la ' + nom + ' ' + str(i + 1), i, nom, ancien)
        dlg.CenterOnScreen()
        val = dlg.ShowModal()

    def modif_nb(self,evt=None):
        dlg = Dialogue_Change_Nombre(self,u'Modifier le nombre de lignes et de colones')
        dlg.CenterOnScreen()
        val = dlg.ShowModal()

    def aide(self,evt=None):
        dlg = help_tableau.Aide(self)
        dlg.Show(True)
        dlg.CenterOnScreen() 
        
    def about(self,evt=None):
        dlg = help_tableau.About(self, -1, u"À propos de ...")
        dlg.CenterOnScreen()
        val = dlg.ShowModal() 
        
    def save(self,evt=None):
        if self.chemain_fichier == u"Pas encore enregistré" or not(self.chemain_fichier.split(u".")[-1] == u"savtx"):
            test = self.pre_save()
            return test
        else:
            self.sauvegarder(self.chemain_fichier)
            return 1

    def pre_save(self,evt=None):
        dlg = wx.FileDialog(self, message=u"Enregistrer le Tableau", defaultDir=os.getcwd(), 
            defaultFile="", wildcard=Extensions_save, style=wx.SAVE)
        
        if dlg.ShowModal() == wx.ID_OK:            
            fichier = dlg.GetPath()
            self.sauvegarder(fichier)
            return 1
        else:
            return 0

    def sauvegarder(self,chemain):
        donnees = self.base_de_donnees.sauvegarder()

        tete = u"""File Proction Data - Tableau
Exemple Aera Tableau
Version """ + Version_Programme

        ecrire = tete + u'\n' + donnees
        try:
            fichier = open(chemain,u"Uw") # Fonctionne jusqu'à Python 2.5 (?)
        except:
            try:
                fichier = open(chemain,u"w") # Fonctionne depuis Python 2.6 (?) (Choix automatique :p)
            except:
                dal = wx.MessageDialog(self, u"Impossible d'enregistrer le fichier. Erreur dans la création du fichier",
                                   u"Erreur grave",wx.OK | wx.ICON_ERROR)
                dal.ShowModal()
                dal.Destroy()
                return

        try:
            fichier.write(ecrire.encode(u"utf-8")) # Encodage pour les chaines de carractères Unicode
            fichier.close()
        except:
            dal = wx.MessageDialog(self, u"Impossible d'enregistrer le fichier. Erreur dans l'écriture",
                                   u"Erreur grave",wx.OK | wx.ICON_ERROR)
            dal.ShowModal()
            dal.Destroy()
        finally:
            fichier.close()
        self.enr = 0
        self.chemain_fichier = chemain
        self.message_save()

    def titre_col_lig(self):
        for i in range(len(self.base_de_donnees.nom_col)):
            self.tableau.SetColLabelValue(i,self.base_de_donnees.nom_col[i])
        for i in range(len(self.base_de_donnees.nom_lig)):
            self.tableau.SetRowLabelValue(i,self.base_de_donnees.nom_lig[i])
        self.tableau.SetColLabelAlignment(wx.ALIGN_LEFT, wx.ALIGN_BOTTOM)

    def ajuster_tableau(self,new_lig,new_col):
        self.tableau.ClearGrid()
        
        delta_lignes = self.lignes - new_lig
        delta_colones = self.colones - new_col

        if delta_lignes >0:
            for i in range(delta_lignes):
                self.tableau.DeleteRows()
        elif delta_lignes <0:
            for i in range(-delta_lignes):
                self.tableau.AppendRows()
        if delta_colones >0:
            for i in range(delta_colones):
                self.tableau.DeleteCols()
        elif delta_colones <0:
            for i in range(-delta_colones):
                self.tableau.AppendCols()

        self.lignes = new_lig
        self.colones = new_col
        
        self.titre_col_lig()

    def pre_ouvrir(self,evt=None):
        ok = 0
        if self.enr:
            dal = wx.MessageDialog(self, u"Vous n'avais pas sauvegarder les modifications de ce fichier.\nVoullez vous enregistrer avant d'ouvrir ?",
                                       u"Confirmation de réinitialisation",wx.YES_NO|wx.CANCEL| wx.ICON_QUESTION)
            test = dal.ShowModal()
            dal.Destroy()
            if test == wx.ID_YES:
                test = self.save()
                if test:
                    ok = 1
            elif test == wx.ID_NO:
                ok = 1
        else:
            ok = 1

        if ok:
            dlg = wx.FileDialog(
                self, message=u"Ouvrir un fichier Tableau", defaultDir=os.getcwd(), 
                defaultFile="", wildcard=Extensions_ouvrir, style=wx.OPEN)
            
            if dlg.ShowModal() == wx.ID_OK:
                fichier = dlg.GetPaths()[0]
                self.ouvrir(fichier)
        
        
    def ouvrir(self,chemain):
        err = 0
        if not(os.path.isfile(chemain)):
            dal = wx.MessageDialog(self, u"Le fichier que vous souhaitez ouvrir n'existe pas !",
                                   u"Erreur d'utilisation",wx.OK | wx.ICON_ERROR)
            dal.ShowModal()
            dal.Destroy()
            err = 1
        else:
            try:
                fichier = open(chemain,u"Ur") # Fonctionne jusqu'à Python 2.5 (?)
            except:
                try:
                    fichier = open(chemain,u"r") # Fonctionne depuis Python 2.6 (?) (Choix automatique :p)
                except:
                    dal = wx.MessageDialog(self, u"Problème lors de l'ouverture du fichier.\nImpossible d'ouvrir le fichier",
                                       u'Grave erreur',wx.OK | wx.ICON_ERROR)
                    dal.ShowModal()
                    dal.Destroy()
                    err = 1

        if not(err):
            try:
                l1 = fichier.readline().decode(u"utf-8")[:-1]
                if l1 == u"File Proction Data - Tableau":
                    l2 = fichier.readline().decode(u"utf-8")[:-1]
                    if l2 == u"Exemple Aera Tableau":
                        l3 = fichier.readline().decode(u"utf-8")[:-1]
                        if u"Version" in l3:
                            version = l3[8:]
                            l4 = fichier.readline().decode(u"utf-8")[:-1]
                            if l4 == u"Tableau":
                                version_file = fichier.readline().decode(u"utf-8")[:-1]
                                if version_file == u"2.0":
                                    test = self.ouvrir_version_2_0(fichier)
                                    if test:
                                        self.enr = 0
                                        self.chemain_fichier = chemain
                                        self.message_save()
                                else:
                                    dal = wx.MessageDialog(self, u"Le fichier que vous souhaitez ouvrir est bien un fichier Tableau mais " + \
                                                           u"à une version non prise en compte",u"Erreur à l'ouverture",wx.OK | wx.ICON_EXCLAMATION)
                                    dal.ShowModal()
                                    dal.Destroy()
                                    fichier.close()
                            else:
                                dal = wx.MessageDialog(self, u"Le fichier que vous souhaitez ouvrir est corrompu",
                                       u"Erreur à l'ouverture",wx.OK | wx.ICON_ERROR)
                                dal.ShowModal()
                                dal.Destroy()
                                fichier.close()
                        else:
                            dal = wx.MessageDialog(self, u"Le fichier que vous souhaitez ouvrir est corrompu",
                                       u"Erreur à l'ouverture",wx.OK | wx.ICON_ERROR)
                            dal.ShowModal()
                            dal.Destroy()
                            fichier.close()
                    else:
                        dal = wx.MessageDialog(self, u"Le fichier que vous souhaitez ouvrir ne correspond pas au programme",
                                       u"Erreur à l'ouverture",wx.OK | wx.ICON_ERROR)
                        dal.ShowModal()
                        dal.Destroy()
                        fichier.close()
        
                elif l1 == u"Tableau v1":
                    test = self.ouvrir_version_1(fichier)
                    if test:
                        self.enr = 0
                        self.chemain_fichier = chemain
                        self.message_save()
                else:
                    dal = wx.MessageDialog(self, u"Le fichier que vous souhaitez ouvrir ne correspond pas au programme",
                                       u"Erreur à l'ouverture",wx.OK | wx.ICON_ERROR)
                    dal.ShowModal()
                    dal.Destroy()
                    fichier.close()
                    
            except:
                dal = wx.MessageDialog(self, u"Impossible de lire les données dans le fichier",
                                       u"Erreur à l'ouverture",wx.OK | wx.ICON_ERROR)
                dal.ShowModal()
                dal.Destroy()
                fichier.close()

            

    def ouvrir_version_2_0(self,fichier):
        try :
            nb_col = fichier.readline().decode(u"utf-8")[:-1]
            nb_lig = fichier.readline().decode(u"utf-8")[:-1]

            nb_col, nb_lig = int(nb_col),int(nb_lig)

            l_lig = []
            l_col = []
                            
            fichier.readline().decode(u"utf-8")
            while 1:
                l = fichier.readline().decode(u"utf-8")
                if l == u"/Nom_Lignes\n":
                    break
                elif l == u"": # Au cas où on est au bout de programme pour évité la boucle infini
                    1/0  # On force le passage à l'exception (= Erreur)
                l_lig.append(l[:-1])
                                
            fichier.readline().decode(u"utf-8")
            while 1:
                l = fichier.readline().decode(u"utf-8")
                if l == u"/Nom_Colones\n":
                    break
                elif l == u"": # Au cas où on est au bout de programme pour évité la boucle infini
                    1/0  # On force le passage à l'exception (= Erreur)
                l_col.append(l[:-1])

            if not(nb_lig == len(l_lig) and nb_col == len(l_col)):
                1/0  # On force le passage à l'exception (= Erreur)
                            
            base_de_donnees_temp = Base_Donnees(nb_col, nb_lig,l_col,l_lig) # On crée une nouvelle base de données
        except:
            dal = wx.MessageDialog(self, u"Le fichier que vous souhaitez ouvrir est corrompu",
                                   u"Erreur à l'ouverture",wx.OK | wx.ICON_ERROR)
            dal.ShowModal()
            dal.Destroy()
            fichier.close()
            return 0 # Fin de la fonction :p
        
        
        while 1:
            ligne = fichier.readline().decode(u"utf-8")
            if ligne == u'':
                break
            elif ligne == u"Cellule\n":
                try:
                    col = fichier.readline().decode(u"utf-8")[:-1]
                    lig = fichier.readline().decode(u"utf-8")[:-1]
                    contenu = fichier.readline().decode(u"utf-8")[:-1]
                    lig , col = int(lig),int(col)
                    if 1<= lig+1 <= base_de_donnees_temp.nb_lig and 1<= col+1 <= base_de_donnees_temp.nb_col:
                        base_de_donnees_temp.change_contenu(lig,col,contenu)
                    else:
                        print "ok"
                        1/0 # On force le passage à l'exception (= Erreur)
                    if fichier.readline() != "/Cellule\n": # Vérification
                        1/0 # On force le passage à l'exception (= Erreur)
                except:
                    dal = wx.MessageDialog(self, u"Le fichier que vous souhaitez ouvrir est corrompu",
                                   u"Erreur à l'ouverture",wx.OK | wx.ICON_ERROR)
                    dal.ShowModal()
                    dal.Destroy()
                    fichier.close()
                    return 0 # Fin de la fonction :p

        fichier.close()

        self.base_de_donnees = base_de_donnees_temp
        self.ajuster_tableau(int(nb_lig),int(nb_col))
        for cellule in self.base_de_donnees.liste_cellules:
            self.tableau.SetCellValue(cellule.lig,cellule.col,cellule.contenu)
        return 1

    def ouvrir_version_1(self,fichier):
        try:
            l1 = fichier.readline()[:-1]
            l2 = fichier.readline()[:-1]
            l_col = eval(l1)
            l_lig = eval(l2)
            base_de_donnees_temp = Base_Donnees(len(l_col), len(l_lig),l_col,l_lig)
            while 1:
                ligne = fichier.readline().decode(u"utf-8")
                if ligne == u"":
                    break
                if ligne != u"\n":
                    ligne = ligne[17:]
                    a = eval(ligne)
                    lig = a[0]
                    col = a[1]
                    contenu = a[2]
                    
                    lig = int(lig)
                    col = int(col)
                    if 1<= lig+1 <= base_de_donnees_temp.nb_lig and 1<= col+1 <= base_de_donnees_temp.nb_col:
                        base_de_donnees_temp.change_contenu(lig,col,contenu)
                    else:
                        1/0 # On force le passage à l'exception (= Erreur)                
        except:
            dal = wx.MessageDialog(self, u"Le fichier que vous souhaitez ouvrir est corrompu",
                                   u"Erreur à l'ouverture",wx.OK | wx.ICON_ERROR)
            dal.ShowModal()
            dal.Destroy()
            fichier.close()
            return 0 # Fin de la fonction :p

        fichier.close()

        self.base_de_donnees = base_de_donnees_temp
        self.ajuster_tableau(len(l_lig),len(l_col))
        for cellule in self.base_de_donnees.liste_cellules:
            self.tableau.SetCellValue(cellule.lig,cellule.col,cellule.contenu)
        return 1
        

if 1: # Lancement de l'application
    app = wx.PySimpleApp(redirect=True)
    app.SetAppName(u"Tableau - Aéra")
    if len(sys.argv) >1:
        fichier = sys.argv[1] # Si il y a des argument supplémentaire on ne s'en occupe pas !
        frame = Fenetre(None, u"Démonstration de sauvegarde & de wxGrid")
        frame.ouvrir(fichier)
    else:
        frame = Fenetre(None, u"Démonstration de sauvegarde & de wxGrid")
    frame.Show(True)
    app.MainLoop()

Conclusion :


POUR CEUX QUI DÉSIR TÉLÉCHARGER WX.PYTHON :

Allez sur le site http://www.wxpython.org/download.php et sélectionner la version correspondant à votre version de Python et à votre système d'exploitation.

POUR FONCTIONNER LE PROGRAMME PRINCIPALE DOIT ÊTRE DANS LE MÊME DOSSIER QUE LE MODULE help_tableau.py ET QUE LE DOSSIER Data
CES DEUX DÉPENDANCES SONT DANS LE ZIP

Codes Sources

A voir également

Ajouter un commentaire Commentaires
Messages postés
382
Date d'inscription
mercredi 23 août 2006
Statut
Membre
Dernière intervention
8 novembre 2010
16
Erreurs dans la version 1.5 :

- Erreur de fermeture : Lors de la fermeture de plusieurs fenêtres en choisissant l'option NON pour la sauvegarde il y a une erreur à la fermeture de la dernière fenêtre.
=> Erreur de wxPython (?) / Pas de solution trouvé actuellement.

- Oublie : Pas de prise en compte de la modification du nombre de lignes/colonnes pour les options de modification.
=> Corriger dans la version 1.5.1 disponible la semaine prochaine

- Erreur d'orthographe (comme d'ab :p).
=> Certaine serons corrigé dans la version 1.5.1 / Possibilité de me laisser un MP pour me les signaler ou corriger directement la source.

Pour les autres erreurs (des autres ? :p) si vous en voyer n'hésitez pas à me les signaler ...
Messages postés
382
Date d'inscription
mercredi 23 août 2006
Statut
Membre
Dernière intervention
8 novembre 2010
16
Nouvelle version en ligne : 1.5
Messages postés
43
Date d'inscription
mercredi 22 mai 2002
Statut
Membre
Dernière intervention
29 octobre 2007

Je travail aussi sous wxPython qui fait tout ce qu'on lui demande (Même si la transparence est très mal gérée).
Je confirme que ça marche sous linux (déjà utilisé), pour MAC je ne suis pas sur.

Donc juste pour dire qu'il existe un RAD pour wxPython -> BOA constructor http://boa-constructor.sourceforge.net/
Très pratique pour les feignasses comme moi ;) Sinon souvent bienvenue pour les débutants.
(Mais interfaces un peu rebutante au début, en fait il y a simplement un petit bouton (trop discret?) avec une petite flèche pour utiliser l'outil de dessin qui apparait à l'utilisation d'une frame ou autre)

Sinon merci à toi et aux autres pour vos sources.

Mouss
Messages postés
382
Date d'inscription
mercredi 23 août 2006
Statut
Membre
Dernière intervention
8 novembre 2010
16
Personellement, je ne travail que sous Windows, mais je sais que WxPython fonctionne sous Linux et donc sans doute sous Mac (pour les ordis Apple). En tout cas, merci pour cette note. Tu verras, WxPython est un peux dure à métriser au début, mais avec les exemple dans le zip de démo (téléchargable sur http://www.wxpython.org/download.php), on arrive assez facilement à créé de petite application simpa comme celle-ci (bon d'accord, elle ne sert pas à grand chose, mais ça permet de voir un petit exemple avec wx.grid qui n'est pas le widget le plus simple sous wx). Si tu as besoin d'aide, n'ésite pas à me contacter (c'est valable également pour les autres - vive le forum !!!) mais n'attend pas de réponse avant le 1er mai (vive les vacances :)). Tu veras, WxPython est bien mieux que Tkinter.
Bon courrage
_____
Aéra
Messages postés
336
Date d'inscription
samedi 26 novembre 2005
Statut
Membre
Dernière intervention
8 novembre 2011
2
Bravo aéra, et merci pour cet exemple : je vais peut-être me mettre au Wx

question : Wx fonctionne sous toute les plateformes non ?

ce vaut un petit 9/10


Xeolin
Afficher les 6 commentaires

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.