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

Tkinter Python Discussion :

Jolie interface ?


Sujet :

Tkinter Python

  1. #1
    Membre régulier Avatar de Caxton
    Homme Profil pro
    Sans
    Inscrit en
    Janvier 2005
    Messages
    586
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Corrèze (Limousin)

    Informations professionnelles :
    Activité : Sans

    Informations forums :
    Inscription : Janvier 2005
    Messages : 586
    Points : 123
    Points
    123
    Par défaut Jolie interface ?
    Bonjour,

    Pour commencer, laissez moi vous dire combien je débute et combien j'aimerais y aller pas à pas. Cela vaudra mieux que de long discours que je risque de ne pas comprendre. Je débute un peu dans Python. Et oui, il faut bien commencer par un bout.

    À l'aide d'exemple, j'a attaqué une GUI. Jusque là, rien d'anormal. J'ai même déjà la suite du code vue que j'ai eu sous la main un prototype qui fonctionne. Mais j'en suis rendu au moment où, d'une part j'ai le code qui tourne (bien) mais qui n'est pas beau à voir et de l'autre une interface à faire IHM qui doit ressembler à quelque-chose.

    Comme mon but est expérimental avant tout, j'ai pas besoin d'un truc totalement fini mais qui soit facile à maintenir.

    Voila donc où j'en suis. Je me suis lancé dans l'idée de faire une fenêtre de contrôle de robot. A ceci prêt que le robot fonctionne par liaison série (le code fonctionne hein, donc on développera pas plus et je ne l'ai pas pour le moment implémenté pour gagner du temps). J'ai donc commencer à aligner quelques boutons et, hélas, je ne voie pas comment remplir la partie à gauche de mes premiers boutons. D'ailleurs dans le code, j'ai laisser un petit commentaire pour dire que c'était ici que je cherchais à implémenté mes autres boutons.

    Voyons niveau 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
     
    #!/usr/bin/python
    # -*- coding: iso-8859-1 -*-
     
    import Tkinter
     
    class test_tk(Tkinter.Tk):
    	def __init__(self, parent):
    		Tkinter.Tk.__init__(self, parent)
    		self.parent = parent
    		self.initialize()
     
    	def initialize(self):
    		self.grid()
     
    		self.entry = Tkinter.Entry(self)				#Widget
    		self.entry.grid(column=0, row=0, sticky='EW')	#Ici je cherche à ajouter de nouveaux contrôles de directions
     
    		#goupe de bouton (avancer, reculer, mettre les roues au centre à gauche et à droite)
    		button = Tkinter.Button(self, text="Avancer")
    		button.grid(column=2, row=0)
     
    		button = Tkinter.Button(self, text="Gauche")
    		button.grid(column=1, row=1)
     
    		button = Tkinter.Button(self, text="Centre")
    		button.grid(column=2, row=1)
     
    		button = Tkinter.Button(self, text="Droite")
    		button.grid(column=3, row=1)
     
    		button = Tkinter.Button(self, text="Reculer")
    		button.grid(column=2, row=2)
     
    		self.grid_columnconfigure(0, weight=1)
     
     
    if __name__ == "__main__":
    	app = test_tk(None)
    	app.title('test tk')
    	app.mainloop()
    Et maintenant, reprenons. J'ai deux systèmes de direction. L'un est figée c'est celui de droite. L'autre est un peu plus subtil. Il y a un premier bouton pour dire qu'on va mettre les roues dans un sens particulier et deux boutons pour tourner sur place à droite ou à gauche. Enfin, il me faudra un dernier pour remettre les roues au centre.

    Si je voulais corsé le tout, j'aurais mis un bouton radio qui grise les boutons qui doivent être désactivé quand on est dans le mode normal ou le mode sur place.

    Voila, si quelqu'un peu m'aider un peu à ajouter mes boutons à gauche dans la zone vide, je serais content.

    Merci.

  2. #2
    Membre éprouvé
    Homme Profil pro
    Aucune activité
    Inscrit en
    Novembre 2011
    Messages
    505
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Aucune activité

    Informations forums :
    Inscription : Novembre 2011
    Messages : 505
    Points : 926
    Points
    926
    Par défaut
    Citation Envoyé par Caxton Voir le message
    Et maintenant, reprenons. J'ai deux systèmes de direction. L'un est figée c'est celui de droite. L'autre est un peu plus subtil. Il y a un premier bouton pour dire qu'on va mettre les roues dans un sens particulier et deux boutons pour tourner sur place à droite ou à gauche. Enfin, il me faudra un dernier pour remettre les roues au centre.

    Si je voulais corsé le tout, j'aurais mis un bouton radio qui grise les boutons qui doivent être désactivé quand on est dans le mode normal ou le mode sur place.

    Voila, si quelqu'un peu m'aider un peu à ajouter mes boutons à gauche dans la zone vide, je serais content.

    Merci.
    Bonsoir,
    Le système tkinter est simple: chaque widget peut contenir un système de positionnement.
    Il suffit donc de créer une frame dans cet espace (sous l'entrée) puis d'utiliser un nouveau système de grille (ou même un autre, tel que pack ou place!!!).
    Ainsi, vous pouvez ajouter (par exemple ligne 18) le code:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    		self.frame = Tkinter.Frame(self)
    		self.frame.grid(column=0, row=1, rowspan=3)
    		bt1 = Tkinter.Button(self.frame, text="coucou")
    		bt1.grid(column=1, row=1)
    Et ainsi avoir une nouvelle grille… et donc positionner autant de boutons que désiré, aux emplacements désirés.
    Non?

    Clodion
    PS: à ce niveau là, il peut être utile de scinder le code de manière à ce que l'ensemble soit plus lisible.

  3. #3
    Membre régulier Avatar de Caxton
    Homme Profil pro
    Sans
    Inscrit en
    Janvier 2005
    Messages
    586
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Corrèze (Limousin)

    Informations professionnelles :
    Activité : Sans

    Informations forums :
    Inscription : Janvier 2005
    Messages : 586
    Points : 123
    Points
    123
    Par défaut Wah !
    Bonjour,

    Déjà merci pour ce bout d'infos.

    Bien décidé d'en découdre, avec quelques explications données ci-dessus, voila ce que j'ai pu réalisé

    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
     
    #!/usr/bin/python
    # -*- coding: iso-8859-1 -*-
     
    # -- INCLUDE --
    import Tkinter as tk
     
    # -- CLASSE --
    class test_tk(tk.Tk):
     
    	# -- CONSTRUCTEUR --
    	def __init__(self, parent):
    		tk.Tk.__init__(self, parent)
    		self.parent = parent
    		self.initialize()
     
    	# -- INITIALISATION DE LA FENETRE --	
    	def initialize(self):
    		self.grid()	#Grille
     
    		# Les boutons de gauche
    		self.entryLeft = tk.Entry(self)				#Widget gauche
    		self.entryLeft.grid(column=0, row=0, sticky='EW')
     
    		buttonG1 = tk.Button(self.entryLeft, text="Roues : Gauche")
    		buttonG1.grid(column=0, row=0)
     
    		buttonSP = tk.Button(self.entryLeft, text="Roues : Sur Place")
    		buttonSP.grid(column=1, row=0)
     
    		buttonD1 = tk.Button(self.entryLeft, text="Roues : Droite")
    		buttonD1.grid(column=2, row=0)
     
    		buttonC1 = tk.Button(self.entryLeft, text="Roues : Centre")
    		buttonC1.grid(column=1, row=1)
     
    		# Les boutons de droite
    		self.entryRight = tk.Entry(self)				#Widget droite
    		self.entryRight.grid(column=1, row=0, sticky='EW')
     
    		buttonG2 = tk.Button(self.entryRight, text="Roues : Gauche")
    		buttonG2.grid(column=0, row=1)
     
    		buttonA1 = tk.Button(self.entryRight, text="Avancer")
    		buttonA1.grid(column=1, row=0)
     
    		buttonC2 = tk.Button(self.entryRight, text="Roues : Centre")
    		buttonC2.grid(column=1, row=1)
     
    		buttonR1 = tk.Button(self.entryRight, text="Reculer")
    		buttonR1.grid(column=1, row=2)
     
    		buttonD2 = tk.Button(self.entryRight, text="Roues : Droite")
    		buttonD2.grid(column=2, row=1)
     
    # -- ICI J'AI PAS TROP COMPRIS COMMENT CA FONCTIONNE
    if __name__ == "__main__":
    	app = test_tk(None)
    	app.title('test tk')
    	app.mainloop()			#Boucler
    Je ne dis pas que c'est parfait mais je comprends mieux ce qui se passe. On peut dire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    # Fenêtre
    #	+ Grid
    #		+ Widget Gauche
    #			+ Grid
    #				+ Boutons à gauche
    #		+ Widget Droite
    #			+ Grid
    #				+ Boutons à Droite
    On voie très bien que j'ai utilisé Grid à plusieurs reprise, si je ne me trompe pas.

    Et maintenant, deux choses :
    - La portion de code en bas que j'aimerais mieux appréhender
    - Ajouter un système qui grise en fonction de l'appuie sur certains boutons. Voir la suite plus bas...

    Suite !
    Alors, mettons que je démarre mon appli. Au départ les boutons de gauches sont désactivés. Normal la séquence sur le robot place les roues au centre. A l'exception du bouton "Roues : Sur Place" qui sert de sélecteur, les autres boutons sont grisés. En revanche, si je clique sur ce même boutons, je grise ceux de droite à l'exception de "Roues : Centre" de droite qui fera alors office de sélecteur.

    On va y aller pas à pas mais déjà on aura avancé d'un chouilla.

    Merci.

  4. #4
    Membre éprouvé
    Homme Profil pro
    Aucune activité
    Inscrit en
    Novembre 2011
    Messages
    505
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Aucune activité

    Informations forums :
    Inscription : Novembre 2011
    Messages : 505
    Points : 926
    Points
    926
    Par défaut
    Citation Envoyé par Caxton Voir le message
    Déjà merci pour ce bout d'infos.
    Bien décidé d'en découdre, avec quelques explications données ci-dessus, voila ce que j'ai pu réalisé
    Bonjour,
    Les bouts d'info sont peut-être trop denses: sauf cas particulier, placer des boutons dans une entrée est inadapté.

    Citation Envoyé par Caxton Voir le message
    - Ajouter un système qui grise en fonction de l'appuie sur certains boutons. Voir la suite plus bas...
    Là, il pourrait commencer à être efficace de lire (ou au moins parcourir) le manuel de tkinter…
    - ce serait bien de regrouper les boutons de chacun des cotés dans une classe de manière à pouvoir les manipuler ensemble.
    - l'option state des boutons permet de les rendre actifs ou non (option: state; valeurs: tk.DISABLED, tk.ACTIVE et tk.NORMAL).

    Citation Envoyé par Caxton Voir le message
    - La portion de code en bas que j'aimerais mieux appréhender
    Cette condition n'est donc pas de vous?
    En bref: le nom du script lancé est "__main__". Tester cela permet de n'exécuter un code que s'il est exécuté comme script principal. Au contraire, si ce script est appelé par un inport, cette condition sera fausse et les instructions suivantes ne seront pas exécutées. Cela permet de tester des scripts de manière individuelle.

    Vous avez absolument tous les éléments pour atteindre votre objectif.

    Clodion

  5. #5
    Membre régulier Avatar de Caxton
    Homme Profil pro
    Sans
    Inscrit en
    Janvier 2005
    Messages
    586
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Corrèze (Limousin)

    Informations professionnelles :
    Activité : Sans

    Informations forums :
    Inscription : Janvier 2005
    Messages : 586
    Points : 123
    Points
    123
    Par défaut
    Ah oui, en effet, j'ai maintenant pas mal de choses et plusieurs pistes.

    Citation Envoyé par Clodion Voir le message
    Cette condition n'est donc pas de vous?
    En effet, cela proviens d'un exercice très succinct.

    Donc, je vais commencé par résoudre le bout de code en bas. Remplacer le commentaire pour m'y retrouver. Si j'ai bon, je garde, sinon, je reformulerais le commentaire.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    # -- SI LE SCRIPT EST __main__
    if __name__ == "__main__":
    	app = test_tk(None)
    	app.title('test tk')	#Titre de l'application
    	app.mainloop()			#Boucler
    Citation Envoyé par Clodion Voir le message
    Bonjour,
    Les bouts d'info sont peut-être trop denses: sauf cas particulier, placer des boutons dans une entrée est inadapté.

    Là, il pourrait commencer à être efficace de lire (ou au moins parcourir) le manuel de tkinter…
    - ce serait bien de regrouper les boutons de chacun des cotés dans une classe de manière à pouvoir les manipuler ensemble.
    - l'option state des boutons permet de les rendre actifs ou non (option: state; valeurs: tk.DISABLED, tk.ACTIVE et tk.NORMAL).
    Oh ! Inadapté ? Comment ça ?
    En revanche, je pense avoir une petite idée mais avant j'aimerais être sûr que je ne parte pas dans la mauvaise direction. Ok pour parcourir le manuel de tkinter. (D'ailleurs quelle est le lien le plus efficace ? Je dis ça car mes recherches n'ont pas donné de bons résultats pour le moment.)

    Faut-il donc que je fasse une classe btnGauche et btnDroite ? Si oui, un petit constructeur. Sauf que du coup, comment ensuite les ajoutés dans la fenêtre ? Je sait pas trop ! Voyons déjà à quoi devrais ressembler la classe gauche (sachant que c'est idem pour l'autre côté).
    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
     
    # -- CLASSE --
    class btnGauche():
     
    	# -- CONSTRUCTEUR --
    	def __init__():
    		self.grid()	#Grille
     
    		# Les boutons de gauche
    		self.entryLeft = tk.Entry(self)				#Widget gauche
    		self.entryLeft.grid(column=0, row=0, sticky='EW')
     
    		buttonG1 = tk.Button(self.entryLeft, text="Roues : Gauche")
    		buttonG1.grid(column=0, row=0)
     
    		buttonSP = tk.Button(self.entryLeft, text="Roues : Sur Place")
    		buttonSP.grid(column=1, row=0)
     
    		buttonD1 = tk.Button(self.entryLeft, text="Roues : Droite")
    		buttonD1.grid(column=2, row=0)
     
    		buttonC1 = tk.Button(self.entryLeft, text="Roues : Centre")
    		buttonC1.grid(column=1, row=1)
    Est-ce que je suis sur la bonne piste ?

  6. #6
    Membre éprouvé
    Homme Profil pro
    Aucune activité
    Inscrit en
    Novembre 2011
    Messages
    505
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Aucune activité

    Informations forums :
    Inscription : Novembre 2011
    Messages : 505
    Points : 926
    Points
    926
    Par défaut
    Citation Envoyé par Caxton Voir le message
    Oh ! Inadapté ? Comment ça ?
    Bonjour,
    Frame, parce que c'est son rôle de contenir d'autres widgets. L'entrée est pour entrer du texte (même si elle peut aussi contenir d'autres widgets)…

    Citation Envoyé par Caxton Voir le message
    D'ailleurs quelle est le lien le plus efficace ? Je dis ça car mes recherches n'ont pas donné de bons résultats pour le moment.
    Sur le site officiel de Python, rubrique tkinter (https://docs.python.org/3.4/library/tkinter.html), on trouve, entre autre: http://infohost.nmt.edu/tcc/help/pub...web/index.html
    Ainsi que bien d'autres liens.

    Citation Envoyé par Caxton Voir le message
    Sauf que du coup, comment ensuite les ajoutés dans la fenêtre ?
    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
    import tkinter as tk
     
    class Pan1(tk.Frame):
        def __init__(self, parent):
            self.parent = parent
            tk.Frame.__init__(self, self.parent)
            self.bt = tk.Button(self, text="bt1")
            self.bt.pack()
     
    class Pan2(tk.Frame):
        def __init__(self, parent):
            self.parent = parent
            tk.Frame.__init__(self, self.parent)
            self.bt = tk.Button(self, text="bt2")
            self.bt.pack()
     
    mon_app = tk.Tk()
    pan1=Pan1(mon_app)
    pan1.grid(column = 0, row = 0)
    pan2=Pan2(mon_app)
    pan2.grid(column = 1, row = 0)
     
    mon_app.mainloop()
    Il faudra sans doutes remplacer l'import de tkinter par l'import de Tkinter (je suis en version Python 3).

    Bien sûr, dans chaque classe, il est possible de dresser une liste des boutons et de définir des fonctions.

    Citation Envoyé par Caxton Voir le message
    Est-ce que je suis sur la bonne piste ?
    Sinon, il suffit de réaliser quelques essais et de voir ce que cela produit.

    Clodion

  7. #7
    Membre régulier Avatar de Caxton
    Homme Profil pro
    Sans
    Inscrit en
    Janvier 2005
    Messages
    586
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Corrèze (Limousin)

    Informations professionnelles :
    Activité : Sans

    Informations forums :
    Inscription : Janvier 2005
    Messages : 586
    Points : 123
    Points
    123
    Par défaut
    Bon, je suis un peu perdu là.

    Alors, oui, chez moi ça fonctionne bien pour 2 boutons. Mais dès que je veux les organisés en grille, comme avant (et c'était pas trop mal d'ailleurs), je m'en sort pas.

    Donc à ce stade, je me dis, si je crée une Frame (enfin bon), je dois pouvoir mettre une grille dedans non ? Et plus bas, je voie bien un grid mais il est pas déclaré plus haut

    Bref, pas compris l'exemple là.

    Je part sur la doc en attendant d'y voir plus clair.

  8. #8
    Membre éprouvé
    Homme Profil pro
    Aucune activité
    Inscrit en
    Novembre 2011
    Messages
    505
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Aucune activité

    Informations forums :
    Inscription : Novembre 2011
    Messages : 505
    Points : 926
    Points
    926
    Par défaut
    Citation Envoyé par Caxton Voir le message
    Alors, oui, chez moi ça fonctionne bien pour 2 boutons. Mais dès que je veux les organisés en grille, comme avant (et c'était pas trop mal d'ailleurs), je m'en sort pas.
    Bonsoir,
    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
    import tkinter as tk
     
    class Pan1(tk.Frame):
        def __init__(self, parent):
            self.parent = parent
            tk.Frame.__init__(self, self.parent)
            self.bt1 = tk.Button(self, text="bt1")
            self.bt1.grid(column=0, row=0)
            self.bt2 = tk.Button(self, text="bt1.2")
            self.bt2.grid(column=0, row=1)
     
    class Pan2(tk.Frame):
        def __init__(self, parent):
            self.parent = parent
            tk.Frame.__init__(self, self.parent)
            self.bt1 = tk.Button(self, text="bt2")
            self.bt1.grid(column=0, row=0)
            self.bt2 = tk.Button(self, text="bt2.2")
            self.bt2.grid(column=1, row=0)
     
    mon_app = tk.Tk()
    pan1=Pan1(mon_app)
    pan1.grid(column = 0, row = 0)
    pan2=Pan2(mon_app)
    pan2.grid(column = 1, row = 0)
    Je ne peux guère être plus explicite.
    Il n'y a pas "besoin" de créer une grille. Dès son invocation elle est mise en place.

    "pan1" et "pan2" sont sur la grille de "mon_app".
    Les boutons de pan1 sont dans la grille de pan1… Même processus pour les boutons de pan2.

    Clodion

  9. #9
    Membre régulier Avatar de Caxton
    Homme Profil pro
    Sans
    Inscrit en
    Janvier 2005
    Messages
    586
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Corrèze (Limousin)

    Informations professionnelles :
    Activité : Sans

    Informations forums :
    Inscription : Janvier 2005
    Messages : 586
    Points : 123
    Points
    123
    Par défaut Je le tiens... Je l'aurais :)
    Bon, alors, je comprends un peux mieux ce qui se passe ! Il vaut mieux ceci-dit...

    Alors, si je ne me trompe pas, le grid est hérité de Frame : http://fossies.org/dox/Tix8.4.3-src/..._1_1Frame.html

    Du coup, c'est logique qu'on ais pas à le déclarer !

    Du coup, une nouvelle fois, j'attaque la suite de l'implémentation. Restera à faire le système pour griser. Là, j'essaie d'abord et je reviens dans le fil pour en parler.

    En attendant, il n'est pas interdit d'enrichir ce tread avec des infos ou autres solutions.

    Aller, zou, au codage !

  10. #10
    Membre régulier Avatar de Caxton
    Homme Profil pro
    Sans
    Inscrit en
    Janvier 2005
    Messages
    586
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Corrèze (Limousin)

    Informations professionnelles :
    Activité : Sans

    Informations forums :
    Inscription : Janvier 2005
    Messages : 586
    Points : 123
    Points
    123
    Par défaut Double post mais... Y a de l'évolution :D
    Et re voila....

    Bon, cette fois-ci j'ai légèrement corsé mon histoire pour avoir le minimum vital de pilotage. Cela reste une interface très basique ! C'est voulue pour la petite histoire.

    Niveau code, comment ça se passe ?
    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
     
    # -- IMPORTATION --
     
    import Tkinter as tk
    #import tkinter as tk
     
    # -- CLASSE FRAME GAUCHE --
    class Pan1(tk.Frame):
        def __init__(self, parent):
            self.parent = parent
            tk.Frame.__init__(self, self.parent)
     
            self.lFControleDirection = tk.LabelFrame(self, text="Tourner sur place", padx=20, pady=20) 
            self.lFControleDirection.grid(column=0, row=0)
     
            self.btRG1 = tk.Button(self.lFControleDirection, text="Tourner : gauche")
            self.btRG1.grid(column=0, row=0)
            self.btSP = tk.Button(self.lFControleDirection, text="Roues : Sur Place")
            self.btSP.grid(column=1, row=0)
            self.btRD1 = tk.Button(self.lFControleDirection, text="Tourner : droite")
            self.btRD1.grid(column=2, row=0)
            self.btRC1 = tk.Button(self.lFControleDirection, text="Roues : Centre")
            self.btRC1.grid(column=1, row=1)
     
    # -- CLASSE FRAME DROITE --
    class Pan2(tk.Frame):
        def __init__(self, parent):
            self.parent = parent
            tk.Frame.__init__(self, self.parent)
     
            self.lFSpeed = tk.LabelFrame(self, text="Vitesse", padx=20, pady=20)
            self.lFSpeed.grid(column=0, row=0)
            self.sliderSpeed = tk.Scale(self.lFSpeed, from_=100, to=50, tickinterval=2)
            self.sliderSpeed.grid(column=0, row=0)
     
            self.lFControleDirect = tk.LabelFrame(self, text="Controle", padx=20, pady=20) 
            self.lFControleDirect.grid(column=1, row=0)
            self.btAV = tk.Button(self.lFControleDirect, text="Avancer")
            self.btAV.grid(column=2, row=0)
            self.btRG2 = tk.Button(self.lFControleDirect, text="Roues : Gauche")
            self.btRG2.grid(column=1, row=1)
            self.btRC2 = tk.Button(self.lFControleDirect, text="Roue : Centre")
            self.btRC2.grid(column=2, row=1)
            self.btRD2 = tk.Button(self.lFControleDirect, text="Roues : Droite")
            self.btRD2.grid(column=3, row=1)
            self.btAR = tk.Button(self.lFControleDirect, text="Reculer")
            self.btAR.grid(column=2, row=2)
     
    mon_app = tk.Tk()	#Instancie la classe
     
    pan1=Pan1(mon_app)	#Panneau Gauche
    pan1.grid(column = 0, row = 0)
     
    pan2=Pan2(mon_app)	#PAnneau Droite
    pan2.grid(column = 1, row = 0)
     
    mon_app.title('POSL Rover')
    mon_app.mainloop()	#Boucler
    Et maintenant, passons aux petites améliorations.

    - J'aimerais mettre tous les labels à la même hauteur.
    - J'aimerais ensuite grisé certains boutons mais les dégrisés en fonction des choix. Sauf que là, je ne sait pas trop comment m'y prendre. Existerais-t-il un exemple avec 2 boutons ? Genre bouton "A" et bouton "B" et "C". "A" et "B" sont activés par défaut et "C" non. "C" est dans le même groupe que "B". Si je clique sur "B", on grisera "A" et on dégrise "C". Mais il faudra trouvé une astuce pour dégrisé "A" plus tard.

    Je ne sait pas si y a moyen de faire une sélection. J'avais pensé en secours à un bouton radio qui serais remplacer par un jeu de flèches. Si je clique sur la flèche gauche, on désactive la partie à droite et vise-versa. C'est peut-être plus simple remarque. Là à ce stade je n'en sait rien.

    Partons donc sur cette seconde solution, simple et viable.

    Merci.

  11. #11
    Membre éprouvé
    Homme Profil pro
    Aucune activité
    Inscrit en
    Novembre 2011
    Messages
    505
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Aucune activité

    Informations forums :
    Inscription : Novembre 2011
    Messages : 505
    Points : 926
    Points
    926
    Par défaut
    Citation Envoyé par Caxton Voir le message
    Et re voila....

    Bon, cette fois-ci j'ai légèrement corsé mon histoire pour avoir le minimum vital de pilotage. Cela reste une interface très basique ! C'est voulue pour la petite histoire.
    Et maintenant, passons aux petites améliorations.

    - J'aimerais mettre tous les labels à la même hauteur.
    - J'aimerais ensuite grisé certains boutons mais les dégrisés en fonction des choix. Sauf que là, je ne sait pas trop comment m'y prendre. Existerais-t-il un exemple avec 2 boutons ? Genre bouton "A" et bouton "B" et "C". "A" et "B" sont activés par défaut et "C" non. "C" est dans le même groupe que "B". Si je clique sur "B", on grisera "A" et on dégrise "C". Mais il faudra trouvé une astuce pour dégrisé "A" plus tard.

    Je ne sait pas si y a moyen de faire une sélection. J'avais pensé en secours à un bouton radio qui serais remplacer par un jeu de flèches. Si je clique sur la flèche gauche, on désactive la partie à droite et vise-versa. C'est peut-être plus simple remarque. Là à ce stade je n'en sait rien.

    Partons donc sur cette seconde solution, simple et viable.
    Merci.
    Bonjour,
    Donc, maintenant il y a trois parties. LabelFrame dans une Frame et dans une autre Frame, deux LabelFrame…
    Les LabelFrame ont le même rôle que les Frame! Il est donc inutile, au moins pour pan1 de le mettre dans une Frame (puisqu'il est ensuite mis dans une LabelFrame).
    Tous les labels à la même hauteur? Il suffit que les trois éléments LabelFrame soient dans la même grille (cela vous savez le faire) et positionnés dans la même ligne, avec une petite option (que l'on trouve dans le manuel de tkinter).

    Vous devez savoir griser un bouton (cf les posts précédents). Vous devez aussi savoir utiliser les listes… Ici une liste des boutons de chaque panneau permet de boucler sur ces boutons afin de les griser/dégriser…
    Il suffit donc d'ajouter une fonction dans les classes concernées qui utilise la liste des boutons pour les griser/dégriser…

    Vous savez absolument tout faire avec un minimum de Python! (création de liste, griser/dégriser un bouton, création de fonction…)

    Clodion

  12. #12
    Membre régulier Avatar de Caxton
    Homme Profil pro
    Sans
    Inscrit en
    Janvier 2005
    Messages
    586
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Corrèze (Limousin)

    Informations professionnelles :
    Activité : Sans

    Informations forums :
    Inscription : Janvier 2005
    Messages : 586
    Points : 123
    Points
    123
    Par défaut Un upgrade en Python 3 est possible ?
    Bonjour,

    Alors, au point de vue interface, du coup, j'ai mis 4 classes. Une est dédié aux commandes spéciales, la seconde au centre à la vitesse, la troisième, à droite c'est le contrôle générale. J'en ai ajouter une autre tout en bas contenant un tK.Text(). J'ai un petit souci dessus, j'y reviendrais plus tard.

    Du coup, j'ai ajouté mes 4 classes à mon application, ça semble bien fonctionner. On va même dire parfait !

    Je commence à chercher des infos pour grisés en haut mais je suis loin du compte ! On y reviendra plus tard dans un autre post dans la journée.

    Pour en revenir au Text(), j'ai aperçu une option tel que wrap=WORD. Sauf que, chez moi, ça plante ! Donc je me dis que j'ai pas la bonne instruction, ou bien j'ai pas su retrouver la bonne info.

    Je place quand même le petit bout de code concerné (raccourci car on connais le reste de l'application).

    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
     
    # -- IMPORTATION --
     
    import Tkinter as tk
    #import tkinter as tk
     
    import serial
     
    #Ici il faudra prévoir le cas ou la connexion échoue -> écrire dans le log est une bonne solution. Ajouter de nouveaux contrôles aussi.
    #ser = serial.Serial('/dev/ttyUSB0', 9600)
     
    # -- CLASSE FRAME GAUCHE --
    # Ici je raccourci mon code car il n'y a rien de nouveau.
     
    # -- CLASSE FRAME CENTRALE --
    class Pan2(tk.Frame):
        def __init__(self, parent):
            self.parent = parent
            tk.Frame.__init__(self, self.parent)
     
            self.lFSpeed = tk.LabelFrame(self, text="Vitesse", padx=20, pady=20)
            self.lFSpeed.grid(column=0, row=0, sticky='NS')
            self.sliderSpeed = tk.Scale(self.lFSpeed, from_=100, to=50, tickinterval=2)
            self.sliderSpeed.grid(column=0, row=0)
     
    # -- CLASSE FRAME DROITE --
    class Pan3(tk.Frame):
        def __init__(self, parent):
            self.parent = parent
            tk.Frame.__init__(self, self.parent)
     
            self.lFControleDirect = tk.LabelFrame(self, text="Controle", padx=20, pady=20) 
            self.lFControleDirect.grid(column=1, row=0, sticky='NS')
            self.btAV = tk.Button(self.lFControleDirect, text="Avancer")
            self.btAV.grid(column=1, row=0)
            self.btRG2 = tk.Button(self.lFControleDirect, text="Roues : Gauche")
            self.btRG2.grid(column=0, row=1)
            self.btRC2 = tk.Button(self.lFControleDirect, text="Roue : Centre")
            self.btRC2.grid(column=1, row=1)
            self.btRD2 = tk.Button(self.lFControleDirect, text="Roues : Droite")
            self.btRD2.grid(column=2, row=1)
            self.btAR = tk.Button(self.lFControleDirect, text="Reculer")
            self.btAR.grid(column=1, row=2)
     
    # -- CLASSE FRAME DESSOUS (LOG) --
    class Pan4(tk.Frame):
        def __init__(self, parent):
            self.parent = parent
            tk.Frame.__init__(self, self.parent)
     
            self.log = tk.Text(self, height=10, width=100)
            self.log.grid(column=0, row=0)
            self.log.insert('1.0', 'Log du programme')
     
    mon_app = tk.Tk()	#Instancie la classe
     
    pan1=Pan1(mon_app)	#Panneau Gauche
    pan1.grid(column = 0, row = 0, sticky='N')
     
    pan2=Pan2(mon_app)	#PAnneau Centrale
    pan2.grid(column = 1, row = 0, sticky='N')
     
    pan3=Pan3(mon_app)	#PAnneau Droite
    pan3.grid(column = 2, row = 0, sticky='N')
     
    pan4=Pan4(mon_app)	#PAnneau Dessous (LOG)
    pan4.grid(column = 0, row = 1, columnspan = 3)
     
    mon_app.title('POSL Rover')
    mon_app.mainloop()	#Boucler
    Bien, revenons alors au log déjà mais avant, peut-on mettre à jour python vers la version 3 ? Si oui, comment sous Linux Ubuntu ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    $ lsb_release -a
    No LSB modules are available.
    Distributor ID:	Ubuntu
    Description:	Ubuntu 12.04.5 LTS
    Release:	12.04
    Codename:	precise
    Merci.

  13. #13
    Membre éprouvé
    Homme Profil pro
    Aucune activité
    Inscrit en
    Novembre 2011
    Messages
    505
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Aucune activité

    Informations forums :
    Inscription : Novembre 2011
    Messages : 505
    Points : 926
    Points
    926
    Par défaut
    Citation Envoyé par Caxton Voir le message
    Alors, au point de vue interface, du coup, j'ai mis 4 classes. Une est dédié aux commandes spéciales, la seconde au centre à la vitesse, la troisième, à droite c'est le contrôle générale. J'en ai ajouter une autre tout en bas contenant un tK.Text().
    Bonjour,
    C'est déjà plus clair…
    Pourquoi ne pas faire, lorsque c'est nécessaire, des classes de type: "class Pan1(tk.LabelFrame)"? Cela supprimerait un étage…

    Citation Envoyé par Caxton Voir le message
    Je commence à chercher des infos pour grisés en haut mais je suis loin du compte !
    Toutes les informations nécessaires sont sur cette page! Et avec les options!

    Citation Envoyé par Caxton Voir le message
    Pour en revenir au Text(), j'ai aperçu une option tel que wrap=WORD. Sauf que, chez moi, ça plante ! Donc je me dis que j'ai pas la bonne instruction, ou bien j'ai pas su retrouver la bonne info.
    Chez moi, aucun problème, avec Python3.4 et Python2.7… Mais sans l'erreur complète et sans le code, compliqué de deviner l'origine du problème…

    Citation Envoyé par Caxton Voir le message
    peut-on mettre à jour python vers la version 3 ? Si oui, comment sous Linux Ubuntu ?
    Sous Ubuntu, on ne peut pas mettre à jour la version de base (elle est utilisée par le système).
    Par contre, Ubuntu accepte sans problème d'avoir plusieurs versions de Python installées en parallèle.
    Pour cela il suffit, de chercher Python3 dans Synaptic ou dans la logithèque. Sans oublier IDLE3 qui va avec!

    Par contre, la 12.04 commence à vieillir…

    Clodion

  14. #14
    Membre régulier Avatar de Caxton
    Homme Profil pro
    Sans
    Inscrit en
    Janvier 2005
    Messages
    586
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Corrèze (Limousin)

    Informations professionnelles :
    Activité : Sans

    Informations forums :
    Inscription : Janvier 2005
    Messages : 586
    Points : 123
    Points
    123
    Par défaut
    Citation Envoyé par Clodion Voir le message
    Bonjour,
    C'est déjà plus clair…
    Pourquoi ne pas faire, lorsque c'est nécessaire, des classes de type: "class Pan1(tk.LabelFrame)"? Cela supprimerait un étage…
    Oh... J'y avais pas songé ! Mais ça semble être une solution. Pour le moment ça me va tel que.

    Citation Envoyé par Clodion Voir le message
    Toutes les informations nécessaires sont sur cette page! Et avec les options!
    Oui, et j'ai fais un petit essais qui démontre que cela fonctionne.

    Citation Envoyé par Clodion Voir le message
    Chez moi, aucun problème, avec Python3.4 et Python2.7… Mais sans l'erreur complète et sans le code, compliqué de deviner l'origine du problème…
    Et oui, en effet, voila le problème et son source
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    # -- CLASSE FRAME DESSOUS (LOG) --
    class Pan4(tk.Frame):
        def __init__(self, parent):
            self.parent = parent
            tk.Frame.__init__(self, self.parent)
     
            self.log = tk.Text(self, height=10, width=100, wrap=WORD)
            self.log.grid(column=0, row=0)
            self.log.insert('1.0', 'Log du programme')
    $ python POSL-Rover.py
    Traceback (most recent call last):
    File "POSL-Rover.py", line 100, in <module>
    pan4=Pan4(mon_app) #PAnneau Dessous (LOG)
    File "POSL-Rover.py", line 85, in __init__
    self.log = tk.Text(self, height=10, width=100, wrap=WORD)
    NameError: global name 'WORD' is not defined
    Citation Envoyé par Clodion Voir le message
    Sous Ubuntu, on ne peut pas mettre à jour la version de base (elle est utilisée par le système).
    Par contre, Ubuntu accepte sans problème d'avoir plusieurs versions de Python installées en parallèle.
    Pour cela il suffit, de chercher Python3 dans Synaptic ou dans la logithèque. Sans oublier IDLE3 qui va avec!

    Par contre, la 12.04 commence à vieillir…

    Clodion
    Oh ça pour vieillir... Effectivement je pense changer dans quelques temps. Mais pour l'heure j'en suis resté sur cette installation qui fonctionne parfaitement. Et pour ce que je veux en faire, pourquoi réinstallé ce qui fonctionne très bien. Ors de question de faire la migration pour cause de perte de datas.

    Ok, il suffirais donc que je cherche dan sla logitèque C'est juste parfait. Je tente

  15. #15
    Membre éprouvé
    Homme Profil pro
    Aucune activité
    Inscrit en
    Novembre 2011
    Messages
    505
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Aucune activité

    Informations forums :
    Inscription : Novembre 2011
    Messages : 505
    Points : 926
    Points
    926
    Par défaut
    Citation Envoyé par Caxton Voir le message
    Et oui, en effet, voila le problème et son source
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    # -- CLASSE FRAME DESSOUS (LOG) --
    class Pan4(tk.Frame):
        def __init__(self, parent):
            self.parent = parent
            tk.Frame.__init__(self, self.parent)
     
            self.log = tk.Text(self, height=10, width=100, wrap=WORD)
            self.log.grid(column=0, row=0)
            self.log.insert('1.0', 'Log du programme')
    $ python POSL-Rover.py
    Traceback (most recent call last):
    File "POSL-Rover.py", line 100, in <module>
    pan4=Pan4(mon_app) #PAnneau Dessous (LOG)
    File "POSL-Rover.py", line 85, in __init__
    self.log = tk.Text(self, height=10, width=100, wrap=WORD)
    NameError: global name 'WORD' is not defined
    Bonjour,
    Ainsi que l'annonce le message, le mot WORD n'est pas défini…
    Une suite de caractère est une variable… Ici la variable n'est pas définie antérieurement.
    Il y a deux manières de faire: utiliser les variables déclarées par tkinter (tk.WORD) ou utiliser leurs valeurs ("word")…


    Citation Envoyé par Caxton Voir le message
    Oh ça pour vieillir... Effectivement je pense changer dans quelques temps. Mais pour l'heure j'en suis resté sur cette installation qui fonctionne parfaitement. Et pour ce que je veux en faire, pourquoi réinstallé ce qui fonctionne très bien. Ors de question de faire la migration pour cause de perte de datas.
    Oui, entièrement d'accord… Sauf lorsque l'on a besoin de mettre à jour des logiciels tiers ou des bibliothèques…

    Clodion

  16. #16
    Membre régulier Avatar de Caxton
    Homme Profil pro
    Sans
    Inscrit en
    Janvier 2005
    Messages
    586
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Corrèze (Limousin)

    Informations professionnelles :
    Activité : Sans

    Informations forums :
    Inscription : Janvier 2005
    Messages : 586
    Points : 123
    Points
    123
    Par défaut Yes ! Mais maintenant... je me retrouve avec un autre problème hihi :)
    Ce n'est pas encore automatique pour moi le coup du tk.WORD. Mais cette fois-ci ça fonctionne.

    Alors, à partir de là, je bascule sur le souci suivant. Un problème avec la partie import serial... En effet, pour que mon robot puisse recevoir des données, je passe par une liaison série sans fil. Tout se passe merveilleusement bien si je pense à brancher mon interface avant de lancer l'application. Dans le cas contraire ça plante.

    Et ça plante par ce que je n'ai pas coder la partie détection. Il cherche à y accéder et si non présent, ça plante. C'est là que le log intervient. Si erreur, on indique mais on plante pas. Il faudra relancer l'interface pyton (c'est voulue ainsi dans un premier temps).

    Mais avant de coder la suite, laissez moi vous parler de ceci. Qui dit serie, dit serial et donc dit "import serial". Comme ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    # -- IMPORTATION --
     
    #import Tkinter as tk
    import tkinter as tk
     
    import serial
     
    #S'en suit la suite du code déjà connu
    Et vlan ! Mange ton erreur sous Python 3

    Python 3.2.3 (default, Feb 27 2014, 21:31:18)
    [GCC 4.6.3] on linux2
    Type "copyright", "credits" or "license()" for more information.
    ==== No Subprocess ====
    >>>
    Traceback (most recent call last):
    File "/home/alexandre/Bureau/Python/POSL-Rover.py", line 6, in <module>
    import serial
    ImportError: No module named serial
    >>>
    Et là je me dis que je ne suis pas au bout de mes peines
    Mais j'y arriverais.

    Merci

  17. #17
    Membre régulier Avatar de Caxton
    Homme Profil pro
    Sans
    Inscrit en
    Janvier 2005
    Messages
    586
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Corrèze (Limousin)

    Informations professionnelles :
    Activité : Sans

    Informations forums :
    Inscription : Janvier 2005
    Messages : 586
    Points : 123
    Points
    123
    Par défaut ... Et galères !
    Bon, un petit tour sous Synaptic ; j'ai coché la case pyserial3 et j'ai appliqué
    Cela fonctionne à présent !

    Je dois maintenant comprendre un autre souci d'interface. Quand je clique sur mes boutons, tout semble bon, puisque mes print s'affichent. Mais l'actualisation des boutons non

    Voila donc ou j'en suis :
    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
    #!/usr/bin/python
    # -*- coding: iso-8859-15 -*-
     
    # -- IMPORTATION --
     
    #import Tkinter as tk
    import tkinter as tk
     
    import serial
     
    #ser = serial.Serial('/dev/ttyUSB0', 9600)
     
    # -- VARIABLES --
    #Déclarer à l'interface que l'on utilisera les boutons de gauche
    btnsGauche = 0
    btnsDroite = 1
     
    # -- CLASSE FRAME GAUCHE --
    class Pan1(tk.Frame):
        def __init__(self, parent):
            self.parent = parent
            tk.Frame.__init__(self, self.parent)
     
            self.lFControleDirection = tk.LabelFrame(self, text="Tourner sur place", padx=20, pady=20)
     
            if btnsGauche == 0 :
                self.btRG1 = tk.Button(self.lFControleDirection, text="Tourner : gauche", state=tk.DISABLED, command=tournerGaucheSurPlace)
                self.btSP = tk.Button(self.lFControleDirection, text="Roues : Sur Place", state=tk.NORMAL, command=rouesSurPlace)
                self.btRD1 = tk.Button(self.lFControleDirection, text="Tourner : droite", state=tk.DISABLED, command=tournerDroiteSurPlace)
                self.btRC1 = tk.Button(self.lFControleDirection, text="Roues : Centre", state=tk.NORMAL, command=rouesCentre)
            else :
                self.btRG1 = tk.Button(self.lFControleDirection, text="Tourner : gauche", state=tk.NORMAL, command=tournerGaucheSurPlace)
                self.btSP = tk.Button(self.lFControleDirection, text="Roues : Sur Place", state=tk.NORMAL, command=rouesSurPlace)
                self.btRD1 = tk.Button(self.lFControleDirection, text="Tourner : droite", state=tk.NORMAL, command=tournerDroiteSurPlace)
                self.btRC1 = tk.Button(self.lFControleDirection, text="Roues : Centre", state=tk.NORMAL, command=rouesCentre)
     
            #Positionnement dans la grille
            self.lFControleDirection.grid(column=0, row=0)
            self.btRG1.grid(column=0, row=0)
            self.btSP.grid(column=1, row=0)
            self.btRD1.grid(column=2, row=0)
            self.btRC1.grid(column=1, row=1)
     
    # -- CLASSE FRAME CENTRALE --
    class Pan2(tk.Frame):
        def __init__(self, parent):
            self.parent = parent
            tk.Frame.__init__(self, self.parent)
     
            self.lFSpeed = tk.LabelFrame(self, text="Vitesse", padx=20, pady=20)
            self.lFSpeed.grid(column=0, row=0, sticky='NS')
            self.sliderSpeed = tk.Scale(self.lFSpeed, from_=100, to=50, tickinterval=2)
            self.sliderSpeed.grid(column=0, row=0)
     
    # -- CLASSE FRAME DROITE --
    class Pan3(tk.Frame):
        def __init__(self, parent):
            self.parent = parent
            tk.Frame.__init__(self, self.parent)
            self.lFControleDirect = tk.LabelFrame(self, text="Controle", padx=20, pady=20)
     
            if btnsDroite == 0 :
                self.btAV = tk.Button(self.lFControleDirect, text="Avancer", state=tk.DISABLED, command=avancer)
                self.btRG2 = tk.Button(self.lFControleDirect, text="Roues : Gauche", state=tk.NORMAL, command=rouesGauche)
                self.btRC2 = tk.Button(self.lFControleDirect, text="Roue : Centre", state=tk.NORMAL, command=rouesCentre)
                self.btRD2 = tk.Button(self.lFControleDirect, text="Roues : Droite", state=tk.NORMAL, command=rouesDroite)
                self.btAR = tk.Button(self.lFControleDirect, text="Reculer", state=tk.DISABLED, command=reculer)
     
            else :
                self.btAV = tk.Button(self.lFControleDirect, text="Avancer", state=tk.NORMAL, command=avancer)
                self.btRG2 = tk.Button(self.lFControleDirect, text="Roues : Gauche", state=tk.NORMAL, command=rouesGauche)
                self.btRC2 = tk.Button(self.lFControleDirect, text="Roue : Centre", state=tk.NORMAL, command=rouesCentre)
                self.btRD2 = tk.Button(self.lFControleDirect, text="Roues : Droite", state=tk.NORMAL, command=rouesDroite)
                self.btAR = tk.Button(self.lFControleDirect, text="Reculer", state=tk.NORMAL, command=reculer)
     
            #Positionnement dans la grille
            self.lFControleDirect.grid(column=1, row=0, sticky='NS')
            self.btAV.grid(column=1, row=0)
            self.btRG2.grid(column=0, row=1)
            self.btRC2.grid(column=1, row=1)
            self.btRD2.grid(column=2, row=1)
            self.btAR.grid(column=1, row=2)
     
    # -- CLASSE FRAME DESSOUS (LOG) --
    class Pan4(tk.Frame):
        def __init__(self, parent):
            self.parent = parent
            tk.Frame.__init__(self, self.parent)
     
            self.log = tk.Text(self, height=10, width=100, wrap = tk.WORD)
            self.log.grid(column=0, row=0)
            self.log.insert('1.0', 'Log du programme')
     
    # -- FONCTION TOURNER A GAUCHE SUR PLACE --
    def tournerGaucheSurPlace():
        print("Tourner a gauche sur place")
     
    # -- FONCTION ROUES SUR PLACE --
    def rouesSurPlace():
        #Déclarer à l'interface que l'on utilisera les boutons de gauche
        btnsGauche = 1
        btnsDroite = 0
        print("Roues sur place")
     
    # -- FONCTION TOURNER A DROITE SUR PLACE --
    def tournerDroiteSurPlace():
        print("Tourner a droite sur place")
     
    # -- FONCTION ROUES AU CENTRE --
    def rouesCentre():
        #Déclarer à l'interface que l'on utilisera les boutons de droite
        btnsGauche = 0
        btnsDroite = 1
        print("Roues au centre")
     
    # -- FONCTION AVANCER --
    def avancer():
        print("Avancer")
     
    # -- FONCTION ROUES A GAUCHE --
    def rouesGauche():
        print("Roue a gauche")
     
    # -- FONCTION ROUES A DROITE --
    def rouesDroite():
        print("Roue a droite")
     
    # -- FONCTION RECULER --
    def reculer():
        print("Reculer")
     
    mon_app = tk.Tk()	#Instancie la classe
     
    pan1=Pan1(mon_app)	#Panneau Gauche
    pan1.grid(column = 0, row = 0, sticky='N')
     
    pan2=Pan2(mon_app)	#PAnneau Centrale
    pan2.grid(column = 1, row = 0, sticky='N')
     
    pan3=Pan3(mon_app)	#PAnneau Droite
    pan3.grid(column = 2, row = 0, sticky='N')
     
    pan4=Pan4(mon_app)	#PAnneau Dessous (LOG)
    pan4.grid(column = 0, row = 1, columnspan = 3)
     
    mon_app.title('POSL Rover')
    mon_app.mainloop()	#Boucler
    Sachant que pendant le temps que l'on me réponde sur la question de l'affichage des boutons, je travaille sur la partie serial maintenant que j'arrive à la faire fonctionner correctement.

    Merci.

  18. #18
    Membre éprouvé
    Homme Profil pro
    Aucune activité
    Inscrit en
    Novembre 2011
    Messages
    505
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Aucune activité

    Informations forums :
    Inscription : Novembre 2011
    Messages : 505
    Points : 926
    Points
    926
    Par défaut
    Citation Envoyé par Caxton Voir le message
    Alors, à partir de là, je bascule sur le souci suivant. Un problème avec la partie import serial... En effet, pour que mon robot puisse recevoir des données, je passe par une liaison série sans fil. Tout se passe merveilleusement bien si je pense à brancher mon interface avant de lancer l'application. Dans le cas contraire ça plante.
    Bonjour,
    Désolé je ne connais pas ce module (C'est un module installé, ou un module par défaut?).
    Pour moi il y a deux solutions:
    -> utiliser les fonctions de ce module pour tester si l'interface est branchée
    -> utiliser une structure try/except… Mais je ne connais pas les erreurs… Donc il faudrait les déterminer afin de les attraper puis de les traiter…

    Ok: le module serial est installé par défaut sous Ubuntu (ie: ce n'est pas dans la distribution de Python standard). Elle est installée sous Python2.7 chez moi…

    Maintenant je ne connais pas la suite…
    Il faut attendre quelqu'un d'autre. Désolé!

    Clodion

    PS:
    Citation Envoyé par Caxton Voir le message
    Je dois maintenant comprendre un autre souci d'interface. Quand je clique sur mes boutons, tout semble bon, puisque mes print s'affichent. Mais l'actualisation des boutons non
    L'initialisation n'est effectuée qu'une seule fois.
    D'où l'intérêt d'utiliser une liste des boutons et une fonction dans la classe (mais ce n'est pas obligatoire).
    Dans la fonction liée au bouton, on appelle la fonction du panneau qui va mettre à jours les boutons (allumer certains, éteindre les autres).
    Le but n'est pas de recréer les boutons, juste de basculer leur état!

    Dans le manuel de tkinter on trouve:
    w.configure(option=value, ...)
    Set the values of one or more options. For the options whose names are Python reserved words
    (class, from, in), use a trailing underbar: 'class_', 'from_', 'in_'.
    You can also set the value of an option for widget w with the statement
    w[option] = value
    If you call the .config() method on a widget with no arguments, you'll get a dictionary of all the
    widget's current options. The keys are the option names (including aliases like bd for borderwidth).
    The value for each key is:
    • for most entries, a five-tuple: (option name, option database key, option database class, default
    value, current value); or,
    • for alias names (like 'fg'), a two-tuple: (alias name, equivalent standard name).
    PS2: pour terminer…
    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
    import tkinter as tk
     
    def fct_bt1():
        print("coucou")
     
    def fct_bt2():
        if bt1["state"] == "normal":
            bt1.configure(state = tk.DISABLED)
        else:
            bt1.configure(state = tk.NORMAL)
        print(bt1["state"])
     
    fen = tk.Tk()
    bt1 = tk.Button(fen, text="Coucou", command = fct_bt1)
    bt1.pack()
    bt2 = tk.Button(fen, text="Bascule", command = fct_bt2)
    bt2.pack()
     
    fen.mainloop()

  19. #19
    Membre régulier Avatar de Caxton
    Homme Profil pro
    Sans
    Inscrit en
    Janvier 2005
    Messages
    586
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Corrèze (Limousin)

    Informations professionnelles :
    Activité : Sans

    Informations forums :
    Inscription : Janvier 2005
    Messages : 586
    Points : 123
    Points
    123
    Par défaut J'ai suivie ce qui à été dit mais... hélas, ça plante en cours de route
    Aie, j'ai mal ! Tel est la phrase que j'ai sorti en voyant l'erreur !

    En effet, comme le dis l'erreur qui va suivre, on as pas accès de l'extérieur aux boutons des classes crées. Et je me dit, c'est logique, puisque on peux pas y accédé autrement ! Diablerie !

    Au démarrage de l'application RAS ça tourne parfaitement. Et je passe à la suite, cliquer sur le bouton à gauche pour basculer mon interface ! Et c'est là que Banzaï ! Python à les yeux crevés et pissent le sang ! Je jette mon dès de sauvegarde et... bon, d'acord, c'est pas un jeu de rôle ! Mais bon, j'aime bien paraphé mes erreurs de débutant

    Python 3.2.3 (default, Feb 27 2014, 21:31:18)
    [GCC 4.6.3] on linux2
    Type "copyright", "credits" or "license()" for more information.
    ==== No Subprocess ====
    >>>
    Tentative de connecion sur... /dev/ttyUSB0
    Exception in Tkinter callback
    Traceback (most recent call last):
    File "/usr/lib/python3.2/tkinter/__init__.py", line 1402, in __call__
    return self.func(*args)
    File "/home/alexandre/Bureau/Python/POSL-Rover.py", line 103, in rouesSurPlace
    if self.btRG1["state"] == "normal":
    NameError: global name 'self' is not defined
    Et pourtant, j'ai bien tenté de :
    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
     
    #!/usr/bin/python
    # -*- coding: iso-8859-15 -*-
     
    # -- IMPORTATION --
     
    #import Tkinter as tk
    import tkinter as tk
     
    import serial
     
    #ser = serial.Serial('/dev/ttyUSB0', 9600)
     
    # -- VARIABLES --
    serialConnection = 0
    locations=['/dev/ttyUSB0', '/dev/ttyUSB1', '/dev/ttyUSB2', '/dev/ttyUSB3', '/dev/ttyS0', '/dev/ttyS1', '/dev/ttyS2', '/dev/ttyS3']
     
    for device in locations:
        try:
            print("Tentative de connecion sur...",device)
            ser = serial.Serial(device, 9600)
            serialConnection = 1
            break
        except:
            print("Connection échoué sur",device)
     
    # -- CLASSE FRAME GAUCHE --
    class Pan1(tk.Frame):
        def __init__(self, parent):
            self.parent = parent
            tk.Frame.__init__(self, self.parent)
     
            self.lFControleDirection = tk.LabelFrame(self, text="Tourner sur place", padx=20, pady=20)
     
            self.btRG1 = tk.Button(self.lFControleDirection, text="Tourner : gauche", state=tk.DISABLED, command=tournerGaucheSurPlace)
            self.btSP = tk.Button(self.lFControleDirection, text="Roues : Sur Place", state=tk.NORMAL, command=rouesSurPlace)
            self.btRD1 = tk.Button(self.lFControleDirection, text="Tourner : droite", state=tk.DISABLED, command=tournerDroiteSurPlace)
            self.btRC1 = tk.Button(self.lFControleDirection, text="Roues : Centre", state=tk.DISABLED, command=rouesCentre)
     
            #Positionnement dans la grille
            self.lFControleDirection.grid(column=0, row=0)
            self.btRG1.grid(column=0, row=0)
            self.btSP.grid(column=1, row=0)
            self.btRD1.grid(column=2, row=0)
            self.btRC1.grid(column=1, row=1)
     
    # -- CLASSE FRAME CENTRALE --
    class Pan2(tk.Frame):
        def __init__(self, parent):
            self.parent = parent
            tk.Frame.__init__(self, self.parent)
     
            self.lFSpeed = tk.LabelFrame(self, text="Vitesse", padx=20, pady=20)
            self.lFSpeed.grid(column=0, row=0, sticky='NS')
            self.sliderSpeed = tk.Scale(self.lFSpeed, from_=100, to=50, tickinterval=2)
            self.sliderSpeed.grid(column=0, row=0)
     
    # -- CLASSE FRAME DROITE --
    class Pan3(tk.Frame):
        def __init__(self, parent):
            self.parent = parent
            tk.Frame.__init__(self, self.parent)
            self.lFControleDirect = tk.LabelFrame(self, text="Controle", padx=20, pady=20)
     
            #if btnsDroite == 0 :
            self.btAV = tk.Button(self.lFControleDirect, text="Avancer", state=tk.NORMAL, command=avancer)
            self.btRG2 = tk.Button(self.lFControleDirect, text="Roues : Gauche", state=tk.NORMAL, command=rouesGauche)
            self.btRC2 = tk.Button(self.lFControleDirect, text="Roue : Centre", state=tk.NORMAL, command=rouesCentre)
            self.btRD2 = tk.Button(self.lFControleDirect, text="Roues : Droite", state=tk.NORMAL, command=rouesDroite)
            self.btAR = tk.Button(self.lFControleDirect, text="Reculer", state=tk.NORMAL, command=reculer)
            self.btDG1 = tk.Button(self.lFControleDirect, text="Reculer", state=tk.NORMAL, command=rouesDiagonaleGauche)
            self.btDD1 = tk.Button(self.lFControleDirect, text="Reculer", state=tk.NORMAL, command=rouesDiagonaleDroite)
            self.btDG1 = tk.Button(self.lFControleDirect, text="Roues : Diagonale à gauche", state=tk.NORMAL, command=rouesDiagonaleGauche)
            self.btDD1 = tk.Button(self.lFControleDirect, text="Roues : Diagonale à droite", state=tk.NORMAL, command=rouesDiagonaleDroite)
     
            #Positionnement dans la grille
            self.lFControleDirect.grid(column=1, row=0, sticky='NS')
            self.btAV.grid(column=1, row=0)
            self.btRG2.grid(column=0, row=1)
            self.btRC2.grid(column=1, row=1)
            self.btRD2.grid(column=2, row=1)
            self.btAR.grid(column=1, row=2)
            self.btDG1.grid(column=0, row=3)
            self.btDD1.grid(column=2, row=3)
     
    # -- CLASSE FRAME DESSOUS (LOG) --
    class Pan4(tk.Frame):
        def __init__(self, parent):
            self.parent = parent
            tk.Frame.__init__(self, self.parent)
     
            self.log = tk.Text(self, height=10, width=100, wrap = tk.WORD)
            self.log.grid(column=0, row=0)
            self.log.insert('1.0', 'Log du programme')
     
    # -- FONCTION TOURNER A GAUCHE SUR PLACE --
    def tournerGaucheSurPlace():
        print("Tourner a gauche sur place")
        if serialConnection == 1:
            ser.write("!,1,0,100,1,100,0,100,1,100,*")
     
    # -- FONCTION ROUES SUR PLACE --
    def rouesSurPlace():
        if self.btRG1["state"] == "normal":
            self.btRG1.configure(state = tk.DISABLED)
        else:
            self.btRG1.configure(state = tk.NORMAL)
        print("Roues sur place")
     
    # -- FONCTION TOURNER A DROITE SUR PLACE --
    def tournerDroiteSurPlace():
        print("Tourner a droite sur place")
     
    # -- FONCTION ROUES AU CENTRE --
    def rouesCentre():
        print("Roues au centre")
     
    # -- FONCTION AVANCER --
    def avancer():
        print("Avancer")
     
    # -- FONCTION ROUES A GAUCHE --
    def rouesGauche():
        print("Roue a gauche")
     
    # -- FONCTION ROUES A DROITE --
    def rouesDroite():
        print("Roue a droite")
     
    # -- FONCTION RECULER --
    def reculer():
        print("Reculer")
     
    # -- FONCTION ROUES DIAGONALE A GAUCHE --
    def rouesDiagonaleGauche():
        print("Roue diagonale a gauche")
     
    # -- FONCTION ROUES DIAGONALE A DROITE --
    def rouesDiagonaleDroite():
        print("Roue diagonale a droite")
     
     
    mon_app = tk.Tk()	#Instancie la classe
     
    pan1=Pan1(mon_app)	#Panneau Gauche
    pan1.grid(column = 0, row = 0, sticky='N')
     
    pan2=Pan2(mon_app)	#PAnneau Centrale
    pan2.grid(column = 1, row = 0, sticky='N')
     
    pan3=Pan3(mon_app)	#PAnneau Droite
    pan3.grid(column = 2, row = 0, sticky='N')
     
    pan4=Pan4(mon_app)	#PAnneau Dessous (LOG)
    pan4.grid(column = 0, row = 1, columnspan = 3)
     
    mon_app.title('POSL Rover')
    mon_app.mainloop()	#Boucler
    Pendant ce temps, je continue à développer les commandes

    Merci.

  20. #20
    Membre éprouvé
    Homme Profil pro
    Aucune activité
    Inscrit en
    Novembre 2011
    Messages
    505
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Aucune activité

    Informations forums :
    Inscription : Novembre 2011
    Messages : 505
    Points : 926
    Points
    926
    Par défaut
    Citation Envoyé par Caxton Voir le message
    En effet, comme le dis l'erreur qui va suivre, on as pas accès de l'extérieur aux boutons des classes crées. Et je me dit, c'est logique, puisque on peux pas y accédé autrement ! Diablerie !
    Bonjour,
    Et oui… Mais c'est certain qu'utiliser des classes nécessite un peu d'apprentissage…
    Et manifestement, le strict minimum ne semble pas être compris…

    Self, est une variable qui désigne l'objet en cours… Donc hors classe, le mot ne peut conduire qu'à une erreur…
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    class Pan1(tk.Frame):
        def __init__(self, parent):
            self.parent = parent
    Signifie que la classe Pan1 (dérivée de tk.Frame) lorsqu'elle est instanciée pour la création d'un objet, cet objet qui est créé, à l'intérieur de la définition de la classe se nomme "self"…
    "self.parent = parent" signifie que pour cet objet (self) la variable "parent" contiendra le "parent" transmis en paramètre…
    Dans le cas présent, le parent est "tk.Tk()" c'est à dire une instance de la Classe Tk.

    D'autre part, c'est éminemment exacte. La variable "btRG1" est parfaitement inaccessible…
    D'où l'intérêt d'une fonction (qui prend alors le nom de méthode) dans la classe Pan1 qui, appelée, se chargera de faire tout ce qu'il y a à faire…
    Les objets (et donc les classes) permettent en premier d'encapsuler le code et les variables.

    Donc, allez… Une petite fonction dans la classe… Et elle fera tout le travail…

    Clodion

    PS: par contre il serait bien de se mettre sérieusement à Python pour ne pas trop compter que les autres fassent le travail, non?

Discussions similaires

  1. Jolie interface graphique
    Par ulysse031 dans le forum Interfaces Graphiques en Java
    Réponses: 4
    Dernier message: 04/11/2010, 00h16
  2. jolie interface en java
    Par morgoths dans le forum Débuter
    Réponses: 14
    Dernier message: 29/12/2009, 13h36
  3. Jolie interface graphique
    Par nramel dans le forum Interfaces Graphiques en Java
    Réponses: 2
    Dernier message: 03/02/2009, 09h32
  4. comment faire une JOLIE interface
    Par estelle84 dans le forum wxWidgets
    Réponses: 4
    Dernier message: 08/05/2007, 19h31
  5. Réponses: 1
    Dernier message: 13/02/2007, 22h00

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