patternpythonMinor
Tkinter file searching program
Viewed 0 times
programfiletkintersearching
Problem
This is my first relatively big program. First it shows an
There are two lists because I couldn't find the way to get path while only writing file names to a list. So one of the list is shown and only have file names, the other one is hidden and contains whole path for that file.
My code is working relatively slow while writing to a database or reading from it but my real problem is, this program should search 3TB of data which contain lots of folders, files etc.. So when I try to show hundreds (sometimes it is thousands) of items in listBox, GUI freezes. I cannot scroll up/down or open folders by double clicking on their names.
-
How can I handle that problem? Is there a way to do it with Tkinter or should I use something else?
-
Any tips on style?
-
Lastly, about writing to/reading from database performance, should I use threading?
```
#--coding: utf8--
import os
import sys
import time
import sqlite3
import tkinter
from tkinter import ttk
from tkinter import filedialog
from tkinter import messagebox
from win32com.shell import shell, shellcon
class Prompt(tkinter.Frame):
def search_button(self):
reading.reader() ##to get data from database tables
self.my_entry = self.ent.get()
if self.my_entry:
for line in reading.lines:
if self.my_entry.lower() in line.split("/")[-1].lower(): ##if entry from textbox in file/path name
self.results.append(line)
self.shown_list()
se
askdirectory() screen to get the path. It gets all subfolders of that path and appends them to a list. It checks every folders' items if they are wanted file types by checking extensions and puts them into a proper sqlite table. After all files written to a database file, a GUI appears to get what user wants to search. After clicking search_button it gets my_entry and checks if it's in database. If yes, appends it to a list and after all database is searched, it shows results in a listbox. There are two lists because I couldn't find the way to get path while only writing file names to a list. So one of the list is shown and only have file names, the other one is hidden and contains whole path for that file.
My code is working relatively slow while writing to a database or reading from it but my real problem is, this program should search 3TB of data which contain lots of folders, files etc.. So when I try to show hundreds (sometimes it is thousands) of items in listBox, GUI freezes. I cannot scroll up/down or open folders by double clicking on their names.
-
How can I handle that problem? Is there a way to do it with Tkinter or should I use something else?
-
Any tips on style?
-
Lastly, about writing to/reading from database performance, should I use threading?
```
#--coding: utf8--
import os
import sys
import time
import sqlite3
import tkinter
from tkinter import ttk
from tkinter import filedialog
from tkinter import messagebox
from win32com.shell import shell, shellcon
class Prompt(tkinter.Frame):
def search_button(self):
reading.reader() ##to get data from database tables
self.my_entry = self.ent.get()
if self.my_entry:
for line in reading.lines:
if self.my_entry.lower() in line.split("/")[-1].lower(): ##if entry from textbox in file/path name
self.results.append(line)
self.shown_list()
se
Solution
In looking at your code, there are a few things I would do:
Here is an example of how I have done GUI's using TKinter:
- Subclass TK..
class MainGUI(Tk):
- Attach all gui components to this class.... your frame for example.
- Add a queue and a polling method for GUI updates to the MainGUI class (this may help fix your freezing issue). You can use the TK.after method to ask the mainloop to do this periodically.
- Do the heavy lifting items such as db reads, filesystem, etc in a separate thread if they block too long, but make sure they don't update the GUI directly from that thread, you can pass a reference to the GUI to them and they should place a callback on the updateq for the main loop to execute as it runs a polling cycle.
- Check the code for pep8 compliance.
Here is an example of how I have done GUI's using TKinter:
class MainGUI(Tk):
""" The GUI """
def __init__(self):
super().__init__()
self.updateq = queue.Queue()
# Build main components
# Layout components
# Key bindings
self.poll()
self.mainloop()
def poll(self):
""" Polls the Queue for the arrival of various callbacks """
# You may want to process more or less callbacks each cycle...
# here it uses 100 as a maximum
for i in range(100):
if self.updateq.empty():
break
callback, args = self.updateq.get()
if args:
callback(args)
else:
callback()
# Recursive call
self.after(50, self.poll)Code Snippets
class MainGUI(Tk):
""" The GUI """
def __init__(self):
super().__init__()
self.updateq = queue.Queue()
# Build main components
# Layout components
# Key bindings
self.poll()
self.mainloop()
def poll(self):
""" Polls the Queue for the arrival of various callbacks """
# You may want to process more or less callbacks each cycle...
# here it uses 100 as a maximum
for i in range(100):
if self.updateq.empty():
break
callback, args = self.updateq.get()
if args:
callback(args)
else:
callback()
# Recursive call
self.after(50, self.poll)Context
StackExchange Code Review Q#39198, answer score: 5
Revisions (0)
No revisions yet.