Forum Programmation.python Tkinter et scrollbar

Posté par  (Mastodon) . Licence CC By‑SA.
Étiquettes :
2
18
fév.
2025

Je suis content de mon code et je cherche à mettre plus d'équipes dorénavant.
Du coup, j'aurais besoin de rajouter une scrollbar sur la fenêtre principale; quelqu'un saurait faire?

https://framagit.org/vev/elo-lvgsports
"Elo LVGsports.py"

ps: pour faire marcher le code sur gnu/linux il faut changer le \ en / ligne 299
ps2: vous pouvez rajouter des joueurs dans le fichier "joueurs.json"
exemple avec 24 joueurs nommés 0001, 0002 etc..
{"0001": ["1500", "0", "0", "0", "aucun enregistrement"], "0002": ["1500", "0", "0", "0", "aucun enregistrement"], "0003": ["1500", "0", "0", "0", "aucun enregistrement"], "0004": ["1500", "0", "0", "0", "aucun enregistrement"], "0005": ["1500", "0", "0", "0", "aucun enregistrement"], "0006": ["1500", "0", "0", "0", "aucun enregistrement"], "0007": ["1500", "0", "0", "0", "aucun enregistrement"], "0008": ["1500", "0", "0", "0", "aucun enregistrement"], "0009": ["1500", "0", "0", "0", "aucun enregistrement"], "0010": ["1500", "0", "0", "0", "aucun enregistrement"], "0011": ["1500", "0", "0", "0", "aucun enregistrement"], "0012": ["1500", "0", "0", "0", "aucun enregistrement"], "0013": ["1500", "0", "0", "0", "aucun enregistrement"], "0014": ["1500", "0", "0", "0", "aucun enregistrement"], "0015": ["1500", "0", "0", "0", "aucun enregistrement"], "0016": ["1500", "0", "0", "0", "aucun enregistrement"], "0017": ["1500", "0", "0", "0", "aucun enregistrement"], "0018": ["1500", "0", "0", "0", "aucun enregistrement"], "0019": ["1500", "0", "0", "0", "aucun enregistrement"], "0020": ["1500", "0", "0", "0", "aucun enregistrement"],"0021": ["1500", "0", "0", "0", "aucun enregistrement"], "0022": ["1500", "0", "0", "0", "aucun enregistrement"], "0023": ["1500", "0", "0", "0", "aucun enregistrement"], "0024": ["1500", "0", "0", "0", "aucun enregistrement"]}

  • # / tout le temps ?

    Posté par  . Évalué à 3 (+1/-0).

    On parle bien de cette ligne ?

    tk_img = tk.PhotoImage(file = r".\v\LogonewLVGB.png")
    

    Un chemin de fichier donc ?

    Depuis longtemps, le / fonctionne sur "les trois OS" : Windows, Linux et macOS.

  • # on ne peut pas en l'état

    Posté par  . Évalué à 2 (+1/-0).

    On ne peut mettre un scroll que sur les widgets Text et Canvas, il va donc falloir que tu revoies et réagence le tout. Je pense qu'un canvas en y intégrant tes labels et radios avec la méthode create_window devrait convenir.

    En revanche chez moi ton script jette plusieurs erreurs, le json des joueurs n'est pas en utf8 mais en iso-8859-1, et comme tu n'as pas spécifié l'encodage dans open.
    Les smileys dans ton code ne passent chez moi :

    _tkinter.TclError: character U+1f60a is above the range (U+0000-U+FFFF) allowed by Tcl

    Préfère aussi les espaces que les tabulations pour indenter ton code.

    • [^] # Re: on ne peut pas en l'état

      Posté par  (Mastodon) . Évalué à 1 (+0/-0).

      merci gled pour toutes ces infos;
      donc, a priori, gros travail pour passer en canvas(faudra que je regarde), je vais peut etre devoir changer les radiobuttons en listbox :s

      • [^] # Re: on ne peut pas en l'état

        Posté par  . Évalué à 2 (+1/-0). Dernière modification le 19 février 2025 à 17:45.

        Un truc fait à l'arrache avec une frame et un simple canvas.
        Il faudrait quand même revoir ton script, et utiliser des frames pour grouper les widgets de ta fenêtre, là, c'est un peu le bazar.

        can_frame = tk.Frame(cadre, bd=2, highlightbackground='grey')
        can_frame.grid(padx=10, pady=10)
        line_height = 40
        can = tk.Canvas(
            can_frame,
            width=280,
            height=line_height * 10,
            highlightthickness=0,
            yscrollincrement=line_height,
        )
        can.grid(row=0, column=0)
        scroll = tk.Scrollbar(
            can_frame, width=20, orient=tk.VERTICAL, highlightthickness=0,
        )
        scroll.grid(row=0, column=1, sticky=tk.NSEW)
        can.config(yscrollcommand=scroll.set)
        scroll.config(command=can.yview)
        colors = 'lightGreen', 'lightBlue'
        radios_base_options = dict(
            fg='grey',
            highlightthickness=0,
        )
        for i in range(nb_joueurs):
            radios_options = dict(
                text=liste_joueurs[i],
                value=liste_joueurs[i],
                bg=colors[i % 2],
            )
            can.create_rectangle(
                0,
                i * line_height,
                can['height'],
                (i + 1) * line_height,
                fill=radios_options['bg'],
                width=0,
            )
            radio = tk.Radiobutton(
                can, variable=j1a, **radios_base_options, **radios_options
            )
            can.create_window(
                0,
                i * line_height + line_height / 2,
                window=radio,
                anchor=tk.W,
            )
            radio = tk.Radiobutton(
                can, variable=j1b, **radios_base_options, **radios_options
            )
            can.create_window(
                int(can['width']) / 2,
                i * line_height + line_height / 2,
                window=radio,
                anchor=tk.W,
            )
        can.configure(scrollregion=(0, 0, 0, i * line_height))

        Reste plus qu'à intégrer cela dans ton interface {º_º}

        Bonne continuation.

        • [^] # Re: on ne peut pas en l'état

          Posté par  (Mastodon) . Évalué à 1 (+0/-0).

          merci gled, je regarderai ça
          saurais tu changer mes radiobuttons en listbox? j'aime moins mais ça me permettrait de l'utiliser

          • [^] # Avec deux listbox

            Posté par  . Évalué à 1 (+0/-0).

            Un autre code fait à l'arrache =D

            import tkinter as tk
            from tkinter import font as tk_font
            import json
            
            SCROLL_WIDTH = 18
            LISTBOX_HEIGHT = 12
            
            def players_load(path):
                with open(path) as f:
                    return json.load(f)
            
            def player_select(list_box):
                i = list_box.curselection()
                if not i:
                    return
                value = list_box.get(i)
                if players_selected[not list_box.id] == value:
                    return
                players_selected[list_box.id] = value
                players_label.config(
                    text=f'{players_selected[0]} - {players_selected[1]}'
                )
            
            players_selected = {0:'', 1:'',}
            players = dict(sorted(players_load('joueurs.json').items()))
            list_box_width = max(len(p) for p in players) + 2
            
            window = tk.Tk()
            font = tk_font.Font(family='mono', size=18)
            
            frame_box = tk.Frame(window, bg='#000')
            frame_box.grid()
            
            left_scroll = tk.Scrollbar(
                frame_box, orient=tk.VERTICAL, width=SCROLL_WIDTH,
            )
            left_scroll.grid(row=0, column=0, sticky=tk.NSEW,)
            left_list = tk.Listbox(
                frame_box,
                font=font,
                width=list_box_width,
                height=LISTBOX_HEIGHT,
                xscrollcommand=left_scroll.set,
                yscrollcommand=left_scroll.set,
            )
            left_list.grid(row=0, column=1, padx=(10, 5),)
            left_scroll.config(command=left_list.yview)
            left_list.id = 0 # C'est crade !
            
            right_scroll = tk.Scrollbar(
                frame_box, orient=tk.VERTICAL, width=SCROLL_WIDTH,
            )
            right_scroll.grid(row=0, column=3, sticky=tk.NSEW,)
            right_list = tk.Listbox(
                frame_box,
                font=font,
                width=list_box_width,
                height=LISTBOX_HEIGHT,
                xscrollcommand=right_scroll.set,
                yscrollcommand=right_scroll.set,
            )
            right_list.grid(row=0, column=2, padx=(5, 10),)
            right_scroll.config(command=right_list.yview)
            right_list.id = 1 # C'est crado !
            
            players_label = tk.Label(
                frame_box, height=3, font=font, bg='#000', fg='#fff',
            )
            players_label.grid(row=1, column=0, columnspan=4,)
            
            left_list.insert(0, *players)
            right_list.insert(0, *players)
            
            left_list.bind(
                '<<ListboxSelect>>', lambda e: player_select(left_list)
            )
            right_list.bind(
                '<<ListboxSelect>>', lambda e: player_select(right_list)
            )
            
            window.mainloop()

            Y a des trucs un peu moches, notamment d'insérer des attributs id aux listbox (permettant de savoir si la sélection courante n'est pas la même que celle de l'autre listbox), il serait préférable de créer une classe dérivée de Listbox et y intégrer un id via un attribut de classe.

Envoyer un commentaire

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.