0% found this document useful (0 votes)
6 views5 pages

message

The document describes a Python application called 'Database Searcher' that utilizes Tkinter for its graphical user interface. It allows users to search for keywords within files located in a specified directory, displaying results in a text area and providing a progress bar during the search. The application includes features such as a splash screen, hover effects for buttons and entries, and input validation with animations.

Uploaded by

binro01120
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
6 views5 pages

message

The document describes a Python application called 'Database Searcher' that utilizes Tkinter for its graphical user interface. It allows users to search for keywords within files located in a specified directory, displaying results in a text area and providing a progress bar during the search. The application includes features such as a splash screen, hover effects for buttons and entries, and input validation with animations.

Uploaded by

binro01120
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
You are on page 1/ 5

Database Searcher with Fixed Widget Stacking

import os
from tkinter import Tk, Label, Button, Entry, Text, Scrollbar, filedialog, Canvas,
Toplevel, Frame
from tkinter import messagebox, ttk
from tkinter.ttk import Progressbar
from websocket import WebSocketApp
import time
import threading
import websocket

class DatabaseSearcherNPY:
def __init__(self, root):
self.root = root
self.root.title("Database Searcher")
self.root.geometry("1000x700")
self.root.configure(bg="#ffffff")

# Configure la police
self.sf_pro = ("Helvetica Neue", "Arial")

# Splash Screen Animation


self.splash_screen()

# Header avec animation de slide


self.header = Label(self.root, text="Database Searcher", bg="#ffffff",
fg="#000000",
font=(self.sf_pro[0], 32, "bold"))
self.header.place(x=500, y=-50)
self.slide_in(self.header, 500, 20)

# Main Container
self.main_frame = Frame(self.root, bg="#f5f5f7")
self.main_frame.place(relx=0.5, rely=0.5, anchor="center", width=900,
height=500)

# Border effect
self.main_frame.configure(highlightbackground="#E0E0E0",
highlightcolor="#E0E0E0",
highlightthickness=1,
bd=0)

# Search Bar Frame


self.search_frame = Frame(self.main_frame, bg="#ffffff")
self.search_frame.place(x=50, y=30, width=800, height=60)
self.search_frame.configure(highlightbackground="#E8E8E8",
highlightcolor="#E8E8E8",
highlightthickness=1,
bd=0)

# Folder Selection
self.folder_entry = Entry(self.search_frame, width=50,
font=(self.sf_pro[0], 12),
bg="#f5f5f7", fg="#000000", relief="flat")
self.folder_entry.place(x=20, y=15, width=600, height=30)
self.add_hover_effect(self.folder_entry)
self.browse_button = Button(self.search_frame, text="Browse",
command=self.browse_folder,
bg="#0071e3", fg="white", font=(self.sf_pro[0],
12, "bold"),
relief="flat", cursor="hand2")
self.browse_button.place(x=640, y=12, width=140, height=36)
self.add_button_effects(self.browse_button)

# Search Section
self.keyword_frame = Frame(self.main_frame, bg="#ffffff")
self.keyword_frame.place(x=50, y=110, width=800, height=60)
self.keyword_frame.configure(highlightbackground="#E8E8E8",
highlightcolor="#E8E8E8",
highlightthickness=1,
bd=0)

self.keyword_entry = Entry(self.keyword_frame, font=(self.sf_pro[0], 12),


bg="#f5f5f7", fg="#000000", relief="flat")
self.keyword_entry.place(x=20, y=15, width=600, height=30)
self.add_hover_effect(self.keyword_entry)

self.search_button = Button(self.keyword_frame, text="Search",


command=self.start_search,
bg="#0071e3", fg="white", font=(self.sf_pro[0],
12, "bold"),
relief="flat", cursor="hand2")
self.search_button.place(x=640, y=12, width=140, height=36)
self.add_button_effects(self.search_button)

# Results Area
self.results_frame = Frame(self.main_frame, bg="#ffffff")
self.results_frame.place(x=50, y=190, width=800, height=250)
self.results_frame.configure(highlightbackground="#E8E8E8",
highlightcolor="#E8E8E8",
highlightthickness=1,
bd=0)

self.results_text = Text(self.results_frame, wrap="word",


font=(self.sf_pro[0], 12),
bg="#ffffff", fg="#000000", relief="flat", padx=10,
pady=10)
self.results_text.place(x=0, y=0, width=780, height=250)

# Scrollbar
self.scrollbar = ttk.Scrollbar(self.results_frame,
command=self.results_text.yview)
self.scrollbar.place(x=780, y=0, height=250)
self.results_text.config(yscrollcommand=self.scrollbar.set)

# Progress Bar Frame


self.progress_frame = Frame(self.main_frame, bg="#ffffff")
self.progress_frame.place(x=50, y=460, width=800, height=20)

