Rafraichir fenêtre tkinter base de données sqlite3

Bonjour,


Je suis actuellement en train de créer une application de gestion commercial en python incluant sqlite3 et tkinter.
Pou faire simple, j'ai plusieurs formulaires, création client, création commande, etc. 
Actuellement mon application fonctionne, en revanche, je dois systématiquement fermer l'application pour mettre à jour la fenêtre tkinter pour avoir les nouveaux enregistrements. Information importante, dans le formulaire de création de commande, je dois sélectionner le client.
Exemple d'utilisation actuelle :
- Etape 1 : je créer  un client à l'aide du formulaire dédié.
- Etape 2 : je ferme l'application afin d'avoir le nouveau client dans la liste déroulante du formulaire de création de commande.
- Etape 3 : je réouvre mon application
- Etape 4 : je rempli le formulaire de création de commande avec le nouveau client de la liste déroulante.

Mon but est tout simplement de supprimer l'étape 2 et 3, c'est à dire lorsque l'on créé un nouveau client, je voudrais qu'il s'ajoute à la liste déroulante du formulaire de création de commande sans devoir fermer la fenêtre.

Est-ce que selon vous cela est possible ? Peut-être une fonction rafraichir ?

Je vous remercie par avance et reste à votre disposition pour tout complément d'information


Windows / Chrome 103.0.5060.114

