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. ç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)
  2. 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.

  3. 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. 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. 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. 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()
      2. 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.