From 8c09578ada3a96c180a045e7a4ffb4e9d63ef8d1 Mon Sep 17 00:00:00 2001 From: SUBHASH Date: Thu, 24 Oct 2024 20:14:25 +0530 Subject: [PATCH] CONTACT-MANAGEMENT-SYSTEM Contact Management System (CMS) - a comprehensive and user-friendly tool designed to streamline your contact management process. Developed with Python's Tkinter library for an intuitive GUI, SQLite for robust data storage, and Openpyxl for seamless data export to Excel, this system is a cut above the rest --- cms.py | 429 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 429 insertions(+) create mode 100644 cms.py diff --git a/cms.py b/cms.py new file mode 100644 index 00000000..02232ba5 --- /dev/null +++ b/cms.py @@ -0,0 +1,429 @@ +from tkinter import * +import tkinter.ttk as ttk +import tkinter.messagebox as tkMessageBox +import sqlite3 +from openpyxl import Workbook +from openpyxl import load_workbook + +# Global variable to store selected contact ID +selected_contact_ids = set() + +def ExportData(): + global selected_contact_ids + if not selected_contact_ids: + tkMessageBox.showwarning('', 'Please Select Contacts to Export!', icon="warning") + else: + # Load existing workbook or create a new one if it doesn't exist + try: + wb = load_workbook("exported_contacts.xlsx") + ws = wb.active + except FileNotFoundError: + wb = Workbook() + ws = wb.active + ws.append(["MemberID", "Firstname", "Lastname", "Gender", "Age", "Address", "Contact", "Email", "Notes"]) + + conn = sqlite3.connect("pythontut.db") + cursor = conn.cursor() + for contact_id in selected_contact_ids: + cursor.execute("SELECT * FROM `member` WHERE `mem_id` =?", (contact_id,)) + contact_data = cursor.fetchone() + ws.append(contact_data) + conn.close() # Close connection after fetching all data + # Save all selected contacts in the same Excel file + wb.save("exported_contacts.xlsx") + tkMessageBox.showinfo('', 'Contacts exported successfully!') + +def OnSelected(event): + global selected_contact_ids + curItem = tree.focus() + selected_contact_ids = [tree.item(curItem, "values")[0]] + if event.num == 1: + UpdateData() + elif event.num == 3: + ExportData() + +def DisplayData(): + # Clear existing entries in the treeview + for record in tree.get_children(): + tree.delete(record) + conn = sqlite3.connect("pythontut.db") + cursor = conn.cursor() + cursor.execute("SELECT * FROM `member` ORDER BY `lastname` ASC") + fetch = cursor.fetchall() + for data in fetch: + tree.insert('', 'end', values=(data)) + cursor.close() + conn.close() + +root = Tk() +root.title("Contact List") +width = 700 +height = 400 +screen_width = root.winfo_screenwidth() +screen_height = root.winfo_screenheight() +x = (screen_width/2) - (width/2) +y = (screen_height/2) - (height/2) +root.geometry("%dx%d+%d+%d" % (width, height, x, y)) +root.resizable(0, 0) +root.config(bg="#6666ff") + +FIRSTNAME = StringVar() +LASTNAME = StringVar() +GENDER = StringVar() +AGE = StringVar() +ADDRESS = StringVar() +CONTACT = StringVar() +EMAIL = StringVar() +SEARCH = StringVar() +NOTES = StringVar() + +def Database(): + conn = sqlite3.connect("pythontut.db") + cursor = conn.cursor() + cursor.execute( + "CREATE TABLE IF NOT EXISTS `member` (mem_id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, firstname TEXT, lastname TEXT, gender TEXT, age TEXT, address TEXT, contact TEXT, Email TEXT, notes TEXT)") + cursor.execute("SELECT * FROM `member` ORDER BY `lastname` ASC") + fetch = cursor.fetchall() + for data in fetch: + tree.insert('', 'end', values=(data)) + cursor.close() + conn.close() + +def SubmitData(): + if FIRSTNAME.get() == "" or LASTNAME.get() == "" or GENDER.get() == "" or AGE.get() == "" or ADDRESS.get() == "" or CONTACT.get() == "" or EMAIL.get() == "": + result = tkMessageBox.showwarning( + '', 'Please Complete The Required Field', icon="warning") + else: + tree.delete(*tree.get_children()) + conn = sqlite3.connect("pythontut.db") + cursor = conn.cursor() + cursor.execute("INSERT INTO `member` (firstname, lastname, gender, age, address, contact, email, notes) VALUES(?, ?, ?, ?, ?, ?, ?, ?)", + (str(FIRSTNAME.get()), str(LASTNAME.get()), str(GENDER.get()), int(AGE.get()), str(ADDRESS.get()), str(CONTACT.get()), str(EMAIL.get()), str(NOTES.get()))) + conn.commit() + cursor.execute( + "SELECT * FROM `member` ORDER BY `lastname` ASC") + fetch = cursor.fetchall() + for data in fetch: + tree.insert('', 'end', values=(data)) + cursor.close() + conn.close() + FIRSTNAME.set("") + LASTNAME.set("") + GENDER.set("") + AGE.set("") + ADDRESS.set("") + CONTACT.set("") + EMAIL.set("") + NOTES.set("") + + +def UpdateData(): + if FIRSTNAME.get() == "" or LASTNAME.get() == "" or GENDER.get() == "" or AGE.get() == "" or ADDRESS.get() == "" or CONTACT.get() == "" or EMAIL.get() == "": + result = tkMessageBox.showwarning( + '', 'Please Complete The Required Field', icon="warning") + else: + tree.delete(*tree.get_children()) + conn = sqlite3.connect("pythontut.db") + cursor = conn.cursor() + cursor.execute("UPDATE `member` SET `firstname` = ?, `lastname` = ?, `gender` = ?, `age` = ?, `address` = ?, `contact` = ?, `email` = ?, `notes` = ? WHERE `mem_id` = ?", + (str(FIRSTNAME.get()), str(LASTNAME.get()), str(GENDER.get()), str(AGE.get()), str(ADDRESS.get()), str(CONTACT.get()), str(EMAIL.get()), str(NOTES.get()), int(mem_id))) + conn.commit() + cursor.execute( + "SELECT * FROM `member` ORDER BY `lastname` ASC") + fetch = cursor.fetchall() + for data in fetch: + tree.insert('', 'end', values=(data)) + cursor.close() + conn.close() + FIRSTNAME.set("") + LASTNAME.set("") + GENDER.set("") + AGE.set("") + ADDRESS.set("") + CONTACT.set("") + EMAIL.set("") + NOTES.set("") + +def OnSelected(event): + global mem_id, UpdateWindow, selected_contact_ids + curItem = tree.focus() + contents = (tree.item(curItem)) + selecteditem = contents['values'] + mem_id = selecteditem[0] + FIRSTNAME.set(selecteditem[1]) + LASTNAME.set(selecteditem[2]) + GENDER.set(selecteditem[3]) + AGE.set(selecteditem[4]) + ADDRESS.set(selecteditem[5]) + CONTACT.set(selecteditem[6]) + EMAIL.set(selecteditem[7]) + NOTES.set(selecteditem[8]) + selected_contact_ids = [tree.item(curItem, "values")[0]] + if event.num == 1: + UpdateWindow = Toplevel() + UpdateWindow.title("Contact List") + width = 400 + height = 700 + screen_width = root.winfo_screenwidth() + screen_height = root.winfo_screenheight() + x = ((screen_width/2) + 450) - (width/2) + y = ((screen_height/2) + 20) - (height/2) + UpdateWindow.resizable(0, 0) + UpdateWindow.geometry("%dx%d+%d+%d" % (width, height, x, y)) + if 'NewWindow' in globals(): + NewWindow.destroy() + + # ===================FRAMES============================== + FormTitle = Frame(UpdateWindow) + FormTitle.pack(side=TOP) + ContactForm = Frame(UpdateWindow) + ContactForm.pack(side=TOP, pady=10) + RadioGroup = Frame(ContactForm) + Male = Radiobutton( + RadioGroup, text="Male", variable=GENDER, value="Male", font=('arial', 14)).pack(side=LEFT) + Female = Radiobutton( + RadioGroup, text="Female", variable=GENDER, value="Female", font=('arial', 14)).pack(side=LEFT) + + # ===================LABELS============================== + lbl_title = Label(FormTitle, text="Update Contacts", + font=('arial', 16), bg="orange", width=300) + lbl_title.pack(fill=X) + lbl_firstname = Label(ContactForm, text="Firstname", + font=('arial', 14), bd=5) + lbl_firstname.grid(row=0, sticky=W) + lbl_lastname = Label(ContactForm, text="Lastname", + font=('arial', 14), bd=5) + lbl_lastname.grid(row=1, sticky=W) + lbl_gender = Label(ContactForm, text="Gender", + font=('arial', 14), bd=5) + lbl_gender.grid(row=2, sticky=W) + lbl_age = Label(ContactForm, text="Age", + font=('arial', 14), bd=5) + lbl_age.grid(row=3, sticky=W) + lbl_address = Label(ContactForm, text="Address", + font=('arial', 14), bd=5) + lbl_address.grid(row=4, sticky=W) + lbl_contact = Label(ContactForm, text="Contact", + font=('arial', 14), bd=5) + lbl_contact.grid(row=5, sticky=W) + lbl_email = Label(ContactForm, text="Email", + font=('arial', 14), bd=5) + lbl_email.grid(row=6, sticky=W) + lbl_notes = Label(ContactForm, text="Notes", + font=('arial', 14), bd=5) + lbl_notes.grid(row=7, sticky=W) + + # ===================ENTRY=============================== + firstname = Entry(ContactForm, textvariable=FIRSTNAME, font=('arial', 14)) + firstname.grid(row=0, column=1) + lastname = Entry(ContactForm, textvariable=LASTNAME, font=('arial', 14)) + lastname.grid(row=1, column=1) + RadioGroup.grid(row=2, column=1) + age = Entry(ContactForm, textvariable=AGE, font=('arial', 14)) + age.grid(row=3, column=1) + address = Entry(ContactForm, textvariable=ADDRESS, font=('arial', 14)) + address.grid(row=4, column=1) + contact = Entry(ContactForm, textvariable=CONTACT, font=('arial', 14)) + contact.grid(row=5, column=1) + email = Entry(ContactForm, textvariable=EMAIL, font=('arial', 14)) + email.grid(row=6, column=1) + notes = Entry(ContactForm, textvariable=NOTES, font=('arial', 14)) + notes.grid(row=7, column=1) + + # ==================BUTTONS============================== + btn_updatecommand = Button(ContactForm, text="Update", + width=50, command=UpdateData) + btn_updatecommand.grid(row=8, columnspan=2, pady=10) + + +def DeleteData(): + if not tree.selection(): + result = tkMessageBox.showwarning( + '', 'Please Select Something First!', icon="warning") + else: + result = tkMessageBox.askquestion( + '', 'Are you sure you want to delete this record?', icon="warning") + if result == 'yes': + curItem = tree.focus() + contents = (tree.item(curItem)) + selecteditem = contents['values'] + tree.delete(curItem) + conn = sqlite3.connect("pythontut.db") + cursor = conn.cursor() + cursor.execute( + "DELETE FROM `member` WHERE `mem_id` = %d" % selecteditem[0]) + conn.commit() + cursor.close() + conn.close() + +def AddNewWindow(): + global NewWindow + FIRSTNAME.set("") + LASTNAME.set("") + GENDER.set("") + AGE.set("") + ADDRESS.set("") + CONTACT.set("") + EMAIL.set("") + NOTES.set("") + NewWindow = Toplevel() + NewWindow.title("Contact List") + width = 400 + height = 700 + screen_width = root.winfo_screenwidth() + screen_height = root.winfo_screenheight() + x = ((screen_width/2) - 450) - (width/2) + y = ((screen_height/2) + 20) - (height/2) + NewWindow.resizable(0, 0) + NewWindow.geometry("%dx%d+%d+%d" % (width, height, x, y)) + + # ===================FRAMES============================== + FormTitle = Frame(NewWindow) + FormTitle.pack(side=TOP) + ContactForm = Frame(NewWindow) + ContactForm.pack(side=TOP, pady=10) + RadioGroup = Frame(ContactForm) + Male = Radiobutton(RadioGroup, text="Male", variable=GENDER, value="Male", font=('arial', 14)).pack(side=LEFT) + Female = Radiobutton(RadioGroup, text="Female", variable=GENDER, value="Female", font=('arial', 14)).pack(side=LEFT) + + # ===================LABELS============================== + lbl_title = Label(FormTitle, text="Adding New Contacts", font=('arial', 16), bg="#66ff66", width=300) + lbl_title.pack(fill=X) + lbl_firstname = Label(ContactForm, text="Firstname", font=('arial', 14), bd=5) + lbl_firstname.grid(row=0, sticky=W) + lbl_lastname = Label(ContactForm, text="Lastname", font=('arial', 14), bd=5) + lbl_lastname.grid(row=1, sticky=W) + lbl_gender = Label(ContactForm, text="Gender", font=('arial', 14), bd=5) + lbl_gender.grid(row=2, sticky=W) + lbl_age = Label(ContactForm, text="Age", font=('arial', 14), bd=5) + lbl_age.grid(row=3, sticky=W) + lbl_address = Label(ContactForm, text="Address", font=('arial', 14), bd=5) + lbl_address.grid(row=4, sticky=W) + lbl_contact = Label(ContactForm, text="Contact", font=('arial', 14), bd=5) + lbl_contact.grid(row=5, sticky=W) + lbl_email = Label(ContactForm, text="Email", font=('arial', 14), bd=5) + lbl_email.grid(row=6, sticky=W) + lbl_notes = Label(ContactForm, text="Notes", font=('arial', 14), bd=5) + lbl_notes.grid(row=7, sticky=W) + + # ===================ENTRY=============================== + firstname = Entry(ContactForm, textvariable=FIRSTNAME, font=('arial', 14)) + firstname.grid(row=0, column=1) + lastname = Entry(ContactForm, textvariable=LASTNAME, font=('arial', 14)) + lastname.grid(row=1, column=1) + RadioGroup.grid(row=2, column=1) + age = Entry(ContactForm, textvariable=AGE, font=('arial', 14)) + age.grid(row=3, column=1) + address = Entry(ContactForm, textvariable=ADDRESS, font=('arial', 14)) + address.grid(row=4, column=1) + contact = Entry(ContactForm, textvariable=CONTACT, font=('arial', 14)) + contact.grid(row=5, column=1) + email = Entry(ContactForm, textvariable=EMAIL, font=('arial', 14)) + email.grid(row=6, column=1) + notes = Entry(ContactForm, textvariable=NOTES, font=('arial', 14)) + notes.grid(row=7, column=1) + + # ==================BUTTONS============================== + btn_addcommand = Button(ContactForm, text="Save", width=50, command=SubmitData) + btn_addcommand.grid(row=8, columnspan=2, pady=10) + + +def SearchData(): + if SEARCH.get() != "": + tree.delete(*tree.get_children()) + conn = sqlite3.connect("pythontut.db") + cursor = conn.cursor() + cursor.execute("SELECT * FROM `member` WHERE `firstname` LIKE ? OR `lastname` LIKE ?", + ('%' + str(SEARCH.get()) + '%', '%' + str(SEARCH.get()) + '%')) + fetch = cursor.fetchall() + for data in fetch: + tree.insert('', 'end', values=(data)) + cursor.close() + conn.close() + + + + + +# ============================FRAMES===================================== +Top = Frame(root, width=700, bd=1, relief=SOLID) +Top.pack(side=TOP) +Mid = Frame(root, width=700, bg="#6666ff") +Mid.pack(side=TOP) +MidLeft = Frame(Mid, width=100) +MidLeft.pack(side=LEFT, pady=10) +MidLeftPadding = Frame(Mid, width=350, bg="#6666ff") +MidLeftPadding.pack(side=LEFT) +MidRight = Frame(Mid, width=100) +MidRight.pack(side=RIGHT, pady=10) +MidRightPadding = Frame(Mid, width=100, bg="#6666ff") +MidRightPadding.pack(side=RIGHT) +TableMargin = Frame(root, width=500) +TableMargin.pack(side=TOP) +# ============================LABELS===================================== +lbl_title = Label(Top, width=700, font=('arial', 18), text="Contact List") +lbl_title.pack(fill=X) + +# ============================ENTRY======================================= +search = Entry(MidLeft, textvariable=SEARCH, font=('arial', 14)) +search.pack() +# ============================BUTTONS===================================== +btn_add = Button(MidLeft, text="+ ADD NEW", bg="#66ff66", command=AddNewWindow) +btn_add.pack() +btn_search = Button(MidLeft, text="SEARCH", + bg="yellow", command=SearchData) +btn_search.pack() +btn_export = Button(MidRight, text="EXPORT", + bg="blue", command=ExportData) +btn_export.pack(side=RIGHT) +btn_delete = Button(MidRight, text="DELETE", + bg="red", command=DeleteData) +btn_delete.pack(side=RIGHT) + + +# ============================TABLES===================================== +scrollbarx = Scrollbar(TableMargin, orient=HORIZONTAL) +scrollbary = Scrollbar(TableMargin, orient=VERTICAL) +tree = ttk.Treeview(TableMargin, columns=("MemberID", "Firstname", "Lastname", "Gender", "Age", "Address", "Contact", "Email", "Notes"), + height=400, selectmode="extended", yscrollcommand=scrollbary.set, xscrollcommand=scrollbarx.set) +scrollbary.config(command=tree.yview) +scrollbary.pack(side=RIGHT, fill=Y) +scrollbarx.config(command=tree.xview) +scrollbarx.pack(side=BOTTOM, fill=X) +tree.heading('MemberID', text="MemberID", anchor=W) +tree.heading('Firstname', text="Firstname", anchor=W) +tree.heading('Lastname', text="Lastname", anchor=W) +tree.heading('Gender', text="Gender", anchor=W) +tree.heading('Age', text="Age", anchor=W) +tree.heading('Address', text="Address", anchor=W) +tree.heading('Contact', text="Contact", anchor=W) +tree.heading('Email', text="Email", anchor=W) +tree.heading('Notes', text="Notes", anchor=W) +tree.column('#0', stretch=NO, minwidth=0, width=0) +tree.column('#1', stretch=NO, minwidth=0, width=80) +tree.column('#2', stretch=NO, minwidth=0, width=120) +tree.column('#3', stretch=NO, minwidth=0, width=120) +tree.column('#4', stretch=NO, minwidth=0, width=50) +tree.column('#5', stretch=NO, minwidth=0, width=150) +tree.column('#6', stretch=NO, minwidth=0, width=120) +tree.column('#7', stretch=NO, minwidth=0, width=120) +tree.column('#8', stretch=NO, minwidth=0, width=120) +tree.pack() +tree.bind('', OnSelected) +tree.bind('', OnSelected) + +# ============================INITIALIZATION============================= +if __name__ == '__main__': + #root = Tk() + #root.title("Contact List") + #width = 700 + #height = 400 + #screen_width = root.winfo_screenwidth() + #screen_height = root.winfo_screenheight() + #x = (screen_width/2) - (width/2) + #y = (screen_height/2) - (height/2) + #root.resizable(0, 0) + #root.geometry("%dx%d+%d+%d" % (width, height, x, y)) + #root.config(bg="blue") + Database() + root.mainloop() \ No newline at end of file