self.progress = ttk.Progressbar(self.progress_frame, mode="determinate",


length=800)
self.progress.place(x=0, y=0, width=800)

def slide_in(self, widget, target_x, target_y, duration=500):


"""Anime un widget avec un effet de slide"""
start_x = widget.winfo_x()
start_y = widget.winfo_y()
steps = 20
dx = (target_x - start_x) / steps
dy = (target_y - start_y) / steps

def animate(step):
if step < steps:
x = start_x + (dx * step)
y = start_y + (dy * step)
widget.place(x=x, y=y)
self.root.after(duration // steps, lambda: animate(step + 1))

animate(0)

def add_hover_effect(self, widget):


"""Ajoute un effet hover aux entrées"""
def on_enter(e):
widget.configure(bg="#e5e5e5")
def on_leave(e):
widget.configure(bg="#f5f5f7")
widget.bind("<Enter>", on_enter)
widget.bind("<Leave>", on_leave)

def add_button_effects(self, button):


"""Ajoute des effets de survol et de clic aux boutons"""
def on_enter(e):
button.configure(bg="#0077ED")
def on_leave(e):
button.configure(bg="#0071e3")
def on_click(e):
button.configure(bg="#005BBF")
self.root.after(100, lambda: button.configure(bg="#0071e3"))

button.bind("<Enter>", on_enter)
button.bind("<Leave>", on_leave)
button.bind("<Button-1>", on_click)

def splash_screen(self):
"""Écran de démarrage avec animation simple"""
splash = Toplevel(self.root)
splash.geometry("1000x700")
splash.configure(bg="#ffffff")
splash.overrideredirect(True)

# Centrer la fenêtre
screen_width = splash.winfo_screenwidth()
screen_height = splash.winfo_screenheight()
x = (screen_width - 1000) // 2
y = (screen_height - 700) // 2
splash.geometry(f"1000x700+{x}+{y}")

# Texte avec animation de slide


splash_label = Label(splash, text="Database Searcher",
bg="#ffffff", fg="#000000",
font=(self.sf_pro[0], 32, "bold"))
splash_label.place(relx=0.5, rely=-0.2, anchor="center")

# Animation de slide pour le texte


def slide_text():
for i in range(20):
y = -0.2 + (0.6 * (i / 19))
splash_label.place(relx=0.5, rely=y, anchor="center")
splash.update()
time.sleep(0.02)

self.root.withdraw()
slide_text()

# Progress bar
progress = ttk.Progressbar(splash, mode="indeterminate", length=400)
progress.place(relx=0.5, rely=0.7, anchor="center")
progress.start(15)

def close_splash():
progress.stop()
splash.destroy()
self.root.deiconify()

splash.after(2000, close_splash)

def browse_folder(self):
folder_path = filedialog.askdirectory()
if folder_path:
self.folder_entry.delete(0, "end")
self.folder_entry.insert(0, folder_path)

def start_search(self):
if not self.validate_inputs():
return

self.search_button.configure(state="disabled")
thread = threading.Thread(target=self.perform_search)
thread.daemon = True
thread.start()

def validate_inputs(self):
"""Valide les entrées avec effet de shake"""
folder_path = self.folder_entry.get()
keyword = self.keyword_entry.get()

if not folder_path or not keyword:


widget = self.folder_entry if not folder_path else self.keyword_entry
self.shake_widget(widget)
messagebox.showwarning("Input Error", "Please fill all fields")
return False
return True

def shake_widget(self, widget):


"""Anime un widget avec un effet de secousse"""
original_x = widget.winfo_x()
for i in range(10):
new_x = original_x + (-5 if i % 2 == 0 else 5)
widget.place(x=new_x)
self.root.update()
time.sleep(0.05)
widget.place(x=original_x)
def perform_search(self):
"""Effectue la recherche avec animations de progression"""
try:
folder_path = self.folder_entry.get()
keyword = self.keyword_entry.get()

total_files = sum(len(files) for _, _, files in os.walk(folder_path))


processed_files = 0

self.progress["value"] = 0
self.results_text.config(state="normal")
self.results_text.delete(1.0, "end")

for root_dir, _, files in os.walk(folder_path):


for file in files:
file_path = os.path.join(root_dir, file)
try:
with open(file_path, "r", encoding="utf-8",
errors="ignore") as f:
content = f.read()
if keyword.lower() in content.lower():
result = f"Found in: {file_path}\n"
self.results_text.insert("end", result)
except Exception as e:
continue

processed_files += 1
self.progress["value"] = (processed_files / total_files) * 100
self.root.update_idletasks()

self.results_text.config(state="disabled")

finally:
self.search_button.configure(state="normal")
self.progress["value"] = 100

if __name__ == "__main__":
root = Tk()
app = DatabaseSearcherNPY(root)
root.mainloop()

You might also like