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 :

[Python] Tkinter Scrollbar et Frame


Sujet :

Tkinter Python

  1. #1
    Nouveau Candidat au Club
    Homme Profil pro
    Lycéen
    Inscrit en
    Février 2017
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Lycéen

    Informations forums :
    Inscription : Février 2017
    Messages : 4
    Points : 1
    Points
    1
    Par défaut [Python] Tkinter Scrollbar et Frame
    Bonjour,

    De nombreuses questions similaires à la mienne existent sur internet mais je n'arrive pas à résoudre mon problème.
    Je réalise un simple programme de Tchat avec python et tkinter et je souhaiterais ajouter de manière dynamique (par "dynamique" j'entends au fil de l'exécution du programme) des widgets dans une Frame (pour afficher les messages reçus).
    Le problème est que quand j'ajoute les widgets de manière dynamiques (ici je le simule avec un Thread pour les tests), ma scrollbar reste inanimée :/ alors qu'elle fonctionne lorsque j'ajoute tous mes widgets directement dans 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
    def add():
        for i in range(0,100):
            Label(master = frame, text = i).pack()
            time.sleep(0.05)
            frame.update_idletasks()
     
    fen = Tk()
     
    vsb = Scrollbar(fen, orient ="vertical")
    vsb.pack(side = RIGHT, fill ="y")
     
    c = Canvas(fen, yscrollcommand = vsb.set)
    c.pack()
     
    vsb.config(command = c.yview)
     
    frame = Frame(c)
     
    thread = Thread(target=add)
    thread.start()
     
    c.create_window(0,0, window = frame)
    c.config(scrollregion = c.bbox("all"))
     
     
    fen.mainloop()
    Merci pour votre aide !

  2. #2
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 287
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 287
    Points : 36 778
    Points
    36 778
    Par défaut
    Salut,

    Peut être qu'il faudrait comprendre ce qu'est la "scrollregion"?
    Pourquoi ne pas utiliser un widget Text? Ca sait bien ajouter des lignes, c'est scrollable. Et çà évite de créer une Frame avec des tas de Labels dans un Canvas juste la pour pouvoir scroller.
    En tous cas, mettre à jour le GUI via un thread n'est pas une bonne idée (même avec tkinter).

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  3. #3
    Nouveau Candidat au Club
    Homme Profil pro
    Lycéen
    Inscrit en
    Février 2017
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Lycéen

    Informations forums :
    Inscription : Février 2017
    Messages : 4
    Points : 1
    Points
    1
    Par défaut
    Oui j'ai pensé à utiliser les Text.
    Mais le problème est que je ne voudrais pas que l'endroit ou j'ajoute mes messages soit éditable et si je fait un text.config(state = DISABLED),
    je ne peux plus non plus ajouter de texte dedans :/

  4. #4
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 287
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 287
    Points : 36 778
    Points
    36 778
    Par défaut
    Citation Envoyé par Azmog2 Voir le message
    Oui j'ai pensé à utiliser les Text.
    Mais le problème est que je ne voudrais pas que l'endroit ou j'ajoute mes messages soit éditable et si je fait un text.config(state = DISABLED),
    je ne peux plus non plus ajouter de texte dedans :/
    Il suffit de rendre le widget éditable seulement pour permettre l'ajout de message. Et comme toutes ces opérations sont dans un "callback", elles sont sérialisées: les autres évènements attendent et trouveront toujours le widget avec un state='disabled'.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  5. #5
    Nouveau Candidat au Club
    Homme Profil pro
    Lycéen
    Inscrit en
    Février 2017
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Lycéen

    Informations forums :
    Inscription : Février 2017
    Messages : 4
    Points : 1
    Points
    1
    Par défaut
    Ah oui d'accord merci j'ai modifié tout sa et sa marche !
    Pendant que j'ai quelqu'un de compétent sous la main ^^, j'ai un second problème,
    en fait je suis dans la classe d'une fenêtre Tkinter et j'aimerai depuis cette classe ouvrir une seconde fenêtre sans pour autant bloquer la première à cause du mainloop() :/
    Je n'ai pas idée de comment procéder :/
    J'ai tenté à l'aide d'un Thread mais j'ai besoin en ouvrant ma seconde fenêtre de lui passer des arguments de la première ce que je ne peux pas faire si je suis dans un Thread à part :/

    Merci infiniment pour votre aide

  6. #6
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 287
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 287
    Points : 36 778
    Points
    36 778
    Par défaut
    Salut,

    Citation Envoyé par Azmog2 Voir le message
    en fait je suis dans la classe d'une fenêtre Tkinter et j'aimerai depuis cette classe ouvrir une seconde fenêtre sans pour autant bloquer la première à cause du mainloop()...
    Avec tkinter (et la plupart des GUI), mainloop traite les évènements et déclenche les callbacks associées. Donc le programme n'est pas bloqué. Et que les callbacks soient "fonctions" ou "méthode" associé à l'instance d'une classe, c'est juste une question de rangement ("classer") de votre code. L'important est de savoir les associer aux évènements qui devront les déclencher (et ils peuvent créer un widget comme faire des tas d'autres choses pourvu qu'ils se terminent assez vite).

    Le fait est que vous vous êtes aventuré dans un pays étrange où vous n'arrivez même pas à trouver les mots pour le décrire. Le plus simple dans ce cas est de coder un petit exemple de ce que vous voulez faire. A défaut des mots, on a au moins un code (des intentions de quelque chose).

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  7. #7
    Nouveau Candidat au Club
    Homme Profil pro
    Lycéen
    Inscrit en
    Février 2017
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Lycéen

    Informations forums :
    Inscription : Février 2017
    Messages : 4
    Points : 1
    Points
    1
    Par défaut
    Oui je suis désolé je suis grand débutant et je n'ai pas le vocabulaire approprié :/
    Mais voici un exemple tout simple de ce qui ne marche pas :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    import time
    from tkinter import *
     
    while True :
        time.sleep(5)
        fen = Tk()
        fen.mainloop()
    Ici je voudrais toutes les 5 secondes afficher une nouvelle fenêtre mais le problème est que dès que la première est lancée elle bloque ma boucle :/

  8. #8
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 287
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 287
    Points : 36 778
    Points
    36 778
    Par défaut
    Citation Envoyé par Azmog2 Voir le message
    Ici je voudrais toutes les 5 secondes afficher une nouvelle fenêtre mais le problème est que dès que la première est lancée elle bloque ma boucle :/
    "toutes les 5 secondes" est un évènement.
    "afficher une nouvelle fenêtre" pourrait être ce que fait un callback.

    Vous avez certainement une documentation tkinter (sinon vous avez une liste ici). Et ce que vous chercher c'est comment déclencher un callback après un délai donné. Ce sont les méthodes .after[_idle|_cancel].
    Ca serait bien aussi de comprendre les différences entre Tk(), Toplevel(), Frame(),...

    Donc vous devriez plutôt écrire:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    from tkinter import *
     
    def callback(delay=5000):
          Toplevel()
          root.after(delay, callback)
     
    root =  Tk()
    callback()
    mainloop()
    i.e. un callback qui fait des choses qui se répètent et un code qui crée la fenêtre principale, crée des widgets, déclare des bindings et donne la main à la mainloop. C'est la construction "de base" plutôt qu'une boucle while
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    from tkinter import *
     
    root =  Tk()
    while True:
        root.after(5000, root.quit)
        root.mainloop()
        Toplevel()
    qui décoince la mainloop pour faire quelque chose et qui n'est pas une construction "de base".

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

Discussions similaires

  1. Réponses: 5
    Dernier message: 11/10/2007, 17h39
  2. Scrollbar pour frame
    Par zoidy dans le forum Macros et VBA Excel
    Réponses: 13
    Dernier message: 02/10/2007, 14h04
  3. Associer une scrollbar à un Frame
    Par Ramoneur dans le forum Tkinter
    Réponses: 1
    Dernier message: 07/09/2007, 10h29
  4. Conteneurs en Python Tkinter ?
    Par tuxout dans le forum Tkinter
    Réponses: 2
    Dernier message: 09/04/2007, 18h46
  5. [Tkinter] ScrollBar et méthode set
    Par BlackPearl dans le forum Tkinter
    Réponses: 1
    Dernier message: 02/04/2005, 20h06

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