7 réponses

  1. Contributeur

    bonjour,

    as-tu envisagé, quand tu créais un nouveau client, de fermer/rouvrir le formulaire de création de commande?

    1. Bonjour,

      C'est à dire ? 

      En fait, mon application possède plusieurs onglets :

      Onglet 1 -> Créer client

      Onglet 2 -> Créer commande

      Onglet 3 -> Créer article

      etc.

      Quand je ferme complètement la fenêtre et réouvre l'application, les nouveaux enregistrements sont bien présents dans la liste déroulante

    2. Contributeur
      @madrid974

      Je pense à deux possibilités:

      1. quand un nouveau client est créé, ton application, sans intervention de l'utilisateur, ferme la fenêtre en en ouvre une nouvelle
      2. quand un nouveau client est créé, tu fais appel à une fonction qui rafraichit la liste déroulante de l'onglet 2.
  2. Bonsoir, sers-toi de variable tkinter afin de simplifier cela.

    Exemple très basique

    import tkinter as tk
    
    def customer_add():
        customer = customer_add_var.get()
        customers.append(customer)
        customers_var.set(customers)
        customer_add_var.set('')
        # + enregister dans ta table sqlite
    
    # On va dire que cela est récupéré dans ta table sqlite
    customers = ['lisa', 'bart', 'homer', 'marge', 'skiner', 'milhouse',]
    
    win = tk.Tk()
    
    customers_scroll = tk.Scrollbar(win, orient=tk.VERTICAL)
    customers_scroll.grid(row=0, column=1, sticky=tk.NS)
    customers_var = tk.StringVar(value=customers)
    customers_list = tk.Listbox(win, height=1, listvariable=customers_var, yscrollcommand=customers_scroll.set)
    customers_list.grid(row=0, column=0)
    
    
    customer_add_var = tk.StringVar()
    customer_add_label = tk.Entry(win, textvariable=customer_add_var)
    customer_add_label.grid()
    customer_add_button = tk.Button(win, text='Ajouter', command=customer_add)
    customer_add_button.grid()
    
    win.mainloop()

    Je n'ai pas mis de commentaires, mais demande si quelque chose te semble flou.

    1. Bonjour et merci pour ton aide.

      C'est ok j'ai réussi grâce à ton code d'afficher l'enregistrement sans fermer l'application.

      Comment je dois faire si en plus du nom, je veux afficher également le prénom et l'ID ?

      import tkinter as tk
      from tkinter import messagebox
      import sqlite3
      
      mysqldb = sqlite3.connect("test.db")
      cursor = mysqldb.cursor()
      
      def customer_add():
          nom = nom_add_var.get()
          liste.append(nom)
          customers_var.set(liste)
          nom_add_var.set('')
          prenom = prenom_add_var.get()
          cursor.execute("INSERT INTO customers(nom,prenom) VALUES('"+ nom +"','"+ prenom +"')")
          messagebox.showinfo("Succès", "Le client a été enregistré")
          mysqldb.commit()
          mysqldb.close()
      
      win = tk.Tk()
      win.geometry('400x400')
      
      liste = []
      cursor.execute("select idclient,nom,prenom from customers;")
      result = cursor.fetchall()
      for row in result:
           liste.append(row)
      
      customers_scroll = tk.Scrollbar(win, orient=tk.VERTICAL)
      customers_scroll.grid(row=0, column=1, sticky=tk.NS)
      customers_var = tk.StringVar(value=liste)
      customers_list = tk.Listbox(win, height=1, listvariable=customers_var, yscrollcommand=customers_scroll.set)
      customers_list.grid(row=0, column=0)
      
      nom_add_var = tk.StringVar()
      nom_add_label = tk.Entry(win, textvariable=nom_add_var)
      nom_add_label.grid()
      prenom_add_var = tk.StringVar()
      prenom_add_label = tk.Entry(win, textvariable=prenom_add_var)
      prenom_add_label.grid()
      customer_add_button = tk.Button(win, text='Ajouter', command=customer_add)
      customer_add_button.grid()
      
      win.mainloop()
    2. @madrid974

      Pour afficher le nom et le prénom c'est ok.

      En revanche, comment faire pour afficher l'ID qui a été associé lors de la création ? svp

      Ci-dessous, le code mis à jour :

      import tkinter as tk
      from tkinter import messagebox
      import sqlite3
      
      mysqldb = sqlite3.connect("test.db")
      cursor = mysqldb.cursor()
      
      def customer_add():
          nom = nom_add_var.get()
          #liste.append(nom) 
          nom_add_var.set('') 
          prenom = prenom_add_var.get()
          liste.append((nom,prenom))
          prenom_add_var.set('') 
          customers_var.set(liste) 
          print(liste)
          cursor.execute("INSERT INTO customers(nom,prenom) VALUES('"+ nom +"','"+ prenom +"')")
          messagebox.showinfo("Succès", "Le client a été enregistré")
          mysqldb.commit()
          mysqldb.close()
      
      win = tk.Tk()
      win.geometry('400x400')
      
      liste = []
      cursor.execute("select idclient,nom,prenom from customers;")
      result = cursor.fetchall()
      for row in result:
           liste.append(row)
      #print(liste)
      
      customers_scroll = tk.Scrollbar(win, orient=tk.VERTICAL)
      customers_scroll.grid(row=0, column=1, sticky=tk.NS)
      customers_var = tk.StringVar(value=liste)
      customers_list = tk.Listbox(win, height=10, listvariable=customers_var, yscrollcommand=customers_scroll.set)
      customers_list.grid(row=0, column=0)
      
      nom_add_var = tk.StringVar()
      nom_add_label = tk.Entry(win, textvariable=nom_add_var)
      nom_add_label.grid()
      prenom_add_var = tk.StringVar()
      prenom_add_label = tk.Entry(win, textvariable=prenom_add_var)
      prenom_add_label.grid()
      customer_add_button = tk.Button(win, text='Ajouter', command=customer_add)
      customer_add_button.grid()
      
      win.mainloop()
  3. Bonjour,

    Pour mettre à jour une liste déroulante, on peut faire ça:

    from tkinter import *
    from tkinter import ttk
    
    def add_customer():
        #on simule l'ajout de client dans la table sqlite3
        _name = 'Dupont'
    
        #Et tu mets à jour la liste utilisée par la liste déroulante :
        customers_list.append(_name)
    
        #En cliquant sur la flèche de la combo box, on voit le nouveau client dans la liste
    
    WIDTH, HEIGHT = 300, 300
    
    main_win = Tk()
    main_win.configure(background = 'light grey')
    main_win.title('Test')
    main_win.geometry(str(WIDTH)+'x'+str(HEIGHT)+'+300+100')
    
    customers_list=['']
    listeCombo = ttk.Combobox(main_win, values=customers_list, postcommand=lambda: listeCombo.configure(values=customers_list))
    listeCombo.place(x = 10,y = 100)
    
    Button(main_win, text="Créer client", command=add_customer).place(x=10, y=250)
    
    main_win.mainloop()
    
    1. Bonjour,

      Super merci 

      J'ai une autre question, comment faire lorsque l'on souhaite le faire apparaitre dans une liste déroulante mais dans une autre fonction ?

      C'est à dire, afficher la liste déroulante pour choisir le client nouvellement créé qui souhaite passer la commande dans une autre fonction dédié.

      Il faut juste que je récupère la liste "liste" de ma fonction add_client, mais ça je ne sais pas comment faire.

      1. Contributeur

        Quand tu écris "ma fonction add_client", il s'agit de la fonction "customer_add()"?

        La liste "liste" est déclarée en ligne 25, hors de toute fonction.  Tu peux utiliser dans une autre fonction, comme la fonction "customer_add() l'utilise.

    2. Ah ok,

      Ce que tu appelles "liste déroulante", c'est une listbox avec une scroll bar, ce n'est pas une combo box:

      1. Oui oui désolé.

        Bon j'ai réussi à faire ce que je voulais MERCI, c'est à dire afficher la listbox dans une autre fonction et afficher l'ID et le prénom dans la listbox.

        Dernière chose svp, comment faire pour mettre à jour ma fenêtre lorsque j'ai supprimé un client ?

        Si ça peut aider certain le code actuel :

        import tkinter as tk
        from tkinter import messagebox
        import sqlite3
        
        mysqldb = sqlite3.connect("test.db")
        cursor = mysqldb.cursor()
        
        def customer_add():
            nom = nom_add_var.get() # On récupère la valeur de la variable nom_add_var
            nom_add_var.set('') # On vide la zone de saisie
            prenom = prenom_add_var.get() # On récupère la valeur de la zone de saisie
            sql = cursor.execute("select max(idclient)+1 from customers") # On récupère l'idmax de la table clients
            sql = list(sql)
            liste.append((sql,nom,prenom)) # On ajoute la ligne dans la liste
            prenom_add_var.set('')
            customers_var.set(liste)
            customers_var2.set(liste)
            cursor.execute("INSERT INTO customers(nom,prenom) VALUES('"+ nom +"','"+ prenom +"')")
            messagebox.showinfo("Succès", "Le client a été enregistré")
            mysqldb.commit()
        
        win = tk.Tk()
        win.geometry('500x500')
        
        liste = []
        cursor.execute("select idclient,nom,prenom from customers;")
        result = cursor.fetchall()
        for row in result:
             liste.append(row)
        
        # listBox 1 avec scrollbar
        customers_scroll = tk.Scrollbar(win, orient=tk.VERTICAL)
        customers_scroll.grid(row=0, column=1, sticky=tk.NS)
        customers_var = tk.StringVar(value=liste)
        customers_list = tk.Listbox(win, height=10, listvariable=customers_var, yscrollcommand=customers_scroll.set)
        customers_list.grid(row=0, column=0)
        
        # Formulaire d'ajout client
        l_nom = tk.Label(win, text="Nom : ")
        l_nom.grid(row=1, column=0,padx=10,pady=10,sticky="w")
        nom_add_var = tk.StringVar()
        nom_add_label = tk.Entry(win, textvariable=nom_add_var)
        nom_add_label.grid(row=1, column=1)
        l_prenom = tk.Label(win, text="Prénom : ")
        l_prenom.grid(row=2, column=0,padx=10,pady=10,sticky="w")
        prenom_add_var = tk.StringVar()
        prenom_add_label = tk.Entry(win, textvariable=prenom_add_var)
        prenom_add_label.grid(row=2, column=1)
        customer_add_button = tk.Button(win, text='Ajouter', command=customer_add)
        customer_add_button.grid(row=3, column=0)
        
        # listBox 2 avec scrollbar pour la deuxième fonction
        customers_scroll2 = tk.Scrollbar(win, orient=tk.VERTICAL)
        customers_scroll2.grid(row=5, column=1, sticky=tk.NS)
        customers_var2 = tk.StringVar(value=liste)
        customers_list2 = tk.Listbox(win, height=10, listvariable=customers_var2, yscrollcommand=customers_scroll2.set)
        customers_list2.grid(row=5, column=0)
        
        win.mainloop()
        1. Contributeur

          Pour supprimer un élément de la liste, tu utilises remove() au lieu de append().

        2. @yg_be

          et ça mettra à jour ma fenêtre ?

        3. Contributeur
          @madrid974

          Oui, si, dans ta fonction de suppression, tu reprends ce que tu as mis dans ta fonction d'ajout pour mettre la fenêtre à jour.

      2. ça fonctionne merci.

        Toute dernière question ma fenêtre affiche également la liste complète des clients dans un tableau (je ne parle pas du menu déroulant). Il s'ajoute automatiquement avec ce bout de code lorsque je crée un client.

        mysqldb = sqlite3.connect("test.db")
        cursor = mysqldb.cursor()
        select = cursor.execute("SELECT * FROM clients ORDER BY idclient DESC")
        select = list(select)
        listBox.insert('', END, values = select[0])
        mysqldb.close()

        comment je dois faire si je veux supprimer la ligne lorsque je supprime un client? J'imagine que je dois faire un listBox.delete(??) mais après plusieurs essais, ça ne fonctionne toujours pas.

        from curses.ascii import isdigit
        import tkinter as tk
        from tkinter import END, StringVar, ttk, messagebox
        import sqlite3
        
        from git import refresh
        import afficher_panier
        import liste_detailcommandes
        
        win = tk.Tk()   
        win.geometry('1850x600')
        
        win.title("Gestion commerciale")  
        
        tabControl = ttk.Notebook(win)
        
        tab1 = ttk.Frame(tabControl)
        tabControl.add(tab1, text='Gestion client')
        tab2 = ttk.Frame(tabControl)
        tabControl.add(tab2, text='Articles / Stock')
        tab3 = ttk.Frame(tabControl)
        tabControl.add(tab3, text='Commandes')
        tab4 = ttk.Frame(tabControl)
        tabControl.add(tab4, text='Archives')
        tab5 = ttk.Frame(tabControl)
        tabControl.add(tab5, text='Statistiques')
        
        tabControl.pack(expand=1, fill="both")
        
        mysqldb = sqlite3.connect("test.db")
        cursor = mysqldb.cursor()
        
        def add_client():
            newNomfamille = var_nom.get()
            var_nom.set('')
            newPrenom = var_prenom.get()
            var_prenom.set('')
            newVille = var_ville.get()
            var_ville.set('')
            newTelephone = var_telephone.get()
            var_telephone.set('')
            newRGPD = var_rgpd.get()
            mysqldb = sqlite3.connect("test.db")
            cursor = mysqldb.cursor()
            sql = cursor.execute("select max(idclient)+1 from clients") # On récupère l'idmax de la table clients
            sql = list(sql)
            sql2 = str(sql).strip('[]')
            if sql2 == '(None,)':
                sql = 1
                liste.append((sql,newNomfamille,newPrenom))
                customers_var.set(liste)
            else:
                liste.append((sql,newNomfamille,newPrenom))
                customers_var.set(liste)
        
            mysqldb = sqlite3.connect("test.db")
            cursor = mysqldb.cursor()
            cursor.execute("SELECT COUNT(*) FROM clients WHERE nom = '"+ newNomfamille +"' and telephone = '"+ newTelephone +"' ")
            result = cursor.fetchone()
            mysqldb.commit()
            if int(result[0]) > 0:
                messagebox.showinfo("Erreur", "Ce client existe déjà")
            else:
                messagebox.showinfo("Succès", "Le client a été enregistré")
                cursor.execute("INSERT INTO clients(nom, prenom, ville, telephone,donneespersonnelles) VALUES('"+ newNomfamille +"','"+ newPrenom +"','"+ newVille +"','"+ newTelephone +"','"+ newRGPD +"')")
                mysqldb.commit()
            mysqldb.close()
            #show last add
            mysqldb = sqlite3.connect("test.db")
            cursor = mysqldb.cursor()
            select = cursor.execute("SELECT * FROM clients ORDER BY idclient DESC")
            select = list(select)
            listBox.insert('', END, values = select[0])
            mysqldb.close()
            #-------
        
        mighty=ttk.LabelFrame(tab1,width=200,height=200,text=" Créer un client ")
        mighty.grid(row=0,column=0,padx=10,pady=5,ipady=10,ipadx=10,sticky="we")
        
        l_nom = ttk.Label(mighty, text="Nom : ")
        l_nom.grid(row=0, column=0,padx=10,pady=10,sticky="w")
        
        l_prenom = ttk.Label(mighty, text="Prénom :")
        l_prenom.grid(row=1, column=0,padx=10,pady=10,sticky="w")
        
        l_ville = ttk.Label(mighty, text="Ville : ")
        l_ville.grid(row=2, column=0,padx=10,pady=10,sticky="w")
        
        l_telephone = ttk.Label(mighty, text="Téléphone :")
        l_telephone.grid(row=3, column=0,padx=10,pady=10,sticky="w")
        
        l_rgpd = ttk.Label(mighty, text="Données personnelles :")
        l_rgpd.grid(row=4, column=0,padx=10,pady=10,sticky="w")
        
        var_nom = tk.StringVar()
        nom_add_label = tk.Entry(mighty, textvariable=var_nom, width=18)
        nom_add_label.grid(row=0, column=1)
        
        var_prenom = tk.StringVar()
        prenom_add_label = tk.Entry(mighty, textvariable=var_prenom, width=18)
        prenom_add_label.grid(row=1, column=1, sticky="w")
        
        var_ville = tk.StringVar()
        ville_add_label = tk.Entry(mighty, textvariable=var_ville, width=18)
        ville_add_label.grid(row=2, column=1, sticky="w")
        
        var_telephone = tk.StringVar()
        telephone_add_label = tk.Entry(mighty, textvariable=var_telephone, width=18)
        telephone_add_label.grid(row=3, column=1, sticky="w")
        
        var_rgpd=StringVar()
        var_rgpd.set("Oui")
        rgpd1=ttk.Radiobutton(mighty, text="oui", variable=var_rgpd,value="Oui")
        rgpd2=ttk.Radiobutton(mighty, text="non", variable=var_rgpd,value="Non")
        rgpd1.grid(row=4, column=1, sticky="w")
        rgpd2.grid(row=5, column=1, sticky="w")
        
        b_add_client = ttk.Button(mighty,text="Créer le client", command=add_client)
        b_add_client.grid(row=6, column=0,padx=10,pady=10,sticky="w")
        
        titreclient = ttk.Label(tab1, text= 'LISTE DES CLIENTS',font = ("Arial" , 25 , "bold"))
        titreclient.place(x = 880, y = 20)
        
        listBox = ttk.Treeview(tab1, columns=(1,2,3,4,5,6), show='headings' )
        
        listBox.place(x = 400, y = 90, height = 358)
        
        listBox.heading(1, text="N° client")
        listBox.column(1, width=100)
        listBox.heading(2, text="Nom")
        listBox.heading(3, text="Prénom")
        listBox.heading(4, text="Ville")
        listBox.heading(5, text="N° téléphone")
        listBox.heading(6, text="Données personnelles")
        
        sql = cursor.execute("SELECT idclient,nom,prenom,ville,telephone,donneespersonnelles from clients")
        
        for col in sql:
            listBox.insert("", "end", values=col)
        
        mighty2=ttk.LabelFrame(tab1,width=200,height=200,text=" Supprimer un client ")
        mighty2.grid(row=1,column=0,padx=10,pady=5,ipady=10,ipadx=10,sticky="we")
        
        l_del_client = ttk.Label(mighty2, text="Client : ")
        l_del_client.grid(row=0, column=0,padx=10,pady=10,sticky="w")
        
        def del_client():
            supClient = customers_list.get(customers_list.curselection())
            supClient = str(supClient[0])
            #print(liste)
            #print(supClient)
            mysqldb = sqlite3.connect("test.db")
            cursor = mysqldb.cursor()
            if str(supClient) == str(liste[0][0]):
                liste.remove((liste[0][0],liste[0][1],liste[0][2]))
                customers_var.set(liste)
                mysqldb.commit()
            else:
                mysqldb.commit()
        
            listBox.delete(?????)
            mysqldb.commit()
            mysqldb.close()
            messagebox.showinfo("Succès", "Le client a été supprimé")
        
        b_del_client = ttk.Button(mighty2,text="Supprimer le client", command=del_client)
        b_del_client.grid(row=1, column=0,padx=10,pady=10,sticky="w")
        
        liste = []
        cursor.execute("select idclient,nom,prenom from clients;")
        result = cursor.fetchall()
        for row in result:
             liste.append(row)
        
        customers_scroll = tk.Scrollbar(mighty2, orient=tk.VERTICAL)
        customers_scroll.grid(row=0, column=2, sticky=tk.NS)
        customers_var = tk.StringVar(value=liste)
        customers_list = tk.Listbox(mighty2, height=3, listvariable=customers_var, yscrollcommand=customers_scroll.set)
        customers_list.grid(row=0, column=1)
        
        def exit():
            win.destroy()
        button_exit = tk.Button(win,text = "Quitter",command = exit)
        button_exit.place(x = 900, y = 500,width = 200, height = 50)
        
        win.mainloop()
        1. Contributeur

          Moi j'essaierais de faire une boucle sur les éléments de la Treeview, et, si c'est l'élément à supprimer, de le supprimer.

          for cli in listBox:
              if ....:
                   listBox.delete(cli)