IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

wxPython Discussion :

Aide pour une application


Sujet :

wxPython

  1. #1
    Membre à l'essai
    Homme Profil pro
    technicien polyvalent debutant developpeur web / maintenance
    Inscrit en
    Octobre 2009
    Messages
    24
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France

    Informations professionnelles :
    Activité : technicien polyvalent debutant developpeur web / maintenance

    Informations forums :
    Inscription : Octobre 2009
    Messages : 24
    Points : 14
    Points
    14
    Par défaut Aide pour une application
    Bonjour,

    Alors voilà on m'a demandé de faire un petit projet en python en peu de temps alors que je ne connaissait pas ce langage. J'ai donc commencer python il y a moins d'un mois et j'ai donc encore quelques souci.

    En gros j'ai décidé de faire en python un logiciel de type Griboull_i http://pedagogie.ac-toulouse.fr/svt/...rez/gribouill/

    Gribouill_i est un logiciel qui permet de "dessiner sur son ecran" pour cela il prends un screenshot de l'écran avant de dessiner dessus.
    Moi je préfère le faire avec une fenêtre transparente sur laquelle je dessinerai

    J'ai donc opter pour wxPython car c'est la première GUI avec laquelle j'ai réussi a obtenir une fenêtre transparente.

    Je bloque à deux endroit pour le moment.

    - Je n'ai pas trouver comment mes objet dessiné sur une fenêtre transparente ne soit pas eux même transparent.(Par exemple le masque (def drawMask) bien qu'il soit en opaque il hérite de la transparence de son conteneur: window(wx.frame))
    - Ni comment garder les dessins effectués

    Alors voici mon code
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
     
    # -*- coding: cp1252 -*-
    #/usr/bin/env
    import wx
     
    class window(wx.Frame):
        #window
        def __init__(self, parent, id, titre):
            wx.Frame.__init__(self, parent, id, titre)
            #taille de la fenetre/width of this window
            a = wx.GetDisplaySize() 
            b = str(a)
            b = b.replace('(','')
            b = b.replace(')','')
            b = b.replace(' ','')
            self.windowWidth = int(b.split(',')[0])
            self.windowHeight = int(b.split(',')[1])
            a = self.windowWidth
            self.windowWidth2 = int(a/2.2)
            self.SetSize(wx.Size(self.windowWidth2,self.windowHeight))
            #panel
            self.cnv=wx.Panel(self,-1)
            print "panneau créé"
            #creation of Client DC      
            self.dc=wx.ClientDC(self.cnv)
            print "clientDC créé"
     
        def OnCloseWindow(self, evt):
            self.Destroy()
     
    class windowTool(window):
        #windowTool inheriting class window () / héritant de la classe window()
        def __init__(self, parent, id, titre):
            window.__init__(self, parent, id, titre)
            #taille de la fenetre/width of this window
            height = self.GetParent().windowHeight
            a = self.GetParent().windowWidth2
            b = self.GetParent().windowWidth - 1920 #cela m'est utile pour le dualscreen / 
            width = int(b-a)
            self.SetSize(wx.Size(width, height))
            self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)
            #panel dans lequel on va mettre les boutons / panel in which we will put the buttons
            panel = wx.Panel(self, size=(170, height))
            #boutons / buttuns
            button_drawLine = wx.Button(panel, -1, "Tracer ligne", (10,10))
            button_drawRectangle = wx.Button(panel, -2, "Placer masque", (10,50))
            button_highlight = wx.Button(panel, -3, "Surligner", (10,90))
            button_close = wx.Button(panel, -4, "Fermer Application", (10,130))
            #evenements / Events
            self.Bind(wx.EVT_BUTTON, self.EventPosition, button_drawLine)
            self.Bind(wx.EVT_BUTTON, self.EventPosition, button_highlight)
            self.Bind(wx.EVT_BUTTON, self.EventPosition, button_drawRectangle)
            self.Bind(wx.EVT_BUTTON, self.GetParent().OnCloseWindow, button_close)
     
        def OnCloseWindow(self, evt):
            self.Destroy()
     
        def EventPosition(self, evt):
            self.btn = evt.GetEventObject()
            print "event position"
            #Focus sur la fenetre transparente et détection des mouvements de la souris 
            #Focus on the transparent window and detection of mouse movements
            self.GetParent().Raise()
            self.GetParent().cnv.Bind(wx.EVT_LEFT_DOWN, self.EventMotion)
     
        def EventMotion(self, evt):
            print "event motion"
            #sauvegarde de la position du clique / #save the position of clicks
            self.posx = evt.GetX() 
            self.posy = evt.GetY()
            self.GetParent().Refresh ()
            self.GetParent().cnv.Bind(wx.EVT_MOTION, self.Position)
     
        def Position(self, evt):
            #if mouse leftbutton is down
            if wx.GetMouseState().LeftDown():
                print "position"
                #Assignation de la position du curseur/ #Detection, arrest and send the cursor position
                self.posx2 = evt.GetX() 
                self.posy2 = evt.GetY()
                self.GetParent().Refresh ()
                self.GetParent().cnv.Bind(wx.EVT_PAINT, self.Paint)
     
        def Paint(self, evt):
            print "Paint"
            #creation de la toile / creation of the painting canvas
            self.GetParent().dc = wx.PaintDC(self.GetParent().cnv)  
            if self.btn.GetLabelText()=="Tracer ligne":
                self.drawLine(self.dc)
            if self.btn.GetLabelText()=="Placer masque":
                self.drawMask(self.dc)
            if self.btn.GetLabelText()=="Surligner":    
                self.highlight(self.dc)
     
        def drawLine(self, dc):     
            print "i drawing line"
            self.GetParent().dc.SetPen(wx.Pen('black', 2)) 
            self.GetParent().dc.DrawLine(self.posx2, self.posy2,self.posx,self.posy) 
     
     
        def drawMask(self, dc):
            print "i drawing mask"
            self.GetParent().dc.SetPen(wx.Pen('red', 2)) 
            self.GetParent().dc.SetBrush(wx.Brush(wx.Color(0, 0, 0), wx.ALPHA_OPAQUE)) 
            self.GetParent().dc.DrawRectangle(self.posx, self.posy, self.posx2 - self.posx, self.posy2- self.posy) 
     
        def highlight (self, dc):
            print "i drawing highlight"    
            self.GetParent().dc.SetBrush(wx.Brush(wx.Color(150, 250, 150)))
            self.GetParent().dc.DrawRectangle(self.posx, self.posy, self.posx2 - self.posx, self.posy2- self.posy)
     
    class monApp (wx.App):
        def OnInit(self):
            frm = window(None, -1, 'transparent')
            frm.Show(True)
            frm.SetTransparent(55) # pour l'instant j'utilise une semi transparence sinon je ne vois pas les dessins.
            frmTool = windowTool(frm, -2, 'outils')
            frmTool.Show(True)
            return True
     
    if __name__ == "__main__":
        app = monApp()
        app.MainLoop()
    Pour y voir plus clair dans le fonctionnement vous pouvez exécuter mon code. J'ai mis des print un peu partout pour voir où le programme passe
    Merci pour toute aide ou remarque constructive

  2. #2
    Membre du Club
    Inscrit en
    Juillet 2005
    Messages
    71
    Détails du profil
    Informations personnelles :
    Âge : 43

    Informations forums :
    Inscription : Juillet 2005
    Messages : 71
    Points : 53
    Points
    53
    Par défaut
    Bonsoir,

    Je voulais essayer votre code seulement sous wx 2.8, j'ai une erreur :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    Traceback (most recent call last):
      File "C:\Documents and Settings\Administrateur\Mes documents\astugeclim\element_pour_developpement\dessin_ecran.py", line 122, in <module>
        app = monApp()
      File "c:\Python26\lib\site-packages\wx-2.8-msw-unicode\wx\_core.py", line 7935, in __init__
        self._BootstrapApp()
      File "c:\Python26\lib\site-packages\wx-2.8-msw-unicode\wx\_core.py", line 7509, in _BootstrapApp
        return _core_.PyApp__BootstrapApp(*args, **kwargs)
      File "C:\Documents and Settings\Administrateur\Mes documents\astugeclim\element_pour_developpement\dessin_ecran.py", line 117, in OnInit
        frmTool = windowTool(frm, -2, 'outils')
      File "C:\Documents and Settings\Administrateur\Mes documents\astugeclim\element_pour_developpement\dessin_ecran.py", line 46, in __init__
        button_drawRectangle = wx.Button(panel, -2, "Placer masque", (10,50))
      File "c:\Python26\lib\site-packages\wx-2.8-msw-unicode\wx\_controls.py", line 87, in __init__
        _controls_.Button_swiginit(self,_controls_.new_Button(*args, **kwargs))
    PyAssertionError: C++ assertion "id == wxID_ANY || (id >= 0 && id < 32767)" failed at ..\..\src\common\wincmn.cpp(249) in wxWindowBase::CreateBase(): invalid id value
    L'avez vous développé sous cette version ?

    Bonne soirée.

  3. #3
    Membre à l'essai
    Homme Profil pro
    technicien polyvalent debutant developpeur web / maintenance
    Inscrit en
    Octobre 2009
    Messages
    24
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France

    Informations professionnelles :
    Activité : technicien polyvalent debutant developpeur web / maintenance

    Informations forums :
    Inscription : Octobre 2009
    Messages : 24
    Points : 14
    Points
    14
    Par défaut
    Bonjour,

    Désolé du retard j'avais un peu perdu espoir a force^^
    Alors je l'ai développer en python 2.6 et wxpyhton 2.8.
    Je travail sous ubuntu. Je vais tester mon appli sur windows 7 aussi et vous tiens au courant.

    Voici mon code tel qu'il fonctionne sous ubuntu:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
     
    # -*- coding: cp1252 -*-
    #/usr/bin/env
    import wx
     
    class window(wx.Frame):
        #window
        def __init__(self, parent, id, titre):
            wx.Frame.__init__(self, parent, id, titre)
            #taille de la fenetre/width of this window
            a = wx.GetDisplaySize() 
            b = str(a)
            b = b.replace('(','')
            b = b.replace(')','')
            b = b.replace(' ','')
            self.windowWidth = int(b.split(',')[0])
            self.windowHeight = int(b.split(',')[1])
            a = self.windowWidth
            self.windowWidth2 = int(a/2.2)
            self.SetSize(wx.Size(self.windowWidth2,self.windowHeight))
            #panel
            self.cnv=wx.Panel(self,-1)
            print "panel create"
            #creation of Client DC      
            self.dc=wx.ClientDC(self.cnv)
            print "clientDC create"
     
        def OnCloseWindow(self, evt):
            self.Destroy()
     
    class windowTool(window):
        #windowTool inheriting class window () / h�ritant de la classe window()
        def __init__(self, parent, id, titre):
            window.__init__(self, parent, id, titre)
            #taille de la fenetre/width of this window
            height = self.GetParent().windowHeight
            #debut lignes a commenter dans le cas d'un seul ecran
            a = self.GetParent().windowWidth2
            b = self.GetParent().windowWidth - 1920 #cela m'est utile pour le dualscreen / 
            width = int(b-a)
            self.SetSize(wx.Size(width, height))
            #fin ligne a commenter dans le cas d'un seul ecran
            self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)
            #panel dans lequel on va mettre les boutons / panel in which we will put the buttons
            panel = wx.Panel(self, size=(170, height))
            #boutons / buttuns
            button_drawLine = wx.Button(panel, -1, "Tracer ligne", (10,10))
            button_drawRectangle = wx.Button(panel, -2, "Placer masque", (10,50))
            button_highlight = wx.Button(panel, -3, "Surligner", (10,90))
            button_close = wx.Button(panel, -4, "Fermer Application", (10,130))
            #evenements / Events
            self.Bind(wx.EVT_BUTTON, self.EventPosition, button_drawLine)
            self.Bind(wx.EVT_BUTTON, self.EventPosition, button_highlight)
            self.Bind(wx.EVT_BUTTON, self.EventPosition, button_drawRectangle)
            self.Bind(wx.EVT_BUTTON, self.GetParent().OnCloseWindow, button_close)
     
        def OnCloseWindow(self, evt):
            self.Destroy()
     
        def EventPosition(self, evt):
            self.btn = evt.GetEventObject()
            print "event position"
            #Focus sur la fenetre transparente et d�tection des mouvements de la souris 
            #Focus on the transparent window and detection of mouse movements
            self.GetParent().Raise()
            self.GetParent().cnv.Bind(wx.EVT_LEFT_DOWN, self.EventMotion)
     
        def EventMotion(self, evt):
            print "event motion"
            #sauvegarde de la position du clique / #save the position of clicks
            self.posx = evt.GetX() 
            self.posy = evt.GetY()
            self.GetParent().Refresh ()
            self.GetParent().cnv.Bind(wx.EVT_MOTION, self.Position)
     
        def Position(self, evt):
            #if mouse leftbutton is down
            if wx.GetMouseState().LeftDown():
                print "position"
                #Assignation de la position du curseur/ #Detection, arrest and send the cursor position
                self.posx2 = evt.GetX() 
                self.posy2 = evt.GetY()
                self.GetParent().Refresh ()
                self.GetParent().cnv.Bind(wx.EVT_PAINT, self.Paint)
     
        def Paint(self, evt):
            print "Paint"
            #creation de la toile / creation of the painting canvas
            self.GetParent().dc = wx.PaintDC(self.GetParent().cnv)  
            if self.btn.GetLabelText()=="Tracer ligne":
                self.drawLine(self.dc)
            if self.btn.GetLabelText()=="Placer masque":
                self.drawMask(self.dc)
            if self.btn.GetLabelText()=="Surligner":    
                self.highlight(self.dc)
     
        def drawLine(self, dc):     
            print "i drawing line"
            self.GetParent().dc.SetPen(wx.Pen('black', 2))
            #self.GetParent().dc.SetBrush(wx.Brush(wx.Color(0, 0, 0), wx.ALPHA_OPAQUE)) 
            self.GetParent().dc.DrawLine(self.posx2, self.posy2,self.posx,self.posy) 
     
        def drawMask(self, dc):
            print "i drawing mask"
            #self.GetParent().dc.SetPen(wx.Pen('red', 2)) 
            # le alpha_opaque n'a pas l'air d'etre pris en compte. Le masque devrait cacher ce qu'il y a en dessous
            #the alpha_opaque did not seem to be taken into account. The mask should hide what he was below
            self.GetParent().dc.SetBrush(wx.Brush(wx.Color(0, 0, 0), wx.ALPHA_OPAQUE)) 
            self.GetParent().dc.DrawRectangle(self.posx, self.posy, self.posx2 - self.posx, self.posy2- self.posy) 
     
        def highlight (self, dc):
            print "i drawing highlight"    
            self.GetParent().dc.SetBrush(wx.Brush(wx.Color(150, 250, 150)))
            self.GetParent().dc.DrawRectangle(self.posx, self.posy, self.posx2 - self.posx, self.posy2 - self.posy)
     
    class monApp (wx.App):
        def OnInit(self):
            frm = window(None, -1, 'transparent')
            frm.Show(True)
            # pour l'instant j'utilise une semi transparence sinon je ne vois pas les dessins.
            #for now I use a semi transparent or I do not see the drawings.
            frm.SetTransparent(155)
            frmTool = windowTool(frm, -2, 'outil')
            frmTool.Show(True)
            return True
     
    if __name__ == "__main__":
        app = monApp()
        app.MainLoop()
    Merci pour l'intérêt a mon problème

  4. #4
    Expert confirmé Avatar de PauseKawa
    Homme Profil pro
    Technicien Help Desk, maintenance, réseau, système et +
    Inscrit en
    Juin 2006
    Messages
    2 725
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Technicien Help Desk, maintenance, réseau, système et +
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 725
    Points : 4 005
    Points
    4 005
    Par défaut
    Bonjour,

    Je n'avais pas vu ce sujet.

    Pourquoi jouer sur la transparence ? Une copie d'écran ne fait pas l'affaire ?
    Un exemple (en tk, désolé je ne connais pas assez wx)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    import sys
    import os
    import Tkinter as Tk
    import Image, ImageTk
     
    class ScreenCap(object):
        def __init__(self):
            if sys.platform == 'linux2':
                self.grab = self._GarbLinux
            elif sys.platform == 'win32':
                import Image, ImageGrab
                self.grab = self._GrabWin
            elif sys.platform == 'darwin':
                self.grab = self._GrabMac
            else:
                pass # TODO
     
        def _FicNormalyze(self, name):
            if name:
                if os.path.basename(name) == name:
                    _fichier = os.path.join(os.environ['HOME'], name)
                else:
                    _fichier = name
            else:
                _fichier = os.path.join(os.environ['HOME'], 'scrcap.jpg')
            return _fichier
     
        def _GarbLinux(self, name=None):
            _fichier = self._FicNormalyze(name)
            _commande = "import -silent -window root " + _fichier
            os.system(_commande)
            return _fichier
     
        def _GrabWin(self, name=None):
            _fichier = self._FicNormalyze(name)
            ImageGrab.grab().save(_fichier, "JPEG")
            return _fichier
     
        def _GrabMac(self, name=None): # A faire
            _fichier = self._FicNormalyze(name)
            _commande = "screencapture -m -x -t jpg " + _fichier
            os.system(_commande)
            return _fichier
     
    class MainMenu(object):
        def __init__(self, master, bg=None, fg=None, activefg=None):
            self.master = master
            self.dicitem = {}
            self.dicctrl = {}
            if bg:
                self.bg = bg
            else:
                self.bg = 'gray'
            if fg:
                self.fg = fg
            else:
                self.fg = 'black'
            if activefg:
                self.activefg = activefg
            else:
                self.activefg = 'blue'
     
        def rootquit(self, event):
            self.master.quit()
     
        def positionne(self, widget, x, y):
            widget.update()
            reqw = widget.winfo_reqwidth()
            reqh = widget.winfo_reqheight()
            winw = widget.winfo_screenwidth()
            winh = widget.winfo_screenheight()
            posx = x - (reqw/2)
            if x + reqw/2 > winw:
                posx =  posx - ((x + reqw/2) - winw)
            elif x - reqw/2 < 0:
                posx =  0
            posy = y - reqh/2
            if y + reqh/2 > winh:
                posy =  posy - ((y + reqh/2) - winh)
            elif y - reqh/2 < 0:
                posy =  0
            widget.geometry("%dx%d+%d+%d" % (reqw, reqh, posx, posy))
     
        def affichemenu(self, event=None):
            for widget in (widget for widget in self.master.winfo_children()
                if isinstance(widget, Tk.Toplevel)):
                    return
            position = self.master.winfo_pointerxy()
            x, y = position[0], position[1]
            self.topmenu = Tk.Toplevel(self.master, bg=self.bg)
            self.topmenu.withdraw()
            ctnfrm = Tk.Frame(self.topmenu, bd=1, relief=Tk.RIDGE,
                bg=self.bg)
            Tk.Label(ctnfrm, text='MENU', fg=self.fg,
                bg=self.bg).pack(padx=3, pady=2)
            Tk.Frame(ctnfrm, height=2, bd=1, relief=Tk.SUNKEN,
                bg=self.bg).pack(fill=Tk.X, padx=5, pady=5)
            lab = {}
            tri = []
            for cle in self.dicitem.keys():
                tri.append(cle)
            tri.sort()
            for elems in tri:
                cmd = self.dicitem[elems]
                lab[elems] = Tk.Label(ctnfrm, text=elems, fg=self.fg,
                   bg=self.bg)
                lab[elems].pack(padx=3, pady=2)
                lab[elems].bind("<Button-1>", cmd)
                self.focusctrl(lab[elems])
            tri = []
            for cle in self.dicctrl.keys():
                tri.append(cle)
            tri.sort()
            for elems in tri:
                cmd = self.dicctrl[elems]
                lab[elems] = Tk.Label(ctnfrm, text=elems, fg=self.fg,
                   bg=self.bg)
                lab[elems].pack(padx=3, pady=2)
                lab[elems].bind("<Button-1>", cmd)
                self.focusctrl(lab[elems])
            labelquit = Tk.Label(ctnfrm, text='Quitter', fg=self.fg,
                bg=self.bg)
            labelquit.pack(padx=3, pady=2)
            self.focusctrl(labelquit)
            ctnfrm.pack(padx=3, pady=2)
            labelquit.bind("<Button-1>", self.rootquit)
            self.positionne(self.topmenu, x, y)
            self.topmenu.overrideredirect(True)
            self.topmenu.bind("<Button-1>", self.cacher)
            self.topmenu.deiconify()
     
        def cacher(self, event=None):
            self.topmenu.destroy()
     
        def focusctrl(self, widget):
            widget.bind("<Leave>", lambda event=None: self.notactive(
                widget))
            widget.bind("<Enter>", lambda event=None: self.isactive(widget))
     
        def isactive(self, widget):
            widget['fg']=self.activefg
            widget.update()
     
        def notactive(self, widget):
            widget['fg']=self.fg
            widget.update()
     
        def additem(self, name, cb):
            self.dicitem[name] = cb
     
        def delitem(self, name):
            del self.dicitem[name]
     
        def addctrl(self, name, cb):
            self.dicctrl[name] = cb
     
        def delctrl(self, name):
            del self.dicctrl[name]
     
    class interface(Tk.Tk):
        def __init__(self, parent, c='red', w=3):
            Tk.Tk.__init__(self, parent)
            self.pts = []
            self.totrace = None
            self.color = c
            self.width = w
            self.sccap = ScreenCap()
            img = self.sccap.grab(name='scrcap.jpg')
            fcapture = Image.open(img)
            self.photo = ImageTk.PhotoImage(fcapture)
            self.c = Tk.Canvas(self, width=self.winfo_screenwidth(),
                height=self.winfo_screenheight())
            self.c.create_image(0, 0, image=self.photo, anchor=Tk.NW)
            self.update()
            self.c.pack(fill=Tk.BOTH)
            mainmenu = MainMenu(self, bg='white', fg='black',
                activefg='blue')
            mainmenu.additem('Ligne',
                lambda event=None: self.trace('ligne'))
            mainmenu.additem('Rectangle',
                lambda event=None: self.trace('rectangle'))
            mainmenu.additem('Ovale',
                lambda event=None: self.trace('ovale'))
            mainmenu.additem('Texte',
                lambda event=None: self.trace('texte'))
            mainmenu.addctrl('Annuler',
                lambda event=None: self.trace('delete'))
            mainmenu.addctrl('Sauvegarder', self.sauve)
            mainmenu.addctrl('Configurer', self.config)
            self.bind('<Escape>', self.intercepte)
            self.bind('<3>', mainmenu.affichemenu)
            self.bind('<1>', self.addlist)
            self.wm_attributes('-fullscreen', 1) #'-topmost', 1, 
     
        def addlist(self, event):
            self.pts.append((event.x, event.y))
            if self.totrace == 'delete' and len(self.pts) == 1:
                item = self.c.find_closest(event.x, event.y)
                if item != (1,):
                    self.c.delete(item)
                self.clear()
            elif self.totrace == 'ligne' and len(self.pts) == 2:
                self.c.create_line(self.pts[0][0], self.pts[0][1],
                    self.pts[1][0], self.pts[1][1], fill=self.color,
                    width=self.width)
                self.clear()
            elif self.totrace == 'rectangle' and len(self.pts) == 2:
                self.c.create_rectangle(self.pts[0][0], self.pts[0][1],
                    self.pts[1][0], self.pts[1][1], outline=self.color,
                    width=self.width)
                self.clear()
            elif self.totrace == 'ovale' and len(self.pts) == 2:
                self.c.create_oval(self.pts[0][0], self.pts[0][1],
                    self.pts[1][0], self.pts[1][1], outline=self.color,
                    width=self.width)
                self.clear()
            # etc...
     
        def clear(self):
            self.totrace = None
            del(self.pts[:])
     
        def intercepte(self, event=None):
            self.quit()
     
        def trace(self, obj):
            del(self.pts[:])
            self.totrace = obj
     
        def sauve(self, event=None):
            # A faire. Utiliser le postscript du Canvas
            pass
     
        def config(self, event=None):
            # A faire. Un Toplevel dans le style de MainMenu pour modifier self.color etc...
            pass
     
    if __name__ == "__main__":
        app = interface(None)
        app.mainloop()
    Il vous suffit de créer une fenêtre plein écran et de réutiliser ScreenCap.

    @+
    Merci d'utiliser le forum pour les questions techniques.

  5. #5
    Membre à l'essai
    Homme Profil pro
    technicien polyvalent debutant developpeur web / maintenance
    Inscrit en
    Octobre 2009
    Messages
    24
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France

    Informations professionnelles :
    Activité : technicien polyvalent debutant developpeur web / maintenance

    Informations forums :
    Inscription : Octobre 2009
    Messages : 24
    Points : 14
    Points
    14
    Par défaut
    La transparence car l'idée serait de pouvoir l'utiliser par exemple sur un diaporama qui défile automatiquement ou une vidéo.

    Pour que l'on soit pas obliger de réduire et agrandir la fenêtre a chaque fois que l'écran change.

    Et puis bon j'ai pas envie de réinventé la roue.
    Gribouill_i fonctionne très bien avec le système de sreenshot.

  6. #6
    Expert confirmé Avatar de PauseKawa
    Homme Profil pro
    Technicien Help Desk, maintenance, réseau, système et +
    Inscrit en
    Juin 2006
    Messages
    2 725
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Technicien Help Desk, maintenance, réseau, système et +
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 725
    Points : 4 005
    Points
    4 005
    Par défaut
    Bonjour,

    Ok pour la transparence.
    Mais cela me semble difficile car dépendant du wm. Par exemple sur mon ordi perso (Ubuntu 11.04 sans 3d) SetTransparent ne fonctionne pas (Idem pour le setWindowOpacity PyQT ou le set_opacity PyGTK, ne parlons pas du wm_attributes alpha sous Tkinter que ne fonction que sous Windows)...

    @+

    Ps: Le code que j'ai donner ne fonctionne pas . Je sais que c'est du Tk mais en voici la correction.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310
    311
    312
    313
    314
    315
    316
    317
    318
    319
    320
    321
    322
    323
    324
    325
    326
    327
    #!/usr/bin/env python
    # -*- coding: ISO8859-1 -*-
    #
    # whiteboard.py
    import sys
    import os
    import Tkinter as Tk
    import Image, ImageTk
    import tkFileDialog
     
     
    class ScreenCap(object):
        def __init__(self):
            if sys.platform == 'linux2':
                self.grab = self._GarbLinux
            elif sys.platform == 'win32':
                import Image, ImageGrab
                self.grab = self._GrabWin
            elif sys.platform == 'darwin':
                self.grab = self._GrabMac
            else:
                pass # TODO
            self._currentf = None
     
        def _FicNormalyze(self, name):
            if name:
                if os.path.basename(name) == name:
                    _fichier = os.path.join(os.path.expanduser('~'), name)
                else:
                    _fichier = name
            else:
                _fichier = os.path.join(os.path.expanduser('~'), 'scrcap.jpg')
            self._currentf = _fichier
            return _fichier
     
        def _GarbLinux(self, name=None):
            _fichier = self._FicNormalyze(name)
            _commande = "import -silent -window root " + _fichier
            os.system(_commande)
            return _fichier
     
        def _GrabWin(self, name=None):
            import ImageGrab
            _fichier = self._FicNormalyze(name)
            ImageGrab.grab().save(_fichier, "JPEG")
            return _fichier
     
        def _GrabMac(self, name=None): # A faire
            _fichier = self._FicNormalyze(name)
            _commande = "screencapture -m -x -t jpg " + _fichier
            os.system(_commande)
            return _fichier
     
        def delete(self):
            if os.path.isfile(self._currentf):
                os.remove(self._currentf)
     
     
    class MainMenu(object):
        def __init__(self, master, bg=None, fg=None, activefg=None):
            self.master = master
            self.dicitem = {}
            self.dicctrl = {}
            if bg:
                self.bg = bg
            else:
                self.bg = 'gray'
            if fg:
                self.fg = fg
            else:
                self.fg = 'black'
            if activefg:
                self.activefg = activefg
            else:
                self.activefg = 'blue'
     
        def rootquit(self, event):
            self.master.quit()
     
        def positionne(self, widget, x, y):
            widget.update()
            reqw = widget.winfo_reqwidth()
            reqh = widget.winfo_reqheight()
            winw = widget.winfo_screenwidth()
            winh = widget.winfo_screenheight()
            posx = x - (reqw/2)
            if x + reqw/2 > winw:
                posx =  posx - ((x + reqw/2) - winw)
            elif x - reqw/2 < 0:
                posx =  0
            posy = y - reqh/2
            if y + reqh/2 > winh:
                posy =  posy - ((y + reqh/2) - winh)
            elif y - reqh/2 < 0:
                posy =  0
            widget.geometry("%dx%d+%d+%d" % (reqw, reqh, posx, posy))
     
        def affichemenu(self, event=None):
            for widget in (widget for widget in self.master.winfo_children()
                if isinstance(widget, Tk.Toplevel)):
                    return
            position = self.master.winfo_pointerxy()
            x, y = position[0], position[1]
            self.topmenu = Tk.Toplevel(self.master, bg=self.bg)
            self.topmenu.withdraw()
            ctnfrm = Tk.Frame(self.topmenu, bd=1, relief=Tk.RIDGE,
                bg=self.bg)
            Tk.Label(ctnfrm, text='MENU', fg=self.fg,
                bg=self.bg).pack(padx=3, pady=2)
            Tk.Frame(ctnfrm, height=2, bd=1, relief=Tk.SUNKEN,
                bg=self.bg).pack(fill=Tk.X, padx=5, pady=5)
            lab = {}
            tri = []
            for cle in self.dicitem.keys():
                tri.append(cle)
            tri.sort()
            for elems in tri:
                cmd = self.dicitem[elems]
                lab[elems] = Tk.Label(ctnfrm, text=elems, fg=self.fg,
                   bg=self.bg)
                lab[elems].pack(padx=3, pady=2)
                lab[elems].bind("<1>", cmd)
                self.focusctrl(lab[elems])
            tri = []
            for cle in self.dicctrl.keys():
                tri.append(cle)
            tri.sort()
            for elems in tri:
                cmd = self.dicctrl[elems]
                lab[elems] = Tk.Label(ctnfrm, text=elems, fg=self.fg,
                   bg=self.bg)
                lab[elems].pack(padx=3, pady=2)
                lab[elems].bind("<1>", cmd)
                self.focusctrl(lab[elems])
            labelquit = Tk.Label(ctnfrm, text='Quitter', fg=self.fg,
                bg=self.bg)
            labelquit.pack(padx=3, pady=2)
            self.focusctrl(labelquit)
            ctnfrm.pack(padx=3, pady=2)
            labelquit.bind("<1>", self.rootquit)
            self.positionne(self.topmenu, x, y)
            self.topmenu.overrideredirect(True)
            self.topmenu.bind("<1>", self.cacher)
            self.topmenu.deiconify()
     
        def cacher(self, event=None):
            self.topmenu.destroy()
     
        def focusctrl(self, widget):
            widget.bind("<Leave>", lambda event=None: self.notactive(
                widget))
            widget.bind("<Enter>", lambda event=None: self.isactive(widget))
     
        def isactive(self, widget):
            widget['fg']=self.activefg
            widget.update()
     
        def notactive(self, widget):
            widget['fg']=self.fg
            widget.update()
     
        def additem(self, name, cb):
            self.dicitem[name] = cb
     
        def delitem(self, name):
            del self.dicitem[name]
     
        def addctrl(self, name, cb):
            self.dicctrl[name] = cb
     
        def delctrl(self, name):
            del self.dicctrl[name]
     
     
    class interface(Tk.Tk):
        def __init__(self, parent):
            Tk.Tk.__init__(self, parent)
            self.title('Whiteboard')
            self.pts = []
            self.totrace = None
            self.color = Tk.StringVar()
            self.color.set('red')
            self.width = Tk.IntVar()
            self.width.set(3)
            self.sccap = ScreenCap()
            img = self.sccap.grab(name='scrcap.jpg')
            fcapture = Image.open(img)
            self.photo = ImageTk.PhotoImage(fcapture)
            self.c = Tk.Canvas(self, width=self.winfo_screenwidth(),
                height=self.winfo_screenheight())
            self.c.create_image(0, 0, image=self.photo, anchor=Tk.NW)
            self.update()
            self.sccap.delete()
            self.c.pack(fill=Tk.BOTH)
            mainmenu = MainMenu(self, bg='white', fg='black',
                activefg='blue')
            mainmenu.additem('Ligne',
                lambda event=None: self.trace('ligne'))
            mainmenu.additem('Rectangle',
                lambda event=None: self.trace('rectangle'))
            mainmenu.additem('Ovale',
                lambda event=None: self.trace('ovale'))
            mainmenu.additem('Texte',
                lambda event=None: self.trace('texte'))
            mainmenu.addctrl('Effacer',
                lambda event=None: self.trace('delete'))
            mainmenu.addctrl('Sauvegarder', lambda event=None: self.after(2,
                self.sauve))
            mainmenu.addctrl('Configurer', self.config)
            mainmenu.addctrl(u"Réduire", self.reduire)
            self.bind('<Escape>', self.intercepte)
            self.bind('<3>', mainmenu.affichemenu)
            self.bind('<1>', self.addlist)
            self.wm_attributes('-fullscreen', 1)
            self.iconify()
     
        def reduire(self, event=None):
            self.iconify()
     
        def addlist(self, event):
            self.pts.append((event.x, event.y))
            if self.totrace == 'delete':
                item = self.c.find_closest(event.x, event.y)
                if item != (1,):
                    self.c.delete(item)
                self.clear()
            elif self.totrace == 'ligne' and len(self.pts) == 2:
                self.c.create_line(self.pts[0][0], self.pts[0][1],
                    self.pts[1][0], self.pts[1][1], fill=self.color.get(),
                    width=self.width.get())
                self.clear()
            elif self.totrace == 'rectangle' and len(self.pts) == 2:
                self.c.create_rectangle(self.pts[0][0], self.pts[0][1],
                    self.pts[1][0], self.pts[1][1], outline=self.color.get(),
                    width=self.width.get())
                self.clear()
            elif self.totrace == 'ovale' and len(self.pts) == 2:
                self.c.create_oval(self.pts[0][0], self.pts[0][1],
                    self.pts[1][0], self.pts[1][1], outline=self.color.get(),
                    width=self.width.get())
                self.clear()
            elif self.totrace == 'texte':
                for widget in (widget for widget in self.winfo_children()
                    if isinstance(widget, Tk.Toplevel)):
                        widget.destroy()
                self.menutext = Tk.Toplevel()
                self.menutext.title("Ajout d'un texte")
                self.textentry = Tk.Entry(self.menutext, width=80)
                self.textentry.grid(row=0, column=0, columnspan=2, padx=5,
                    pady=5)
                self.textentry.focus_set()
                self.btvalid = Tk.Button(self.menutext, fg='green', text='Valider',
                    command=self.createtxt)
                self.btvalid.grid(row=1, column=0, padx=5, pady=5)
                self.btquit = Tk.Button(self.menutext, fg='red',
                    text='Annuler', command=lambda: self.delwidget(self.menutext))
                self.btquit.grid(row=1, column=1, padx=5, pady=5)
                self.menutext.update()
                self.menutext.geometry("%dx%d+%d+%d" %
                    (self.menutext.winfo_reqwidth(),
                    self.menutext.winfo_reqheight(), event.x, event.y))
                self.menutext.bind('<Escape>', lambda event=None:
                    self.delwidget(self.menutext))
     
        def delwidget(self, widget):
            widget.destroy()
            self.clear()
     
        def createtxt(self):
            self.c.create_text(self.pts[0][0], self.pts[0][1],
                fill=self.color.get(), text=self.textentry.get())
            self.delwidget(self.menutext)
     
        def clear(self):
            self.totrace = None
            del(self.pts[:])
     
        def intercepte(self, event=None):
            self.quit()
     
        def trace(self, obj):
            del(self.pts[:])
            self.totrace = obj
     
        def sauve(self, event=None):
            img = self.sccap.grab(name='scrcap.jpg')
            filetosave = tkFileDialog.asksaveasfilename(
                initialdir=os.path.expanduser('~'), title="Enregistrement",
                filetypes=[('JPEG / JFIF','*.jpg')], defaultextension='jpg',
                initialfile='capture.jpg')
            if filetosave:
                if os.path.isfile(filetosave):
                    os.remove(filetosave)
                os.rename(img, filetosave)
            else:
                self.sccap.delete()
     
        def config(self, event=None):
            for widget in (widget for widget in self.winfo_children()
                if isinstance(widget, Tk.Toplevel)):
                    widget.destroy()
            self.menuconfig = Tk.Toplevel()
            self.menuconfig.title("Configuration")
            Tk.Label(self.menuconfig, text='Epaisseur de ligne').grid(row=0,
                column=0, padx=5, pady=5)
            for i in range(0, 11):
                Tk.Radiobutton(self.menuconfig, text=str(i), variable=self.width,
                    value=i).grid(row=1+i, column=0, padx=5, pady=5)
            Tk.Label(self.menuconfig, text='Couleur').grid(row=0, column=2,
                padx=5, pady=5)
            col = 0
            for c, n in [('Noir', 'black'), ('Blanc', 'white'), ('Rouge', 'red'),
                ('Vert', 'green'), ('Bleu', 'blue'), ('Jaune', 'yellow'),
                ('Violet', 'purple'), ('Orange', 'orange'), ('Gris', 'gray'),
                ('Rose', 'pink'), ('Marron', 'brown'),]:
                Tk.Radiobutton(self.menuconfig, text=c, variable=self.color,
                    value=n).grid(row=col+1, column=2, padx=5, pady=5, sticky=Tk.W)
                col += 1
            self.btquit = Tk.Button(self.menuconfig, fg='green',
                text='Quitter', command=lambda: self.delwidget(self.menuconfig))
            self.btquit.grid(row=14, column=1, pady=10)
            self.menuconfig.bind('<Escape>', lambda event=None:
                self.delwidget(self.menuconfig))
     
    if __name__ == "__main__":
        app = interface(None)
        app.mainloop()
    Partie Mac non testée (sauf si je tombe sur 'gentil donateur' )

    @++

    Ps: Désolé pour le temps d'édit mais je suis passer par un éditeur qui m'as mis des CRLF en fin de ligne (Geany suite à la mise à jour de mon système...) et j'avais des sauts de ligne dans tout le code.
    Merci d'utiliser le forum pour les questions techniques.

  7. #7
    Membre à l'essai
    Homme Profil pro
    technicien polyvalent debutant developpeur web / maintenance
    Inscrit en
    Octobre 2009
    Messages
    24
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France

    Informations professionnelles :
    Activité : technicien polyvalent debutant developpeur web / maintenance

    Informations forums :
    Inscription : Octobre 2009
    Messages : 24
    Points : 14
    Points
    14
    Par défaut
    Merci.

    Après pour l'instant la portabilité n'est pas une nécessite. C'est une application que je présenterai éventuellement pour un examen bts.

    Merci. J'installe tk et je vois ca.

  8. #8
    Membre à l'essai
    Homme Profil pro
    technicien polyvalent debutant developpeur web / maintenance
    Inscrit en
    Octobre 2009
    Messages
    24
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France

    Informations professionnelles :
    Activité : technicien polyvalent debutant developpeur web / maintenance

    Informations forums :
    Inscription : Octobre 2009
    Messages : 24
    Points : 14
    Points
    14
    Par défaut
    Bon alors je viens de" tester il ne me trouve pas le module

    import Image, ImageTk

    Comment faire?

    Merci beaucoup, le temps presse

  9. #9
    Expert confirmé Avatar de PauseKawa
    Homme Profil pro
    Technicien Help Desk, maintenance, réseau, système et +
    Inscrit en
    Juin 2006
    Messages
    2 725
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Technicien Help Desk, maintenance, réseau, système et +
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 725
    Points : 4 005
    Points
    4 005
    Par défaut
    Bonjour,

    Si tu utilise Gribouill_i c'est que tu dois être sous Windows et s'il n'y a pas d'erreur sur l'import de Tkinter juste au dessus tu dois être en Python 2.x.
    Tu trouveras ce qu'il te manque ici. Télécharge la version de PIL 1.1.7 qui correspond à ta version de Python et installe la.

    @+
    Merci d'utiliser le forum pour les questions techniques.

  10. #10
    Membre à l'essai
    Homme Profil pro
    technicien polyvalent debutant developpeur web / maintenance
    Inscrit en
    Octobre 2009
    Messages
    24
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France

    Informations professionnelles :
    Activité : technicien polyvalent debutant developpeur web / maintenance

    Informations forums :
    Inscription : Octobre 2009
    Messages : 24
    Points : 14
    Points
    14
    Par défaut
    J'ai jamais dis que j'utilisai gribouill_i et je suis sous ubuntu.

    L'install de Tkinter c'est dérouler correctement

  11. #11
    Expert confirmé Avatar de PauseKawa
    Homme Profil pro
    Technicien Help Desk, maintenance, réseau, système et +
    Inscrit en
    Juin 2006
    Messages
    2 725
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Technicien Help Desk, maintenance, réseau, système et +
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 725
    Points : 4 005
    Points
    4 005
    Par défaut
    Dans ce cas le deb c'est python-imaging-tk.
    Merci d'utiliser le forum pour les questions techniques.

  12. #12
    Membre à l'essai
    Homme Profil pro
    technicien polyvalent debutant developpeur web / maintenance
    Inscrit en
    Octobre 2009
    Messages
    24
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France

    Informations professionnelles :
    Activité : technicien polyvalent debutant developpeur web / maintenance

    Informations forums :
    Inscription : Octobre 2009
    Messages : 24
    Points : 14
    Points
    14
    Par défaut
    Merci beaucoup je test ca tout a l'heure et vous tiens au courant

  13. #13
    Expert confirmé Avatar de PauseKawa
    Homme Profil pro
    Technicien Help Desk, maintenance, réseau, système et +
    Inscrit en
    Juin 2006
    Messages
    2 725
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Technicien Help Desk, maintenance, réseau, système et +
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 725
    Points : 4 005
    Points
    4 005
    Par défaut
    Oups : python-imaging et python-imaging-tk (via synaptic ou sudo apt-get install)
    Merci d'utiliser le forum pour les questions techniques.

  14. #14
    Membre à l'essai
    Homme Profil pro
    technicien polyvalent debutant developpeur web / maintenance
    Inscrit en
    Octobre 2009
    Messages
    24
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France

    Informations professionnelles :
    Activité : technicien polyvalent debutant developpeur web / maintenance

    Informations forums :
    Inscription : Octobre 2009
    Messages : 24
    Points : 14
    Points
    14
    Par défaut
    Merci ca se compile correctement.

    J'aimerai vous déranger encore pour un petit souci.Le débogueur sur eclipse me retourne ce message d'erreur:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
     
    pydev debugger: warning: psyco not available for speedups (the debugger will still work correctly, but a bit slower)
    pydev debugger: starting
    sh: import: not found
    Traceback (most recent call last):
      File "/home/caz/.eclipse/org.eclipse.platform_3.5.0_155965261/plugins/org.python.pydev.debug_1.6.5.2011020317/pysrc/pydevd.py", line 1133, in <module>
        debugger.run(setup['file'], None, None)
      File "/home/caz/.eclipse/org.eclipse.platform_3.5.0_155965261/plugins/org.python.pydev.debug_1.6.5.2011020317/pysrc/pydevd.py", line 918, in run
        execfile(file, globals, locals) #execute the script
      File "/home/caz/Bureau/screenPresentTk.py", line 317, in <module>
        app = interface(None)
      File "/home/caz/Bureau/screenPresentTk.py", line 186, in __init__
        fcapture = Image.open(img)
      File "/usr/lib/python2.6/dist-packages/PIL/Image.py", line 1952, in open
        fp = __builtin__.open(fp, "rb")
    IOError: [Errno 2] No such file or directory: '/home/caz/scrcap.jpg'

    Je ne comprends pas bien ce qu'il signifie et donc comment le corriger.
    J'ai l'impression qu'il n'arrive pas a créer le screenShot et qu'il manque ensuite.
    Désolé je suis un débutant pure et dur.

    Encore merci pour toute aide



    EDIT: J'ai trouver je n'avais pas installer le programme import sur mon linux

  15. #15
    Membre à l'essai
    Homme Profil pro
    technicien polyvalent debutant developpeur web / maintenance
    Inscrit en
    Octobre 2009
    Messages
    24
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France

    Informations professionnelles :
    Activité : technicien polyvalent debutant developpeur web / maintenance

    Informations forums :
    Inscription : Octobre 2009
    Messages : 24
    Points : 14
    Points
    14
    Par défaut
    Je suis en plein dans ton code et je ne comprends pas tout. J'ai jamais fait de tkinter avant.

    Ça serai cool si tu pouvais me le commenter un peu stp.
    Vite fait et si tu en as le temps.

    Merci beaucoup

  16. #16
    Expert confirmé Avatar de PauseKawa
    Homme Profil pro
    Technicien Help Desk, maintenance, réseau, système et +
    Inscrit en
    Juin 2006
    Messages
    2 725
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Technicien Help Desk, maintenance, réseau, système et +
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 725
    Points : 4 005
    Points
    4 005
    Par défaut
    Bonjour,

    Pas trop le temps ce matin mais voici déjà quelques notes

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310
    311
    312
    313
    314
    315
    316
    317
    318
    319
    320
    321
    322
    323
    324
    325
    326
    327
    328
    329
    330
    331
    332
    333
    334
    335
    336
    337
    338
    339
    340
    341
    342
    343
    344
    345
    346
    347
    348
    349
    350
    351
    352
    353
    354
    355
    356
    357
    358
    359
    360
    361
    362
    363
    364
    365
    366
    367
    368
    369
    370
    371
    372
    373
    374
    375
    376
    377
    378
    379
    380
    381
    382
    383
    384
    385
    386
    387
    388
    389
    390
    391
    392
    393
    394
    395
    396
    397
    398
    399
    400
    401
    402
    403
    404
    405
    406
    #!/usr/bin/env python
    # -*- coding: ISO8859-1 -*-
    #
    #
    """whiteboard.py
    Utilitaire de capture d'écran multiplateforme sous Python 2.x.
    Prérequis généraux : Tkinter et PIL
    Prérequis Linux : ImageMagick
    Prérequis Mac : screencapture
    Version de test suite à ce sujet :
    http://www.developpez.net/forums/d1058928/autres-langages/python-zope/gui/wxpython/aide-application/
    """
     
    import sys
    import os
    import Tkinter as Tk
    import Image, ImageTk
    import tkFileDialog
     
    # Classe de capture d'image
    class ScreenCap(object):
        def __init__(self):
            # Test de l'os.
            if sys.platform == 'linux2':
                self.grab = self._GarbLinux
            elif sys.platform == 'win32':
                import Image, ImageGrab
                self.grab = self._GrabWin
            elif sys.platform == 'darwin':
                self.grab = self._GrabMac
            else:
                pass # TODO
            self._currentf = None
     
        def _FicNormalyze(self, name):
            """Internal Function"""
            # Génération du chemin du fichier image. Par défaut dans le
            # Répertoire de l'utilisateur pour éviter tout problème
            # de droits.
            if name:
                if os.path.basename(name) == name:
                    _fichier = os.path.join(os.path.expanduser('~'), name)
                else:
                    _fichier = name
            else:
                # Nom par défaut
                _fichier = os.path.join(os.path.expanduser('~'), 'scrcap.jpg')
            self._currentf = _fichier
            return _fichier
     
        # Fonction de capture Linux
        def _GarbLinux(self, name=None):
            _fichier = self._FicNormalyze(name)
            _commande = "import -silent -window root " + _fichier
            os.system(_commande)
            return _fichier
     
        # Fonction de capture Windows.
        # ImageGrab de PIL ne fonctionne que sous Windows
        def _GrabWin(self, name=None):
            import ImageGrab
            _fichier = self._FicNormalyze(name)
            ImageGrab.grab().save(_fichier, "JPEG")
            return _fichier
     
        # Fonction de capture Mac.
        def _GrabMac(self, name=None): # A faire
            _fichier = self._FicNormalyze(name)
            _commande = "screencapture -m -x -t jpg " + _fichier
            os.system(_commande)
            return _fichier
     
        def delete(self):
            # Pour détruire le fichier temporaire 
            if os.path.isfile(self._currentf):
                os.remove(self._currentf)
     
    # Classe pour créer le menu principal.
    class MainMenu(object):
        def __init__(self, master, bg=None, fg=None, activefg=None):
            # Master qui vas nous donner la fenetre Tk à utiliser.
            self.master = master
            # Dicos des lignes du menu. {'titre': fonction dans master}.
            self.dicitem = {}
            self.dicctrl = {}
            if bg:
                self.bg = bg
            else:
                self.bg = 'gray'
            if fg:
                self.fg = fg
            else:
                self.fg = 'black'
            if activefg:
                self.activefg = activefg
            else:
                self.activefg = 'blue'
     
        def rootquit(self, event):
            # Tout simplement pour fermer le programme à partir du menu.
            self.master.quit()
     
        # Fonction de placement du menu. Réutilisable puisque
        # l'on donne 'widget'.
        # Remplacable par une classe pour etre plus général.
        def positionne(self, widget, x, y):
            # Mise à jour 
            widget.update()
            # Informations de géométrie sur le widget.
            reqw = widget.winfo_reqwidth()
            reqh = widget.winfo_reqheight()
            winw = widget.winfo_screenwidth()
            winh = widget.winfo_screenheight()
            posx = x - (reqw/2)
            if x + reqw/2 > winw:
                posx =  posx - ((x + reqw/2) - winw)
            elif x - reqw/2 < 0:
                posx =  0
            posy = y - reqh/2
            if y + reqh/2 > winh:
                posy =  posy - ((y + reqh/2) - winh)
            elif y - reqh/2 < 0:
                posy =  0
            # Positionement du widget
            widget.geometry("%dx%d+%d+%d" % (reqw, reqh, posx, posy))
     
        # fonction d'affichage du menu
        def affichemenu(self, event=None):
            # On détruit les Toplevel existants.
            for widget in (widget for widget in self.master.winfo_children()
                if isinstance(widget, Tk.Toplevel)):
                    return
            # On récupère la position de la souris
            position = self.master.winfo_pointerxy()
            x, y = position[0], position[1]
            # Création du Toplevel qui sert de menu
            self.topmenu = Tk.Toplevel(self.master, bg=self.bg)
            # On le réduit
            self.topmenu.withdraw()
            ctnfrm = Tk.Frame(self.topmenu, bd=1, relief=Tk.RIDGE,
                bg=self.bg)
            Tk.Label(ctnfrm, text='MENU', fg=self.fg,
                bg=self.bg).pack(padx=3, pady=2)
            Tk.Frame(ctnfrm, height=2, bd=1, relief=Tk.SUNKEN,
                bg=self.bg).pack(fill=Tk.X, padx=5, pady=5)
            # listes vides pour créer les Labels 
            lab = {}
            tri = []
            # Création des Labels suivant les dicos
            for cle in self.dicitem.keys():
                tri.append(cle)
            tri.sort()
            for elems in tri:
                cmd = self.dicitem[elems]
                lab[elems] = Tk.Label(ctnfrm, text=elems, fg=self.fg,
                   bg=self.bg)
                lab[elems].pack(padx=3, pady=2)
                # Liaison des Labels avec la fonction de 'master'
                # qui lui correspond dans le dico.
                lab[elems].bind("<1>", cmd)
                # Association au gestionnaire de focus
                self.focusctrl(lab[elems])
            tri = []
            for cle in self.dicctrl.keys():
                tri.append(cle)
            tri.sort()
            for elems in tri:
                cmd = self.dicctrl[elems]
                lab[elems] = Tk.Label(ctnfrm, text=elems, fg=self.fg,
                   bg=self.bg)
                lab[elems].pack(padx=3, pady=2)
                lab[elems].bind("<1>", cmd)
                self.focusctrl(lab[elems])
            # Label quitter
            labelquit = Tk.Label(ctnfrm, text='Quitter', fg=self.fg,
                bg=self.bg)
            labelquit.pack(padx=3, pady=2)
            self.focusctrl(labelquit)
            ctnfrm.pack(padx=3, pady=2)
            # Liaison bouton gauche sur le Label quitter avec la fonction
            # interne rootquit
            labelquit.bind("<1>", self.rootquit)
            # On positionne le menu
            self.positionne(self.topmenu, x, y)
            # On enleve les bordures
            self.topmenu.overrideredirect(True)
            # Liaison du bouton gauche > fonction qui cache le Label
            self.topmenu.bind("<1>", self.cacher)
            # On affiche le menu
            self.topmenu.deiconify()
     
        def cacher(self, event=None):
            # Destruction du menu
            self.topmenu.destroy()
     
        def focusctrl(self, widget):
            # Lorsque l'on entre ou quitter le Label on change la couleur du texte avec
            # isactive/noactive
            widget.bind("<Leave>", lambda event=None: self.notactive(
                widget))
            widget.bind("<Enter>", lambda event=None: self.isactive(widget))
     
        def isactive(self, widget):
            # Changement de la couleur du texte
            widget['fg']=self.activefg
            # Mise à jour forcée.
            widget.update()
     
        def notactive(self, widget):
            widget['fg']=self.fg
            widget.update()
     
        def additem(self, name, cb):
            # Ajout dans le menu
            self.dicitem[name] = cb
     
        def delitem(self, name):
            # Supprime du menu
            del self.dicitem[name]
     
        def addctrl(self, name, cb):
            # Comme additem mais pour les fonctions de controle
            # Permet de place les fonctions de controle sous les autres
            # Puisque la création des Label de controle se fait après
            # dans affichemenu
            self.dicctrl[name] = cb
     
        def delctrl(self, name):
            # Comme delitem mais pour les fonctions de controle
            del self.dicctrl[name]
     
    # instance Tk principale
    class interface(Tk.Tk):
        def __init__(self, parent):
            Tk.Tk.__init__(self, parent)
            self.title('Whiteboard')
            self.pts = []
            self.totrace = None
            # variables globales pour le dessin
            self.color = Tk.StringVar()
            self.color.set('red')
            self.width = Tk.IntVar()
            self.width.set(3)
            # Création de la capture
            self.sccap = ScreenCap()
            img = self.sccap.grab(name='scrcap.jpg')
            fcapture = Image.open(img)
            self.photo = ImageTk.PhotoImage(fcapture)
            # Mise en place de la capture dans la Canvas c
            # Le Canvas c vas nous servir pour les dessins
            self.c = Tk.Canvas(self, width=self.winfo_screenwidth(),
                height=self.winfo_screenheight())
            self.c.create_image(0, 0, image=self.photo, anchor=Tk.NW)
            # Mise à jour de la fenetre
            self.update()
            # destruction du fichier temporaire
            self.sccap.delete()
            self.c.pack(fill=Tk.BOTH)
            # Création du menu et rajout des Labels
            mainmenu = MainMenu(self, bg='white', fg='black',
                activefg='blue')
            mainmenu.additem('Ligne',
                lambda event=None: self.trace('ligne'))
            mainmenu.additem('Rectangle',
                lambda event=None: self.trace('rectangle'))
            mainmenu.additem('Ovale',
                lambda event=None: self.trace('ovale'))
            mainmenu.additem('Texte',
                lambda event=None: self.trace('texte'))
            mainmenu.addctrl('Effacer',
                lambda event=None: self.trace('delete'))
            mainmenu.addctrl('Sauvegarder', lambda event=None: self.after(2,
                self.sauve))
            mainmenu.addctrl('Configurer', self.config)
            mainmenu.addctrl(u"Réduire", self.reduire)
            # Liaison de évènements clavier/souris
            # pour la fenetre principale
            self.bind('<Escape>', self.intercepte)
            self.bind('<3>', mainmenu.affichemenu)
            self.bind('<1>', self.addlist)
            # gestion de la géométrie :
            # La fenetre principale est en plein écran
            self.wm_attributes('-fullscreen', 1)
            # On réduit la fenetre à l'initialisation du programme
            self.iconify()
     
        # Fonction pour réduire la fenetre principale
        def reduire(self, event=None):
            self.iconify()
     
        # Actions suivant self.totrace
        def addlist(self, event):
            self.pts.append((event.x, event.y))
            if self.totrace == 'delete':
                item = self.c.find_closest(event.x, event.y)
                if item != (1,):
                    self.c.delete(item)
                self.clear()
            elif self.totrace == 'ligne' and len(self.pts) == 2:
                self.c.create_line(self.pts[0][0], self.pts[0][1],
                    self.pts[1][0], self.pts[1][1], fill=self.color.get(),
                    width=self.width.get())
                self.clear()
            elif self.totrace == 'rectangle' and len(self.pts) == 2:
                self.c.create_rectangle(self.pts[0][0], self.pts[0][1],
                    self.pts[1][0], self.pts[1][1], outline=self.color.get(),
                    width=self.width.get())
                self.clear()
            elif self.totrace == 'ovale' and len(self.pts) == 2:
                self.c.create_oval(self.pts[0][0], self.pts[0][1],
                    self.pts[1][0], self.pts[1][1], outline=self.color.get(),
                    width=self.width.get())
                self.clear()
            elif self.totrace == 'texte':
                for widget in (widget for widget in self.winfo_children()
                    if isinstance(widget, Tk.Toplevel)):
                        widget.destroy()
                self.menutext = Tk.Toplevel()
                self.menutext.title("Ajout d'un texte")
                self.textentry = Tk.Entry(self.menutext, width=80)
                self.textentry.grid(row=0, column=0, columnspan=2, padx=5,
                    pady=5)
                self.textentry.focus_set()
                self.btvalid = Tk.Button(self.menutext, fg='green', text='Valider',
                    command=self.createtxt)
                self.btvalid.grid(row=1, column=0, padx=5, pady=5)
                self.btquit = Tk.Button(self.menutext, fg='red',
                    text='Annuler', command=lambda: self.delwidget(self.menutext))
                self.btquit.grid(row=1, column=1, padx=5, pady=5)
                self.menutext.update()
                self.menutext.geometry("%dx%d+%d+%d" %
                    (self.menutext.winfo_reqwidth(),
                    self.menutext.winfo_reqheight(), event.x, event.y))
                self.menutext.bind('<Escape>', lambda event=None:
                    self.delwidget(self.menutext))
     
        # Destruction d'un 'dessin'
        def delwidget(self, widget):
            widget.destroy()
            self.clear()
     
        # pour la création de texte
        def createtxt(self):
            self.c.create_text(self.pts[0][0], self.pts[0][1],
                fill=self.color.get(), text=self.textentry.get())
            self.delwidget(self.menutext)
     
        # Vide la liste des points
        def clear(self):
            self.totrace = None
            del(self.pts[:])
     
        # Pour quitter proprement le programme
        def intercepte(self, event=None):
            self.quit()
     
        # initialisation de la liste des point et mise en place
        # de self.totrace
        def trace(self, obj):
            del(self.pts[:])
            self.totrace = obj
     
        # Sauvegarde de l'image
        def sauve(self, event=None):
            img = self.sccap.grab(name='scrcap.jpg')
            filetosave = tkFileDialog.asksaveasfilename(
                initialdir=os.path.expanduser('~'), title="Enregistrement",
                filetypes=[('JPEG / JFIF','*.jpg')], defaultextension='jpg',
                initialfile='capture.jpg')
            if filetosave:
                if os.path.isfile(filetosave):
                    os.remove(filetosave)
                os.rename(img, filetosave)
            else:
                self.sccap.delete()
     
        # Menu de configuration
        def config(self, event=None):
            for widget in (widget for widget in self.winfo_children()
                if isinstance(widget, Tk.Toplevel)):
                    widget.destroy()
            self.menuconfig = Tk.Toplevel()
            self.menuconfig.title("Configuration")
            Tk.Label(self.menuconfig, text='Epaisseur de ligne').grid(row=0,
                column=0, padx=5, pady=5)
            for i in range(0, 11):
                Tk.Radiobutton(self.menuconfig, text=str(i), variable=self.width,
                    value=i).grid(row=1+i, column=0, padx=5, pady=5)
            Tk.Label(self.menuconfig, text='Couleur').grid(row=0, column=2,
                padx=5, pady=5)
            col = 0
            for c, n in [('Noir', 'black'), ('Blanc', 'white'), ('Rouge', 'red'),
                ('Vert', 'green'), ('Bleu', 'blue'), ('Jaune', 'yellow'),
                ('Violet', 'purple'), ('Orange', 'orange'), ('Gris', 'gray'),
                ('Rose', 'pink'), ('Marron', 'brown'),]:
                Tk.Radiobutton(self.menuconfig, text=c, variable=self.color,
                    value=n).grid(row=col+1, column=2, padx=5, pady=5, sticky=Tk.W)
                col += 1
            Tk.Button(self.menuconfig, fg='green', text='Quitter', command=lambda:
                 self.delwidget(self.menuconfig)).grid(row=14, column=1, pady=10)
            self.menuconfig.bind('<Escape>', lambda event=None:
                self.delwidget(self.menuconfig))
     
    if __name__ == "__main__":
        app = interface(None)
        app.mainloop()
    @+
    Merci d'utiliser le forum pour les questions techniques.

  17. #17
    Membre à l'essai
    Homme Profil pro
    technicien polyvalent debutant developpeur web / maintenance
    Inscrit en
    Octobre 2009
    Messages
    24
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France

    Informations professionnelles :
    Activité : technicien polyvalent debutant developpeur web / maintenance

    Informations forums :
    Inscription : Octobre 2009
    Messages : 24
    Points : 14
    Points
    14
    Par défaut
    Merci. Pas la peine de t'embêter à en faire plus je trouve déjà les commentaires bien complet.

    Merci pour tout^^

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Aide pour une application
    Par mon-gi dans le forum Débuter
    Réponses: 6
    Dernier message: 05/12/2012, 10h28
  2. j`ai besoin d`une aide pour une application sur labview
    Par sarah1991 dans le forum LabVIEW
    Réponses: 3
    Dernier message: 14/05/2012, 19h24
  3. aide pour une application Android (assez facile)
    Par grogz dans le forum Android
    Réponses: 3
    Dernier message: 21/09/2011, 01h58
  4. Réponses: 0
    Dernier message: 11/03/2010, 09h39

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo