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 :

Centrage wx.Sizer et classe dérivée


Sujet :

wxPython

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Février 2008
    Messages
    45
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 45
    Par défaut Centrage wx.Sizer et classe dérivée
    Bien le bonjour à tous

    Voilà plus de huit six mois que j'avais laissé tomber mon projet, mais maintenant, j'ai pluss de temps alors je m'y remets.
    Mais me voilà de nouveau confronté à un ***** de problème. Je m'arrache les cheveux dessus depuis un bon nombre d'heures, j'ai essayé tout ce que je trouvais, etc ... J'y suis allé au débogueur,mais rien n'y fait ...

    C'est pourquoi je solicite votre aidé précieuse :p

    J'ai un sizer dans lequel je place un MyStaticText (classe dérivée d'une wx.Window qui me permet de rendre transparent le Background, de cette facon je peux écrire du texte sans avoir le cadre d'une wx.StaticText, voir http://www.developpez.net/forums/d67...sparent-panel/) et un wx.Button

    Quand j'appuie sur mon bouton, je change le Label de mon MyStaticText et donc j'augmente (ou diminue sa taille). Le probleme est que, après ce redimensionnement, mon widget n'est plus centré !! J'ai utilisé un sizer.Layout(), mais ca ne donne aucun résultat !

    Voici mon programme simplifié :

    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
    import wx
     
    class MyStaticText(wx.Window):
        def __init__(self, parent, label):
            wx.Window.__init__(self,parent,-1)
            self.parent=parent
            self.label=label
            self.police=wx.Font(12,wx.FONTFAMILY_DEFAULT,wx.FONTSTYLE_NORMAL,wx.FONTWEIGHT_NORMAL)
            self.police.SetNativeFontInfoFromString(u'0;-16;0;0;0;400;0;0;0;0;3;2;1;66;Lucida Handwriting')
    ## Remplacez la police ci-dessus par 'Georgia' si vous n'avez pas le Lucida Handwriting
            width,height=self.GetFullTextExtent(label,font=self.police)[0:2]
            self.SetSize((width,height))
            self.SetBackgroundStyle(wx.BG_STYLE_CUSTOM)
     
            self.Bind(wx.EVT_PAINT, self.OnPaint)
     
        def OnPaint(self,evt):
            x,y=self.GetPositionTuple()
            dc=wx.PaintDC(self)
            l,h=dc.GetFullTextExtent(self.label,font=self.police)[0:2]
            self.SetSize((l,h))
            dc=wx.PaintDC(self)
            dc2=wx.BufferedPaintDC(self.parent)
            dc.Blit(0,0,l,h,dc2,x,y)
            dc.SetTextBackground(wx.NullColour)
            dc.SetTextForeground(wx.BLACK)
            dc.SetFont(self.police)
            dc.DrawText(self.label,0,0)
     
        def SetLabel(self,label):
            self.Refresh(True)
            self.label=label
            width,height=self.GetFullTextExtent(label,font=self.police)[0:2]
            self.SetSize((width,height))
     
    class MyFrame(wx.Frame):
     
        def __init__(self, *args, **kwargs):
     
            wx.Frame.__init__(self, *args, **kwargs)
     
            self.panel = wx.Panel(self)
     
            self.btn = wx.Button(self.panel, -1, "Click me!!!")
            self.stt = MyStaticText(self.panel, "Salut")
     
            self.szr = wx.GridBagSizer(5, 5)
            self.szr.Add(self.stt, (0, 0), flag=wx.ALIGN_CENTRE_VERTICAL|wx.ALIGN_CENTRE_HORIZONTAL)
            self.szr.AddGrowableCol(0)
            self.szr.AddGrowableRow(0)
            self.szr.Add(self.btn, (1, 0), flag=wx.ALIGN_CENTRE)
     
            self.panel.SetSizer(self.szr)
            self.btn.Bind(wx.EVT_BUTTON,self.button)
            self.panel.Bind(wx.EVT_PAINT,self.OnPaint)
     
        def button(self,evt):
            self.stt.SetLabel("Saluuuuuuuuuuuuuuuuuut")
            self.szr.Layout()
     
        def OnPaint(self,evt):
            size=self.panel.GetRect()
            dc=wx.BufferedPaintDC(self.panel)
            dc.GradientFillLinear(size,wx.BLUE,wx.SystemSettings.GetColour(wx.SYS_COLOUR_MENU),wx.NORTH)
            evt.Skip()
     
    if __name__ == "__main__":
     
        app = wx.PySimpleApp(redirect=False)
        fr = MyFrame(None, -1, "Test bouton")
        fr.Show(True)
        app.MainLoop()
    J'espere que vous pourrez m'aider !
    Merci beaucoup !

    Lotendan

  2. #2
    Membre Expert

    Homme Profil pro
    Diverses et multiples
    Inscrit en
    Mai 2008
    Messages
    662
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Diverses et multiples

    Informations forums :
    Inscription : Mai 2008
    Messages : 662
    Par défaut
    Salut Lotendan.

    Malheureusement, je ne peut pas tester ce code, Cependant, je me pose une question: pourquoi utiliser un sizer aussi complexe que le GridBag, pour deux malheureux contrôles? Un BoxSizer devrait largement suffire, il me semble… À moins que tu ne veuilles y rajouter d’autres choses…

    De toute façon, essaye déjà avec un simple BoxSizer, pour voir si la disposition de ton contrôle texte est maintenant correcte.

    Sinon, je ne suis pas tout à fait sûr qu’un simple Layout() entraîne le rafraîchissement de la fenêtre parent (et donc des contrôles enfants), vois par exemple si en redimensionnant (avec la souris) ta fenêtre, ton texte ne se recentre pas tout seul. Si c’est le cas, tu devrais essayer de forcer le rafraîchissement de la fenêtre…

    Tu peux aussi essayer d’insérer un sous-sizer spécifiquement pour ton contrôle texte. L’emboîtement de sizers peut être assez complexe à gérer (et à suivre !), mais c’est parfois la seule solution pratique…

    Dernière piste: au lieux de redimensionner ton contrôle texte (que tu laisse alors automatique), vois si tu ne peux pas plutôt redimensionner la cellule du sizer qui le contient (en spécifiant à l’ajout de ton contrôle le flag wxEXPAND, pour que celui-ci “suive le mouvement” automatiquement).

    De toute façon, la gestion du redimensionnement des éléments d’un sizer n’est pas toujours évidente… Il faut alors tester plusieurs combinaisons avant de trouver le bon truc (ou alors, être un crac du raisonnement logique… et parfaitement connaître le fonctionnement interne des sizers ).

    Bref, pas de solution “toute faite”, mais j’espère quand même que ces quelques pistes pourront t’aider à résoudre ce problème (et à conserver quelque pilosité capillaire, tout de même ).

    A+, Bastien

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Février 2008
    Messages
    45
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 45
    Par défaut
    Salut Mont29,

    Tout d'abord merci d'avoir au moins essayé de répondre !

    Eh bien, j'ai une mauvaise nouvelle, malgré toutes les astuces que tu m'as donné, je les ai toutes essayées sauf une (celle du sous-sizer) et aucune ne marche ...

    Je vais te détailler tout ça : il est vrai que l'idée du sous-sizer peut être intéressante, j'y avais pensé mais comme tu dis c'est assez compliqué et assez lourd et impropre niveau programmation. Ceci dit, s'il n'y a pas d'autre solution, je ferai avec en dernier recours.

    Ensuite, le flag wx.EXPAND ne fonctionne pas puisqu'il blanchit tout le background, et ce n'est surtout pas ce que je veux ...

    Puis, je ne veux pas utiliser un BoxSizer puisque j'ai une trentaine d'éléments à mettre dans ma fenêtre. Le script que j'ai fourni ci-dessus n'est qu'un exemple "allégé" avec deux widgets pour simplifier ma demande d'aide. Non, je veux absolument utiliser le GridBagSizer

    Pour finir, je t'ai pris des screen pour la derniere piste : le redimensionnement. Le premier screen indique l'état de la fenêtre AVANT redimensionnement et après avoir cliqué sur le bouton "Click Me !!" qui déclenche le changement de label. Et le second screen montre la fenêtre APRES un redimensionnement quelconque. On voit bien que le texte reste prisonnier dans le petit carré, c'est pour ça que je voulais augmenter la taille du contrôle MyStaticText. J'ai donc mis des "print self.stt.GetSize()" de partout (une ligne sur deux) dans l'exemple ci-dessus, et je me rend compte que la taille revient à sa valeur initiale toute seule !!!!!!! C'est-à-dire que mon SetSize() ne fonctionne que temporairement.
    Je pense qu'il faut réussir à augmenter la taille du MyStaticText, puis ensuite utiliser un Layout() pour que le sizer prenne en compte les nouvelles dimensions de la MyStaticText.


    Encore une fois, merci d'avoir essayé de m'aider, et merci d'avance pour la suite.

    Lotendan
    Images attachées Images attachées   

  4. #4
    Membre éprouvé
    Inscrit en
    Octobre 2006
    Messages
    92
    Détails du profil
    Informations forums :
    Inscription : Octobre 2006
    Messages : 92
    Par défaut
    Bonjour,

    Je ne peux pas te fournir de véritable réponse car je ne maîtrise encore que très mal le dc ; en effert, je pense que c'est de ce côté-là que se situe le problème et non pas du côté des sizers.

    En effet, j'ai essayé ton code (sous GNU/Linux) en le simplifiant : pas de gradient en background, et StaticText classique ; par contre j'ai conservé tout le reste en particulier tes sizers...

    ... et cette fois, le code fonctionne parfaitement !

    D'une façon générale, j'évite d'utiliser un fond en dégradé, au moins sur une interface dynamique : à chaque fois que j'ai un redimensionnement d'un élément, mon interface est badibulguée.

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Février 2008
    Messages
    45
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 45
    Par défaut
    Salut,

    Donc tu penses que c'est le gradient qui fait tout boguer ?
    J'y tiens vraiment à mon gradient

    En tout cas, merci d'avoir essayé d'apporter une réponse
    Est-ce que quelqu'un aurait d'autres pistes svp ?

    Merci beaucoup !

  6. #6
    Membre Expert

    Homme Profil pro
    Diverses et multiples
    Inscrit en
    Mai 2008
    Messages
    662
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Diverses et multiples

    Informations forums :
    Inscription : Mai 2008
    Messages : 662
    Par défaut
    Salut Lotendan

    Désolé pour le délais, mais je ne me connecte pas souvent…

    En fait, si je comprends bien, le problème ne vient pas tant des sizers que de ton contrôle.

    Si je ne me trompe pas, le fonctionnement des sizers est le suivant (lors d’un re-calcul de taille):
    *ils interrogent chaque élément géré, pour en obtenir la taille optimum
    *ils “font leur sauce” avec toutes ces dimensions, pour obtenir la meilleur répartition possible
    *ils règlent la taille (et la position) des éléments contrôlés, en fonction de leurs calculs précédents.

    Donc, si ton contrôle retrouve sa taille par défaut, c’est parce que le sizer l’y oblige, et probablement parce que le texte statique ne renvoie pas la bonne dimension "optimale".

    Je ne sais pas exactement quelle fonction de wxWindow les sizers appelle pour déterminer la taille voulue d’un élément, peut-être GetBestSize(), par ex.

    Toujours est-il que tu peux essayer, dans ta classe MyStaticText, de surcharger cette fonction. ou alors, au lieu de modifier sa taille avec SetSize(), utiliser SetMinSize() et SetMaxSize(), avec les mêmes valeurs pour les deux. Comme ça, le contrôle MyStaticText ne devrait plus pouvoir revenir à sa taille par défaut.

    Reste le problème du centrage…

    De toute façon, encore une fois, ce ne sont que des pistes .

    Bon courage,
    Bastien

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

Discussions similaires

  1. classe dérivée de thread
    Par aaronw dans le forum Threads & Processus
    Réponses: 9
    Dernier message: 08/03/2006, 15h35
  2. Réponses: 2
    Dernier message: 06/12/2005, 09h41
  3. Réponses: 4
    Dernier message: 20/11/2005, 05h48
  4. [MFC] CArray et classe dérivée?
    Par TigreRouge dans le forum MFC
    Réponses: 14
    Dernier message: 02/08/2005, 22h45
  5. Déterminer le type d'une class dérivée
    Par LDDL dans le forum MFC
    Réponses: 3
    Dernier message: 10/12/2004, 17h36

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