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 :

Quel contrôle pour un calendrier ?


Sujet :

wxPython

  1. #1
    Membre éclairé
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    328
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2007
    Messages : 328
    Par défaut Quel contrôle pour un calendrier ?
    Bonjour,

    Je souhaite créer un calendrier personnalisé (c'est pourquoi je l'utilise pas les contrôles calendar existant). Je veux pouvoir afficher du texte ou des images dans les cases et que chaque case réagisse au click ou au passage de la souris (bref comme un contrôle calendrier classique).

    J'utilise un GridSizer pour faire le tableau. Ca marche très bien. MAIS je ne trouve pas de contrôle satisfaisant pour faire les cases-jours. J'ai essayé avec les boutons mais il n'y a pas assez de possibilités concernant l'affichage de textes dedans et j'ai essayé les TextCtrl mais je n'arrive pas à faire réagir la souris comme je le souhaite.

    Donc, quel contrôle utiliser ? la réponse doit être simple j'imagine, mais je sèche dur là...

    Merci pour vos réponses !!!

  2. #2
    Membre Expert Avatar de pacificator
    Profil pro
    Inscrit en
    Août 2006
    Messages
    1 074
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 1 074
    Par défaut
    un panel?

  3. #3
    Membre éclairé
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    328
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2007
    Messages : 328
    Par défaut
    Merci pour ta réponse.

    Mais, d'après toi, est-ce qu'il me serait par exemple de faire changer la couleur du panel si le curseur de la souris passe dessus ?

    EDIT : A première vue, cette idée me paraît excellente, mais je ne trouve toujours pas comment faire réagir la souris...

  4. #4
    Membre Expert Avatar de pacificator
    Profil pro
    Inscrit en
    Août 2006
    Messages
    1 074
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 1 074
    Par défaut
    un exemple basique:
    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
     
     
     
    import wx
     
    class MyPanel(wx.Panel):
     
    	def __init__(self, *args, **kwargs):
     
    		wx.Panel.__init__(self, *args, **kwargs)
    		self.SetBackgroundColour((255, 255, 255))
    		self.Bind(wx.EVT_ENTER_WINDOW, self.OnEnter)
    		self.Bind(wx.EVT_LEAVE_WINDOW, self.OnLeave)
     
    	def OnEnter(self, evt):
    		self.SetBackgroundColour((255, 0, 0))
    		self.Refresh()
    		evt.Skip()
     
    	def OnLeave(self, evt):
    		self.SetBackgroundColour((255, 255, 255))
    		self.Refresh()
    		evt.Skip()
     
    class MyFrame(wx.Frame):
     
    	def __init__(self, *args, **kwargs):
     
    		wx.Frame.__init__(self, *args, **kwargs)
    		panel = MyPanel(self, -1)
     
     
    if __name__ == "__main__":
     
    	app = wx.PySimpleApp(redirect=False)
    	frame = MyFrame(None, -1, 'test panel')
    	frame.Show(True)
    	app.MainLoop()

  5. #5
    Membre éclairé
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    328
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2007
    Messages : 328
    Par défaut
    Merci.

    Tu m'a encore donné un sacré coup de main. Ca devient une habitude . Merci pour ta générosité.

    D'ailleurs, j'en profite encore un peu (honte sur moi mais bon...). Histoire que je ne sois plus un boulet, pourrais-tu me dire comment tu trouves, par exemple, les méthodes SetBackgroundColour ou wx.EVT_ENTER_WINDOW pour le PANEL dans la documentation ?

    Parce que là, j'étais en train de la lire mais je ne vois pas du tout ces expressions... (je cherche sur : http://www.wxpython.org/docs/api/)

    Saurais-je mal chercher ou est-ce caché autre part ? (Ta réponse me permettrait sûrement d'être un peu plus autonome).

    Merci encore

  6. #6
    Membre éclairé
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    328
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2007
    Messages : 328
    Par défaut
    Eh bien je crois que j'ai trouvé la réponse à ma question : Panel appartient à Windows et donc hérite de ces "propriétés". J'espère que je ne me trompe pas...

    Bon, j'ai encore une colle :

    Le coup du panel pour chaque case fonctionne à merveille. J'ai placé dans chaque panel un StaticText contenant le Numéro du jour. Mais le problème est que quand je passe la souris sur ce StaticText, le panel ne réagit bien évidemment plus.

    Cela fonctionne si je mets StaticText.Enable(False). mais dans ce cas, le texte devient gris, ce qui ne me plaît pas forcément. Auriez-vous une combine pour contrer ce problème ?

    Merci pour vos réponses

  7. #7
    Membre Expert Avatar de pacificator
    Profil pro
    Inscrit en
    Août 2006
    Messages
    1 074
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 1 074
    Par défaut
    Bien vu pour le panel heritant de window, c'est exactement ça.
    Concernant ton autre problème, peux-tu poster un bout de code pour pouvoir le tester.

  8. #8
    Membre éclairé
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    328
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2007
    Messages : 328
    Par défaut
    Ok, je te mets tout le 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
     
    import calendar
    import wx
     
     
    class Case_Calendrier(wx.Panel):
     
        def __init__(self, *args, **kwargs):
     
    	# Initialisation du panel
    	wx.Panel.__init__(self, *args, **kwargs)
    	self.SetBackgroundColour((255, 255, 255))
    	self.SetToolTipString(self.GetName())
     
    	self.Bind(wx.EVT_ENTER_WINDOW, self.OnEnter)
    	self.Bind(wx.EVT_LEAVE_WINDOW, self.OnLeave)
    	self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftClick)
            self.Bind(wx.EVT_RIGHT_DOWN, self.OnRightClick)
     
            # Création de l'intérieur de la case
            gridSizer = wx.FlexGridSizer(2, 2, 0, 0)
            gridSizer.AddGrowableCol(0)
            gridSizer.AddGrowableCol(1)
            self.LabelNumJour = wx.StaticText(self, -1, str(self.GetId()))
            gridSizer.Add(self.LabelNumJour, 0, wx.ALL, 2)
            self.SetSizer(gridSizer)
     
        def OnEnter(self, event):
    	self.SetBackgroundColour((255, 0, 0))
    	self.Refresh()
    	event.Skip()
     
        def OnLeave(self, event):
    	self.SetBackgroundColour((255, 255, 255))
    	self.Refresh()
    	event.Skip()
     
        def OnLeftClick(self, event):
            print ("Click Gauche ! (%d)" % event.GetId())
            event.Skip()
     
        def OnRightClick(self, event):
            print ("Click Droit ! (%d)" % event.GetId())
            print "Taille de la case : ", self.GetClientSizeTuple()
            print self.GetName()
            event.Skip()
     
     
    class MyFrame(wx.Frame):
        def __init__(self, titre):
            wx.Frame.__init__(self, None, -1, title = titre)
            self.panel = wx.Panel(self)
            sizerVertical = wx.BoxSizer(wx.VERTICAL)
            sizerGridHeaders = wx.GridSizer(rows=1, cols=7, hgap=4, vgap=4)
            sizerGridCases = wx.GridSizer(rows=7, cols=7, hgap=4, vgap=4) 
     
            # Création des dates
            self.annee = 2007
            self.mois = 8
            datesCalendrier = calendar.monthcalendar(self.annee, self.mois)
     
            # Création du tableau
            jours=["Lundi", "Mardi", "Mercredi", "Jeudi", "Vendredi", "Samedi", "Dimanche"]
            for jour in jours:
                self.header = wx.StaticText(self.panel, -1, jour, style = wx.ALIGN_CENTRE)
                sizerGridHeaders.Add(self.header, 0, wx.EXPAND|wx.ALL, 4)
     
            for semaine in datesCalendrier:
                for jour in semaine:
                    if jour ==0 :
                        sizerGridCases.Add((60, 20), 0, wx.EXPAND)
                    else:
                        texte = str(jour)
                        ID = jour
                        nomPanel = str(jour)+"/"+str(self.mois)+"/"+str(self.annee)
                        self.case = Case_Calendrier(self.panel, ID, name=nomPanel)
                        sizerGridCases.Add(self.case, 0, wx.EXPAND, 0)
     
            sizerVertical.Add(sizerGridHeaders, 0, wx.EXPAND)
            sizerVertical.Add(sizerGridCases, 1, wx.EXPAND)
            self.panel.SetSizer(sizerVertical)
            self.panel.Layout()
     
     
    class MonApp(wx.App):
        def OnInit(self):
            frame = MyFrame("Test Calendrier")
            frame.Show(True)
            return True
     
    app = MonApp()
    app.MainLoop()

  9. #9
    Membre Expert Avatar de pacificator
    Profil pro
    Inscrit en
    Août 2006
    Messages
    1 074
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 1 074
    Par défaut
    Salut Ggamer,

    Après avoir un peu cherché, il apparaît que le passage sur le StaticText génère l'événement EVT_LEAVE_WINDOW sur le panel.

    J'ai trouvé une solution, ce doit être possible de faire autrement mais en attendant, ça a l'air de fonctionner.

    Dans le __init__ du panel, on définit un attribut OnWidget:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    class Case_Calendrier(wx.Panel):
     
        def __init__(self, *args, **kwargs):
     
            # Initialisation du panel
            # ...
     
            self.OnWidget = False
    On bind sur le StaticText les événements EVT_ENTER_WINDOW et EVT_LEAVE_WINDOW dans le panel.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
            self.LabelNumJour.Bind(wx.EVT_ENTER_WINDOW, self.OnEnterWidget)
            self.LabelNumJour.Bind(wx.EVT_LEAVE_WINDOW, self.OnLeaveWidget)
    On ajoute les méthodes OnEnterWidget et OnLeaveWidget.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
        def OnEnterWidget(self, evt):
            print "OnEnterWidget"
            self.OnWidget = True
            self.SetBackgroundColour((255, 0, 0))
            self.Refresh()
     
        def OnLeaveWidget(self, evt):
            print "OnLeaveWidget"
            self.OnWidget = False
            self.SetBackgroundColour((255, 255, 255))
            self.Refresh()
    On modifie les méthodes OnEnter et OnLeave.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
        def OnEnter(self, event):
            print "OnEnter"
            self.OnWidget = False
            self.SetBackgroundColour((255, 0, 0))
            self.Refresh()
            event.Skip()
     
        def OnLeave(self, event):
            print "OnLeave"
            if self.OnWidget: return
            self.SetBackgroundColour((255, 255, 255))
            self.Refresh()
            event.Skip()
    Et voilà

    <inconvenient>
    Il faut binder les événements EVT_ENTER_WINDOW et EVT_LEAVE_WINDOW sur chaque widget du panel.
    </inconvenient>

    Mais bon, on a rien sans rien

  10. #10
    Membre éclairé
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    328
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2007
    Messages : 328
    Par défaut
    Bonjour,

    Tout d'abord, merci d'avoir passé du temps sur mon affaire.

    J'ai passé de nombreuses heures dessus hier

    J'avais tenté à peu près la même solution que tu me proposes ici. J'ai ré-essayé avec la tienne et ... Problème !

    Quand je passe sur un staticText et que je le quitte pour retourner sur la case "panel" qui le contient. l'évènement OnEnter du panel ne fonctionne pas : le panel ne s'allume pas. Je suis pas sûr d'être très clair là...

    Evidemment, j'espère avoir bien reproduit ta solution, mais je pense que c'est bien ça... Si tu veux bien, il faudrait que tu vérifies sur ton test si cette situation se produit.

    Mais bon, si on n'arrive pas à mettre en place cette solution, j'ai pas chômé hier : j'ai trouvé une autre solution (moins convaincante, mais ca marche) :

    J'utilise un wx.DC dans chaque panel pour dessiner le numéro du jour et les autres textes que je souhaite mettre dedans (style 'évènements dans un agenda'). Dans ce cas de figure, le panel s'allume bien, et les textes sont impec.

    Mais il y a des inconvénients :
    - Je dois dessiner les textes avec des coordonnées
    - Pour gérer le redimensionnement, je dois programmer des modifications de tailles de police et de coordonnées.
    - Je ne peux pas placer de widgets intéractifs (comme des Listes...)

    Mais bon, la solution fonctionne (On peut pas tout avoir je suppose).

    Voilà où j'en suis.

    Si tu as d'autres idées, je suis preneur. Sinon je te remercie pour ton investissement... A+.

  11. #11
    Membre Expert Avatar de pacificator
    Profil pro
    Inscrit en
    Août 2006
    Messages
    1 074
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 1 074
    Par défaut
    Quand je passe sur un staticText et que je le quitte pour retourner sur la case "panel" qui le contient. l'évènement OnEnter du panel ne fonctionne pas : le panel ne s'allume pas. Je suis pas sûr d'être très clair là...
    Exact, pareil chez moi...

    Une solution palliative possible: créer un attribut OnPanel.Modifier les méthodes qui vont bien:
    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
        def OnEnterWidget(self, evt):
            print "OnEnterWidget"
            self.OnWidget = True
            self.SetBackgroundColour((255, 0, 0))
            self.Refresh()
     
        def OnLeaveWidget(self, evt):
            print "OnLeaveWidget"
            self.OnWidget = False
            if self.OnPanel: return
            self.SetBackgroundColour((255, 255, 255))
            self.Refresh()
     
        def OnEnter(self, event):
            print "OnEnter"
            self.OnPanel = True
            self.SetBackgroundColour((255, 0, 0))
            self.Refresh()
            event.Skip()
     
        def OnLeave(self, event):
            print "OnLeave"
            self.OnPanel = False
            if self.OnWidget: return
            self.SetBackgroundColour((255, 255, 255))
            self.Refresh()
            event.Skip()
    Et là, ça devrait rouler...

  12. #12
    Membre éclairé
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    328
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2007
    Messages : 328
    Par défaut
    Alors là, rien à dire

    Ca marche parfaitement. Dire que j'étais en train de me casser les dents sur le wx.DC

    Merci pour tout Pacificator !

  13. #13
    Membre Expert Avatar de pacificator
    Profil pro
    Inscrit en
    Août 2006
    Messages
    1 074
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 1 074
    Par défaut
    Merci pour tout Pacificator !
    De rien, l'entraide c'est important
    Dire que j'étais en train de me casser les dents sur le wx.DC
    Ca fait pas de mal de se frotter un peu aux autres classes de la librairie

    Bon python

    pacificator

Discussions similaires

  1. Quel Contrôle pour escalier de répertoire?
    Par KiraX10A dans le forum Visual C++
    Réponses: 1
    Dernier message: 04/01/2010, 16h46
  2. [Debutant] Quel contrôle pour faire
    Par vpet dans le forum Windows Forms
    Réponses: 5
    Dernier message: 28/05/2008, 15h39
  3. Quel contrôle utilisez-vous pour calendar ?
    Par rad_hass dans le forum ASP.NET
    Réponses: 20
    Dernier message: 14/03/2008, 16h04
  4. Quel contrôle utiliser pour agenda?
    Par gangsterus dans le forum VB.NET
    Réponses: 4
    Dernier message: 30/01/2008, 18h44
  5. Quel CMS pour un site sur l'événementiel? (Le calendrier est très important)
    Par elraton dans le forum EDI, CMS, Outils, Scripts et API
    Réponses: 1
    Dernier message: 17/09/2007, 13h38

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