Flat Details

root = tk.Toplevel()
root.title("Add Flat")
root.configure(bg="#585858")
root.resizable(width=0, height=0
win_width = 1280
print(1280 * 56.25 / 100)
win_height = int(1280 * 52 / 100)
root.geometry(str(win_width) + "x" + str(win_height))
Util.center(root)
# Get screen size
screen_width = self.winfo_screenwidth()
screen_height = self.winfo_screenheight()
Util.set_font_size(screen_width, screen_height, win_width, win_height)
self.width = win_width * 96 / 100
self.height = win_height * 94 / 100
After creation of window, we will add a canvas background.
bg_canvas = RoundBackgroundFrame(root, self.width, self.height, padding, cornerradius,color_2, "#585858")
bg_canvas.place(width=self.width, height=self.height, x=win_width / 2 - self.width / 2,
y=win_height / 2 - self.height / 2)
class RoundBackgroundFrame(tk.Canvas):
def __init__(self, parent, width, height, padding, cornerradius, color, bg):
tk.Canvas.__init__(self, parent, borderwidth=0, relief="flat", highlightthickness=0, bg=bg)
self.width = width
self.height = height
self.padding = padding
self.cornerradius = cornerradius
self.color = color
original = Image.open("images/corner_green.png")
resized = original.resize((int(40), int(40)), Image.ANTIALIAS)
self.image_r_t = ImageTk.PhotoImage(resized)
original = original.rotate(90, expand=0)
resized = original.resize((int(40), int(40)), Image.ANTIALIAS)
self.image_l_t = ImageTk.PhotoImage(resized)
# original = Image.open("images/corner.png")
original = original.rotate(90, expand=0)
resized = original.resize((int(40), int(40)), Image.ANTIALIAS)
self.image_l_b = ImageTk.PhotoImage(resized)
original = original.rotate(90, expand=0)
resized = original.resize((int(40), int(40)), Image.ANTIALIAS)
self.image_r_b = ImageTk.PhotoImage(resized)
self.shape(width, height, padding, cornerradius, color)
(x0, y0, x1, y1) = self.bbox("all")
width = (x1 - x0)
height = (y1 - y0)
self.configure(width=width, height=height)
def shape(self, width, height, padding, cornerradius, color):
self.create_polygon((padding, height - cornerradius - padding, padding, cornerradius + padding,
padding + cornerradius, padding, width - padding - cornerradius, padding,
width - padding, cornerradius + padding, width - padding,
height - cornerradius - padding, width - padding - cornerradius, height - padding,
padding + cornerradius, height - padding), fill=color, outline=color)
self.create_image(width - self.image_r_t.width(), 0, image=self.image_r_t, anchor=NW)
self.create_image(0, 0, image=self.image_l_t, anchor=NW)
self.create_image(0, height - self.image_l_b.width(), image=self.image_l_b, anchor=NW)
self.create_image(width - self.image_r_b.width(), height - self.image_r_b.width(), image=self.image_r_b,
anchor=NW)
self.width = self.width * 98 / 100
self.height = self.height * 96 / 100
self.base_frame = Frame(root, width=self.width, height=self.height, bg=self.color)
bg_canvas.create_window(self.width / 100, self.height * 2 / 100, anchor=NW, window=self.base_frame)
# Add Heading Name
add_heading_label(self.base_frame, self.color, AppConstant.FONT_SIZE, self.height, self.width)
def add_heading_label(base_frame, color, font_size, height, width):
label_heading = Label(base_frame, text="FLAT DETAIL", anchor=CENTER, bg=color,
font=("Lucida Grande", int(font_size*120/100)))
label_heading.place(width=width * 90 / 100, height=height * 7 / 100, x=width * 5 / 100, y=height * 2/ 100)
# Add line
add_line_border(self.base_frame, self.color, self.height, self.width)
def add_line_border(base_frame, color, height, width):
line_canvas = Canvas(base_frame, bg=color, borderwidth=0, relief="flat", highlightthickness=0)
line_canvas.place(width=width - 4, height=5, x=2, y=height * 10 / 100)
line_canvas.create_line(0, 0, width, 0, fill="#787878")
self.action_frame = add_action_frame(self, self.base_frame, self.color, self.height, self.width)
def add_action_frame(self,base_frame, color, height, width):
afw = width * 95/100
afh = height *20/100
button_font = ("Lucida Grande", AppConstant.FONT_SIZE - 6)
label_frame_action = LabelFrame(base_frame, text="Actions", font=button_font, pady=afw * 2 / 100,
padx=afw * 2 / 100, bg=color)
label_frame_action.place(width=afw, height=afh, x=width*2.5/100, y=height * 0.12)
return label_frame_action
self.search_frame = add_search_frame(self.base_frame, self.color, self.height, self.width)
def add_search_frame(base_frame,color, height, width):
sfw = width * 64/100
sfh = height *60/100
button_font = ("Lucida Grande", AppConstant.FONT_SIZE - 6)
label_frame_search = LabelFrame(base_frame, text="Search", font=button_font, pady=sfw * 2 / 100,
padx=sfw * 2 / 100, bg=color)
label_frame_search.place(width=sfw, height=sfh, x=width*2.5/100, y=height * 0.12+height *22/100)
Now We create add flat UI in Action Frame.
self.flat_no = CustomEntrySimple(self.action_frame, entry_width, entry_height, ("Lucida Grande", text_size), self.color,
"Flat No:")
self.flat_no.place(x=20, y=pos_y)
self.flat_owner_name = CustomEntrySimple(self.action_frame, entry_width, entry_height, ("Lucida Grande", text_size), self.color,
"Flat Owner Name:")
self.flat_owner_name.place(x=250, y=pos_y)
self.flat_owner_contact = CustomEntrySimple(self.action_frame, entry_width, entry_height, ("Lucida Grande",text_size), self.color,
"Contact:")
self.flat_owner_contact.place(x=480, y=pos_y)
self.get_flat_status_label(entry_width,entry_height,text_size)
self.show_add_flat_button()
Here is our class CustomEntrySimple:
class CustomEntrySimple(tk.Canvas):
def __init__(self, parent, width, height, font, color, text):
tk.Canvas.__init__(self, parent, borderwidth=0, relief="flat", highlightthickness=0, bg=color)
self.width = width
self.height = height
self.color = color
self.create_text(6, 6, anchor=W, font=font, text=text, fill="#000000")
self.create_line(5, height - 8, width - 5, height - 8, fill="#808080")
frame = Frame(parent, width=width * 95 / 100, height=height * 50 / 100)
self.entry = Entry(frame, bg=color, bd=0, highlightthickness=0, font=font)
self.entry.place(relwidth=1, relheight=1, x=0, y=0)
self.create_window(6, height / 2 - (height * 50 / 100) / 2, anchor=NW, window=frame)
self.update()
(x0, y0, x1, y1) = self.bbox("all")
width = (x1 - x0)
height = (y1 - y0)
self.configure(width=width, height=height)
Create a "ADD FLAT" button in Action Frame.
def show_add_flat_button(self):
self.add_button = RoundedButton(self.base_frame, self.width * 12 / 100, self.width * 3 / 100, self.color, "images/button3.png",
"ADD FLAT",
font=("Lucida Grande", int(AppConstant.FONT_SIZE*75/100)),
command=self.add_flat_click)
self.add_button.place(x=self.width*83/100, y=self.height * 22/100)
class RoundedButton(tk.Canvas):
def __init__(self, parent, width, height, bg, icon_path, text, font, command=None):
tk.Canvas.__init__(self, parent, borderwidth=0, relief="flat", highlightthickness=0, bg=bg)
self.command = command
self.width = width
self.height = height
self.text = text
self.font = font
original = Image.open(icon_path)
resized = original.resize((int(width), int(height)), Image.ANTIALIAS)
self.image = ImageTk.PhotoImage(resized)
self.shape(width, height)
(x0, y0, x1, y1) = self.bbox("all")
width = (x1 - x0)
height = (y1 - y0)
self.configure(width=width, height=height)
self.bind("", self._on_press)
self.bind("", self._on_release)
def shape(self, width, height):
self.create_image(0, 0, image=self.image, anchor=NW)
self.create_text(width / 2, height / 2, anchor=CENTER, font=self.font, text=self.text, fill="#FFFFFF")
def shape_press(self, width, height):
self.create_image(0, 0, image=self.image, anchor=NW)
self.create_text(width / 2, height / 2, anchor=CENTER, font=self.font, text=self.text, fill="#000000")
def _on_press(self, event):
self.configure(relief="sunken")
self.delete("all")
# self.update()
self.shape_press(self.width, self.height)
def _on_release(self, event):
self.configure(relief="raised")
self.delete("all")
self.shape(self.width, self.height)
if self.command is not None:
self.command()
self.ce_flat_var = CustomEntry(self.base_frame, entry_width*7/4, entry_height*88/100, 10, 2, self.color, "Search Flat",
"images/ic_search.png")
self.ce_flat_var.place(x=self.width*5/100, y=self.height*38/100)
self.ce_flat_var.entry.bind('', self.search_flat)
Here's the logic to search data in table
def search_flat(self, *arg):
if self.ce_book_var.entry.get() != "":
self.tree.delete(*self.tree.get_children())
conn = Util.connect_db()
cursor = conn.cursor()
cursor.execute(
"SELECT id, flat_no, flat_owner_name, contact_no, flat_status FROM `flat_detail` WHERE `flat_no` LIKE ? OR `flat_owner_name` LIKE ?",
('%' + str(self.ce_flat_var.entry.get()) + '%',
'%' + str(self.ce_flat_var.entry.get()) + '%'))
fetch = cursor.fetchall()
count = 0
for data in fetch:
if count % 2 == 0:
self.tree.insert('', 'end', values=data, tags=('even',))
else:
self.tree.insert('', 'end', values=data, tags=('odd',))
count = count + 1
cursor.close()
conn.close()
else:
self.reset_flat()
def reset_flat(self):
self.tree.delete(*self.tree.get_children())
self.update_table_data()
class Util:
@staticmethod
def connect_db():
db = None
try:
db = sql.connect("securitySystem.db")
return db
except sql.Error as error:
print("Failed to insert data into sqlite table", error)
Fetch data from database and show it in table form with the use of "Treeview" of Tkinter.
style = ttk.Style()
# style.element_create("Custom.Treeheading.border", "from", "default")
style.layout("Custom.Treeview.Heading", [
("Custom.Treeheading.cell", {'sticky': 'nswe'}),
("Custom.Treeheading.border", {'sticky': 'nswe', 'children': [
("Custom.Treeheading.padding", {'sticky': 'nswe', 'children': [
("Custom.Treeheading.image", {'side': 'right', 'sticky': ''}),
("Custom.Treeheading.text", {'sticky': 'we'})
]})
]}),
])
# style.configure("Custom.Treeview.Heading", background="blue", foreground="red", relief="flat")
style.map("Custom.Treeview.Heading",relief=[('active', 'groove'), ('pressed', 'sunken')])
style.configure("Custom.Treeview", highlightthickness=0, bd=0, font=('Calibri', int(AppConstant.FONT_SIZE*60/100)), rowheight=30,)
self.table_heading()
list_box_width = self.width * 58.7/100
self.tree = ttk.Treeview(self.base_frame, height=8, show='tree', style="Custom.Treeview")
# self.tree.tag_configure('odd', background='#DFEBF6', foreground="#000000", )
# self.tree.tag_configure('even', background='#FFFFFF', foreground="#000000", )
self.tree.place(x=self.width *5/100, y=self.height*52/100, width=list_box_width)
self.tree["columns"] = "0", "1", "2", "3", "4", "5"
self.tree.column("#0", width=0)
self.tree.column("#1", width=100)
self.tree.column("#2", width=130)
self.tree.column("#3", width=150)
self.tree.column("#4", width=190)
vsby = ttk.Scrollbar(self.base_frame, orient="vertical", command=self.tree.yview)
vsby.place(x=self.width*62.3/100, y=self.height*53/100, height=self.height*39.1/100)
self.tree.configure(yscrollcommand=vsby.set)
self.update_table_data()
self.tree.column("#0", anchor=tk.CENTER)
self.tree.column("#1", anchor=tk.CENTER)
self.tree.column("#2", anchor=tk.CENTER)
self.tree.column("#3", anchor=tk.CENTER)
self.tree.column("#4", anchor=tk.CENTER)
self.on_tree_click()
root.attributes('-alpha', 0.0)
root.attributes('-alpha', 1.0)
We have created our own heading for table, lets configure it.
def table_heading(self):
heading_y = self.height*47/100
bg_color = "#5ad16a"
text_color = "#ffffff"
canvas_width = self.width * 90 / 100
text_size = int(AppConstant.FONT_SIZE * 70 / 100)
canvas = Canvas(self.base_frame, width=canvas_width*65/100, height=30)
canvas.create_rectangle(0, 0, canvas_width, 30, fill=bg_color)
canvas.place(x=self.width*5/100, y=heading_y -3)
heading_width=canvas_width/8
flayt_id_label = Label(self.base_frame, text="Flat ID", font=('Calibri', text_size, 'bold'), background=bg_color,
foreground=text_color)
flat_id_label.place(x=self.width*5.5/100, y=heading_y, width=heading_width)
flat_id_label.configure(anchor="center")
flat_no_label = Label(self.base_frame, text="Flat No.", font=('Calibri', text_size, 'bold'), background=bg_color,
foreground=text_color)
flat_no_label.place(x=heading_width+self.width*3.7/100, y=heading_y, width=heading_width)
flat_no_label.configure(anchor="center")
flat_owner_label = Label(self.base_frame, text="Owner's Name", font=('Calibri',text_size, 'bold'), background=bg_color,
foreground=text_color)
flat_owner_label.place(x=2*heading_width+self.width*4/100, y=heading_y, width=heading_width)
flat_owner_label.configure(anchor="center")
#
contact_label = Label(self.base_frame, text="Contact", width=6,font=('Calibri', text_size, 'bold'), background=bg_color,
foreground=text_color)
contact_label.place(x=3*heading_width+self.width*6.8/100, y=heading_y, width=heading_width)
contact_label.configure(anchor="center")
status_label = Label(self.base_frame, text="Status", font=('Calibri', text_size, 'bold'), background=bg_color,
foreground=text_color)
status_label.place(x=4*heading_width+self.width*5.8/100, y=heading_y, width=heading_width)
status_label.configure(anchor="center")
UI part is completed, lets move to funtionality. First we need to add click on "ADD FLAT" button.
def add_flat_click(self):
var = ""
flat_no = ""
owner_name = ""
contact_no = ""
is_flat_no_provided = False
is_name_provided = False
is_contact_provided = False
flat_status = self.flat_status_combobox.get()
if self.flat_no.entry.get() == "" or self.flat_no.entry.get() == " ":
var += "Flat No. Should not be empty, "
else:
flat_no = self.flat_no.entry.get()
is_flat_no_provided = True
if self.flat_owner_name.entry.get() == "" or self.flat_owner_name.entry.get() == " ":
var += "Flat owner name Should not be empty, "
else:
owner_name = self.flat_owner_name.entry.get()
is_name_provided = True
if self.flat_owner_contact.entry.get() == "" or self.flat_owner_contact.entry.get() == " ":
var += "Flat Contact Should not be empty, "
else:
contact_no = self.flat_owner_contact.entry.get()
is_contact_provided = True
if is_flat_no_provided and is_name_provided and is_contact_provided:
conn = Util.connect_db()
cursor = conn.cursor()
cursor.execute('INSERT INTO flat_detail(flat_no, flat_owner_name, contact_no, flat_status) VALUES(?,?,?,?)',
(flat_no, owner_name, contact_no, flat_status))
conn.commit()
messagebox.showinfo("Success", "Flat has been added successfully")
self.flat_owner_contact.entry.delete(0, 'end')
self.flat_owner_name.entry.delete(0, 'end')
self.flat_no.entry.delete(0, 'end')
# self.entery_time.entry.delete(0, 'end')
self.flat_no.entry.focus()
self.tree.delete(*self.tree.get_children())
self.update_table_data()
else:
messagebox.showerror("Error", var)
def update_table_data(self):
conn = Util.connect_db()
cursor = conn.cursor()
cursor.execute('SELECT id, flat_no, flat_owner_name, contact_no, flat_status FROM flat_detail ORDER BY id DESC')
self.sql_output = cursor.fetchall()
count = 0
for data in self.sql_output:
if count % 2 == 0:
self.tree.insert('', 'end', values=data, tags=('even',))
else:
self.tree.insert('', 'end', values=data, tags=('odd',))
count = count + 1
To edit and delete Flat Details on click on table row, we need to show Edit And Delete Button.
def on_tree_click(self, *args):
self.show_edit_button()
self.delete_flat_button()
def show_edit_button(self, *args):
self.edit_button = RoundedButton(self.base_frame, self.width * 12 / 100, self.width * 3 / 100, self.color, "images/button3.png",
"EDIT", font=("Lucida Grande", int(AppConstant.FONT_SIZE*75/100)),
command=self.edit_flat)
self.edit_button.place(x=self.width * 78 / 100, y=self.height * 50 / 100)
def delete_flat_button(self, *args):
self.delete_button = RoundedButton(self.base_frame, self.width * 12 / 100, self.width * 3 / 100, self.color, "images/button3.png",
"DELETE FLAT", font=("Lucida Grande", int(AppConstant.FONT_SIZE*75/100)),
command=self.delete_flat)
self.delete_button.place(x=self.width * 78/100, y=self.height * 70/100)
After Buttons UI completed move on their button click functionality
def edit_flat(self):
cur_item = self.tree.focus()
if self.tree.item(cur_item)["values"]:
self.flat_no.entry.delete(0, END)
self.flat_owner_name.entry.delete(0, END)
self.flat_owner_contact.entry.delete(0, END)
# self.entery_time.entry.delete(0, END)
self.flat_no.entry.insert(0, self.tree.item(cur_item)["values"][1])
self.flat_owner_name.entry.insert(0, self.tree.item(cur_item)["values"][2])
# self.entery_time.entry.insert(0, self.tree.item(cur_item)["values"][3])
self.flat_owner_contact.entry.insert(0, self.tree.item(cur_item)["values"][3])
if "Occupied" == self.tree.item(cur_item)["values"][4]:
self.flat_status_combobox.current(0)
else:
self.flat_status_combobox.current(1)
self.add_button.place_forget()
self.delete_button.place_forget()
self.edit_button.place_forget()
# book_id = self.tree.item(cur_item)["values"][0]
self.update_button = RoundedButton(self.base_frame, self.width * 12 / 100, self.width * 3 / 100, self.color, "images/button3.png", "UPDATE",
font=("Lucida Grande", int(AppConstant.FONT_SIZE*75/100)),
command=lambda: self.update_flat_click())
self.update_button.place(x=self.width * 78 / 100, y=self.height * 60 / 100)
self.cancel_button = RoundedButton(self.base_frame, self.width * 12 / 100, self.width * 3 / 100, self.color, "images/button3.png", "CANCEL",
font=("Lucida Grande", int(AppConstant.FONT_SIZE*75/100)),
command=self.cancel_button_click)
self.cancel_button.place(x=self.width * 78 / 100, y=self.height * 80 / 100)
else:
messagebox.showinfo("Error", "Please select any flat data from the table")
# Delete button functionality
def delete_flat(self):
cur_item = self.tree.focus()
if self.tree.item(cur_item)["values"]:
flat_id = self.tree.item(cur_item)["values"][0]
flat_no = self.tree.item(cur_item)["values"][1]
owner_name = self.tree.item(cur_item)["values"][2]
response = messagebox.askokcancel("Are you sure?", " Do you want to delete "+str(owner_name)+"'s " + str(flat_no) + " ?")
if response:
conn = Util.connect_db()
cursor = conn.cursor()
cursor.execute("DELETE FROM flat_detail WHERE id = ?", (flat_id, ))
conn.commit()
self.tree.delete(*self.tree.get_children())
self.update_table_data()
else:
messagebox.askokcancel("Error", "Please select any flat detail from the table.")
Implement Update And Cancel Button functionality
def update_flat_click(self):
var = ""
flat_no = ""
owner_name = ""
contact_no = ""
is_flat_no_provided = False
is_name_provided = False
is_contact_provided = False
flat_status = self.flat_status_combobox.get()
if self.flat_no.entry.get() == "" or self.flat_no.entry.get() == " ":
var += "Flat No. Should not be empty, "
else:
flat_no = self.flat_no.entry.get()
is_flat_no_provided = True
if self.flat_owner_name.entry.get() == "" or self.flat_owner_name.entry.get() == " ":
var += "Flat owner name Should not be empty, "
else:
owner_name = self.flat_owner_name.entry.get()
is_name_provided = True
if self.flat_owner_contact.entry.get() == "" or self.flat_owner_contact.entry.get() == " ":
var += "Flat Contact Should not be empty, "
else:
contact_no = self.flat_owner_contact.entry.get()
is_contact_provided = True
if is_flat_no_provided and is_name_provided and is_contact_provided:
conn = Util.connect_db()
cursor = conn.cursor()
# cursor.execute('INSERT INTO flat_detail(flat_no, flat_owner_name, contact_no, flat_status) VALUES(?,?,?,?)',
cursor.execute("UPDATE flat_detail SET flat_no = ?, flat_owner_name = ?, contact_no = ?, flat_status = ? WHERE flat_no = ?",
(flat_no, owner_name, contact_no, flat_status, flat_no))
conn.commit()
self.flat_owner_contact.entry.delete(0, 'end')
self.flat_owner_name.entry.delete(0, 'end')
self.flat_no.entry.delete(0, 'end')
messagebox.showinfo("Success", "Flat detail has been updated successfully")
self.tree.delete(*self.tree.get_children())
self.update_table_data()
self.show_add_flat_button()
self.cancel_button.place_forget()
self.update_button.place_forget()
def cancel_button_click(self):
self.flat_owner_contact.entry.delete(0, 'end')
self.flat_owner_name.entry.delete(0, 'end')
self.flat_no.entry.delete(0, 'end')
self.on_tree_click()
self.show_add_flat_button()
self.cancel_button.place_forget()
self.update_button.place_forget()
At last we will manage closing of window
def on_closing():
root.destroy()
if len(args) > 1:
from dashboard.DashboardWindow import DashboardWindow
DashboardWindow.add_desk_frame(args[1])
args[0].deiconify()
root.protocol("WM_DELETE_WINDOW", on_closing)
Programmer Mirta is for learning and training. Projects might be simple to improve learning. Projects are constantly reviewed to avoid errors, but we cannot assure full correctness of all content. While using Programmer Mitra, you agree to have read and accepted our terms of use, cookie and privacy policy.
Copyright 2021 by Programmer Mitra. All Rights Reserved.