Trying to Refresh a ScrolledText and combobox from tkinter python - json

I have a code that will read in a json file from a method. What I want to do is. Have this method called when the program is opened. And called again when the user presses a button which send a json request to a server and then changes the database there. Now when the user presses the button I want to refresh the values that are inside the combobox and scrolledtext widgets. I just can seem to do that correctly. It either does not do anything or adds extra things to the bottom.
What I would like is to clear the scrolledtext and the combobox value and rewrite them form the new Json file.
What I have so far.
from tkinter import *
from tkinter.ttk import *
from tkinter import scrolledtext
from tkinter import messagebox
# AI devices imports
from SmartAdFSM import ADControlSystem as aic
from SmartAdFSM.AdUtility import AdHelperMethods as adm
# Varialbes that are collected from differnt APIs
# TODO:Replace with real ads from Google/Yahoo/Facebook
# TODO: Create method to gather all avalialbe ads from service providers and create
# 1: list of all ads form API, '(Yahoo, Google, Facebook)
# 2: FSM for all ads
# List for ads
# They are broken up first by service provider then added into a master list
currentAds = [] # This holds every add from every service provider.
apiYahooAds = [] # This holds every yahoo add
jsonFile = "TestAds/YahooAd.json"
# Get the initial setup and read the new info from Yahoo API
adm.CreateYahooAdList(jsonFile, apiYahooAds, currentAds)
# Add ad values into the list for dropdown and fsm
# Initial set up of the UI
ddMenuValues = [] # names of each ad
adTitles = [] # The FSM for each ad
def activateClicked():
target = dropdownWidget.get()
msg = "{} Ad is now active".format(target)
for targetAd in currentAds:
if target == targetAd.title:
aic.controlFSM(targetAd, "activate")
messagebox.showinfo('Action', msg)
# collect the updated API from yahoo API to update the UI
adm.CreateYahooAdList(jsonFile, apiYahooAds, currentAds)
adm.UpdateUI(adTitleViewWidget,dropdownWidget,adTitles,ddMenuValues,currentAds)
break
def deactivateClicked():
target = dropdownWidget.get()
msg = "{} Ad in now inactive".format(target)
for targetAd in currentAds:
if target == targetAd.title:
aic.controlFSM(targetAd, "pause")
messagebox.showinfo('Action', msg)
# collect the updated API from yahoo API to update the UI
adm.CreateYahooAdList(jsonFile, apiYahooAds, currentAds)
break
def endClicked():
target = dropdownWidget.get()
msg = "{} Ad in now ended".format(target)
for targetAd in currentAds:
if target == targetAd.title:
aic.controlFSM(targetAd, "delete")
messagebox.showinfo('Action', msg)
# collect the updated API from yahoo API to update the UI
adm.CreateYahooAdList(jsonFile, apiYahooAds, currentAds)
break
window = Tk()
window.title("SmartAd Manager IgniterLabs")
window.geometry("900x500")
# Widgets
mainLabel = Label(window, text="Welcome to SmartAd management Tool",
font=("Arial Bold", 12))
activeAdsLabel = Label(window, text="Current Ads Available")
# Activate button
activateButton = Button(window, text="Activate Ad",
command=activateClicked)
# Deactivate Button
deactivateButton = Button(window, text="Deactivate Ad",
command=deactivateClicked)
# End Button
endButton = Button(window, text="End Ad",
command=endClicked)
# Quit button
quitButton = Button(window, text="Quit",
command=quit)
# Combo box to select the Ad
dropdownWidget = Combobox(window)
# Set the dropdownmenu contents
# Text filed for user
adTitleViewWidget = scrolledtext.ScrolledText(window)
# set the textfeild' contents
adm.UpdateUI(adTitleViewWidget, dropdownWidget, adTitles, ddMenuValues,currentAds)
# Set main label position on grid
mainLabel.grid(column=0, row=0)
dropdownWidget.grid(column=0, row=1)
activateButton.grid(column=1, row=1)
deactivateButton.grid(column=2, row=1)
endButton.grid(column=3, row=1)
activeAdsLabel.grid(column=0, row=2)
adTitleViewWidget.grid(column=0, row=3, columnspan=3)
quitButton.grid(column=0, row=4)
window.mainloop()
And here is the helper methods that i am using:
def CreateYahooAdList(jsonSource, yahooAdList, adList):
# Test Ad simulate call from API
# TODO: Create call to API for Yahoo Ad to get every ad that is available
readFromAPI = jsonSource
# read in the file
parsedFile = yjp.readinJson(readFromAPI)
# create objects for each ad and add them into the Yahoo Ad list
yjp.createAdObjects(yahooAdList, parsedFile)
# Then add all the new Yahoo parsed ads (Now Ad Objects) into the myAds list
for ad in yahooAdList:
adList.append((ad))
'''
This method will get values from a Json file
In the future it will pull it off the Yahoo API
#:param textFeildValues = adTitles[] from SimpleUIControler
#:param comboValues = ddMenuValues[] from SimpleUIControler
#:param ads = currentAds from SimpleUIControler
'''
def UpdateUIValues(textFeildValues, comboValues, ads):
for ad in ads:
title = ad.title
status = ad.status
comboValues.append(title)
textFeildValues.append(title + "-" + status + "\n")
def UpdateUI(adTitleViewWidget, dropdownWidget, adTitle, dropdownValues, currentAds):
# First update the values to be used
UpdateUIValues(adTitle, dropdownValues, currentAds)
# Clear exsiting UI
adTitleViewWidget.delete(1.0, END)
for ad in adTitle:
adTitleViewWidget.insert(END, ad)
dropdownWidget['values'] = dropdownValues
# The init value
dropdownWidget.current(0)

Ok so I found an answer to this that works, may not be the best thing, but hey.
So on a button click you need to clear the contents of the box then add the new content into the box.
def getItemsPerLine(dropdownValues, listboxWidget):
# Clear the list
listboxWidget.delete(0,'end')
x = 1
for item in dropdownValues:
listboxWidget.insert(x, item)
x += 1

Related

Interactive wizard in wxpython (Phoenix)

I am trying to develop an interactive wizard in wxPython 4.0(Phoenix) with Python 3.7. Basically the wizard has 4 pages(Stages). Each time I click Next, it should run a different Python script by taking the arguments on the page. I need to display the progress of the running of script on the wizard page.
I have already developed a basic interface for wizard with 4 pages. Now I need help on
1. How to pass arguments from the Page to the Python script?
2. How to call a different Python script everytime I click Next Button on the 4 Pages of wizard? (I think I need to write code around the event ON_PAGE_CHANGING, But I am not clear how to call a different Python script everytime I click NExt Button)
3. How to display progress bar of each script on the wizard?
I am attaching the code for my Basic wizard interface. I am new to WxPython, Any help on the above 3 points is greatly appreciated.
#!/usr/bin/env python
import wx
import wx.adv
from wx.adv import Wizard as wizmod
#import images
from wx.adv import WizardPage, WizardPageSimple
import os.path
padding = 5
class wizard_page(wx.adv.WizardPage):
''' An extended panel obj with a few methods to keep track of its siblings.
This should be modified and added to the wizard. Season to taste.'''
def __init__(self, parent, title):
WizardPage.__init__(self, parent)
self.next = self.prev = None
self.sizer = wx.BoxSizer(wx.VERTICAL)
title = wx.StaticText(self, -1, title)
title.SetFont(wx.Font(18, wx.SWISS, wx.NORMAL, wx.BOLD))
self.sizer.Add(title, 0, wx.ALIGN_LEFT|wx.ALL, padding)
self.sizer.Add(wx.StaticLine(self, -1), 0, wx.EXPAND|wx.ALL, padding)
self.SetSizer(self.sizer)
def add_stuff(self, stuff):
'''Add aditional widgets to the bottom of the page'''
self.sizer.Add(stuff, 0, wx.EXPAND|wx.ALL, padding)
def SetNext(self, next):
'''Set the next page'''
self.next = next
def SetPrev(self, prev):
'''Set the previous page'''
self.prev = prev
def GetNext(self):
'''Return the next page'''
return self.next
def GetPrev(self):
'''Return the previous page'''
return self.prev
class wizard(wx.adv.Wizard):
'''Add pages to this wizard object to make it useful.'''
def __init__(self, title, img_filename=""):
# img could be replaced by a py string of bytes
if img_filename and os.path.exists(img_filename):
img = wx.Bitmap(img_filename)
else: img = wx.NullBitmap
wx.adv.Wizard.__init__(self, None, -1, title, img)
self.pages = []
# Lets catch the events
self.Bind(wx.adv.EVT_WIZARD_PAGE_CHANGED, self.on_page_changed)
self.Bind(wx.adv.EVT_WIZARD_PAGE_CHANGING, self.on_page_changing)
self.Bind(wx.adv.EVT_WIZARD_CANCEL, self.on_cancel)
self.Bind(wx.adv.EVT_WIZARD_FINISHED, self.on_finished)
def add_page(self, page):
'''Add a wizard page to the list.'''
if self.pages:
previous_page = self.pages[-1]
page.SetPrev(previous_page)
previous_page.SetNext(page)
self.pages.append(page)
def run(self):
self.RunWizard(self.pages[0])
def on_page_changed(self, evt):
'''Executed after the page has changed.'''
if evt.GetDirection(): dir = "forward"
else: dir = "backward"
page = evt.GetPage()
print ("page_changed: %s, %s\n" % (dir, page.__class__))
def on_page_changing(self, evt):
'''Executed before the page changes, so we might veto it.'''
if evt.GetDirection(): dir = "forward"
else: dir = "backward"
page = evt.GetPage()
print ("page_changing: %s, %s\n" % (dir, page.__class__))
def on_cancel(self, evt):
'''Cancel button has been pressed. Clean up and exit without continuing.'''
page = evt.GetPage()
print ("on_cancel: %s\n" % page.__class__)
# Prevent cancelling of the wizard.
if page is self.pages[0]:
wx.MessageBox("Cancelling on the first page has been prevented.", "Sorry")
evt.Veto()
def on_finished(self, evt):
'''Finish button has been pressed. Clean up and exit.'''
print ("OnWizFinished\n")
if __name__ == '__main__':
app = wx.App() # Start the application
# Create wizard and add any kind pages you'd like
mywiz = wizard('Simple Wizard', img_filename='wiz.png')
page1 = wizard_page(mywiz, 'Stage 1') # Create a first page
#page1.add_stuff(wx.StaticText(page1, -1, 'Hola'))
page1.add_stuff(wx.CheckBox(page1,-1,'Argument1',(35,40),(150,20)))
page1.add_stuff(wx.CheckBox(page1,-1,'Argument2',(35,60),(150,20)))
page1.add_stuff(wx.CheckBox(page1,-1,'Argument3',(35,80),(150,20)))
mywiz.add_page(page1)
# Add some more pages
mywiz.add_page( wizard_page(mywiz, 'Stage 2') )
mywiz.add_page( wizard_page(mywiz, 'Stage 3') )
mywiz.add_page( wizard_page(mywiz, 'Stage 4') )
mywiz.run() # Show the main window
# Cleanup
mywiz.Destroy()
#del app
app.MainLoop()
del app

Working with coroutines in Python Tornado Web Server

I am working on an autonomous car implementation for a web browser game with Python 2x. I use Tornado Web Server to run game on localhost and I post and receive data from game with JSON data format in the function called "FrameHandler" and also I determine what the act of car should be in "to_dict_faster()" function.
Here, my problem is that I can write data to text file which is hold in speed_data variable in specific time interval with help of a coroutine. However, I can't dump JSON data to function in this specific time interval because "FrameHandler" acts like While True and it always requests data to dump. What I am trying to do is sending desired acts as writing text file in specific time interval while not changing flow frame handler because it affects FPS of the game.
I am trying to figure out How can I do that for a long time any help would be great here:
#gen.coroutine
def sampler():
io_loop = tornado.ioloop.IOLoop.current()
start = time.time()
while True:
with open("Sampled_Speed.txt", "a") as text_file:
text_file.write("%d,%.2f\n" % (speed_data, ((time.time() - start))))
yield gen.Task(io_loop.add_timeout, io_loop.time() + period)
class MainHandler(tornado.web.RequestHandler):
def get(self):
self.redirect("/static/v2.curves.html")
class FrameHandler(tornado.web.RequestHandler):
def post(self):
global speed_data
data = json.loads(self.get_arguments("telemetry")[0])
ar = np.fromstring(base64.decodestring(self.request.body), dtype=np.uint8)
image = ar.reshape(hp.INPUT_SIZE, hp.INPUT_SIZE, hp.NUM_CHANNELS)
left, right, faster, slower = data["action"]
terminal, action, all_data, was_start = (
data["terminal"],
Action(left=left, right=right, faster=faster, slower=slower),
data["all_data"],
data["was_start"]
)
for i in range(len(all_data)):
data_dict=all_data[i]
speed_data = data_dict[u'speed']
position_data=data_dict[u'position']
result_action = agent.steps(image, 0.1, terminal, was_start, action, all_data)
if speed_data < 4000:
self.write(json.dumps(result_action.to_dict_faster()))
else:
self.write(json.dumps(result_action.to_dict_constant()))
def make_app():
return tornado.web.Application([
(r"/", MainHandler),
(r"/frame", FrameHandler),
(r"/static/(.*)", tornado.web.StaticFileHandler, {"path": static_path})
], debug=True)
if __name__ == "__main__":
app = make_app()
if "SERVER_PORT" in os.environ:
port = int(os.environ["SERVER_PORT"])
else:
port = 8880
print "LISTENING ON PORT: %d" % port
app.listen(port)
tornado.ioloop.IOLoop.current().run_sync(sampler)
tornado.ioloop.IOLoop.current().start()
You can move file writing to a different thread (using tornado's run_on_executor for example), so python interpreter will automatically switch from Sampler to main thread with FrameHandler on write. But you have to use thread-safe speed_data variable, I've used stdlib Queue.Queue as an example:
class Handler(tornado.web.RequestHandler):
#gen.coroutine
def get(self):
global speed_data
speed_data.put("REALLY BIG TEST DATA\n")
self.finish("OK")
class Sampler():
executor = concurrent.futures.ThreadPoolExecutor(max_workers=1)
def __init__(self, queue):
self._q = queue
#run_on_executor
def write_sample(self):
with open("foobar.txt", "w") as f:
while True:
data = self._q.get()
f.write(data)
if __name__ == '__main__':
application = Application(
[("/status", Handler)]
)
server = HTTPServer(application)
server.listen(8888)
speed_data = Queue.Queue()
smp = Sampler(speed_data)
IOLoop.current().add_callback(smp.write_sample)
IOLoop.current().start()

Fail to store data in csv file through scraping

I try to scraping a webpage and extracting data ,then store all data in a csv file. Before adding ScrapeCallback class and calling it, everything works fine. However, it does not store any type of data except headers in the cvs file after adding the new class. Can anyone help me to figure out the problem?
import re
import urlparse
import urllib2
import time
from datetime import datetime
import robotparser
import Queue
import csv
import lxml.html
class ScrapeCallback:
# extract and store all data in a csv file
def __init__( self):
self.writer = csv.writer(open('countries.csv', 'w'))
self.fields = ('area', 'population', 'iso', 'country', 'capital', 'continent', 'tld', 'currency_code', 'currency_name', 'phone', 'postal_code_format', 'postal_code_regex', 'languages', 'neighbours')
self.writer.writerow( self.fields)
def __call__( self, url, html):
if re.search('/view/',url):
tree = lxml.html.fromstring(html)
row = []
for field in self.fields:
row.append(tree.cssselect('table > tr#places_{}__row > td.w2p_fw'.format(field))[0].text_content())
print row
self.writer.writerow(row)
def link_crawler(seed_url, link_regex=None, delay=5, max_depth=-1, max_urls=-1, headers=None, user_agent='wswp', proxy=None, num_retries=1, scrape_callback=None):
"""Crawl from the given seed URL following links matched by link_regex
"""
# the queue of URL's that still need to be crawled
crawl_queue = [seed_url]
# the URL's that have been seen and at what depth
seen = {seed_url: 0}
# track how many URL's have been downloaded
num_urls = 0
rp = get_robots(seed_url)
throttle = Throttle(delay)
headers = headers or {}
if user_agent:
headers['User-agent'] = user_agent
while crawl_queue:
url = crawl_queue.pop()
depth = seen[url]
# check url passes robots.txt restrictions
if rp.can_fetch(user_agent, url):
throttle.wait(url)
html = download(url, headers, proxy=proxy, num_retries=num_retries)
links = []
if scrape_callback:
links.extend(scrape_callback(url, html) or [])
if depth != max_depth:
# can still crawl further
if link_regex:
# filter for links matching our regular expression
links.extend(link for link in get_links(html) if re.match(link_regex, link))
for link in links:
link = normalize(seed_url, link)
# check whether already crawled this link
if link not in seen:
seen[link] = depth + 1
# check link is within same domain
if same_domain(seed_url, link):
# success! add this new link to queue
crawl_queue.append(link)
# check whether have reached downloaded maximum
num_urls += 1
if num_urls == max_urls:
break
else:
print 'Blocked by robots.txt:', url
class Throttle:
"""Throttle downloading by sleeping between requests to same domain
"""
def __init__(self, delay):
# amount of delay between downloads for each domain
self.delay = delay
# timestamp of when a domain was last accessed
self.domains = {}
def wait(self, url):
"""Delay if have accessed this domain recently
"""
domain = urlparse.urlsplit(url).netloc
last_accessed = self.domains.get(domain)
if self.delay > 0 and last_accessed is not None:
sleep_secs = self.delay - (datetime.now() - last_accessed).seconds
if sleep_secs > 0:
time.sleep(sleep_secs)
self.domains[domain] = datetime.now()
def download(url, headers, proxy, num_retries, data=None):
print 'Downloading:', url
request = urllib2.Request(url, data, headers)
opener = urllib2.build_opener()
if proxy:
proxy_params = {urlparse.urlparse(url).scheme: proxy}
opener.add_handler(urllib2.ProxyHandler(proxy_params))
try:
response = opener.open(request)
html = response.read()
code = response.code
except urllib2.URLError as e:
print 'Download error:', e.reason
html = ''
if hasattr(e, 'code'):
code = e.code
if num_retries > 0 and 500 <= code < 600:
# retry 5XX HTTP errors
html = download(url, headers, proxy, num_retries-1, data)
else:
code = None
return html
def normalize(seed_url, link):
"""Normalize this URL by removing hash and adding domain
"""
link, _ = urlparse.urldefrag(link) # remove hash to avoid duplicates
return urlparse.urljoin(seed_url, link)
def same_domain(url1, url2):
"""Return True if both URL's belong to same domain
"""
return urlparse.urlparse(url1).netloc == urlparse.urlparse(url2).netloc
def get_robots(url):
"""Initialize robots parser for this domain
"""
rp = robotparser.RobotFileParser()
rp.set_url(urlparse.urljoin(url, '/robots.txt'))
rp.read()
return rp
def get_links(html):
"""Return a list of links from html
"""
# a regular expression to extract all links from the webpage
webpage_regex = re.compile('<a[^>]+href=["\'](.*?)["\']', re.IGNORECASE)
# list of all links from the webpage
return webpage_regex.findall(html)
if __name__ == '__main__':
# link_crawler('http://example.webscraping.com', '/(index|view)', delay=0, num_retries=1, user_agent='BadCrawler')
# link_crawler('http://example.webscraping.com', '/(index|view)', delay=0, num_retries=1, max_depth=1, user_agent='GoodCrawler')
link_crawler('http://example.webscraping.com', '/(index|view)', max_depth =2, scrape_callback = ScrapeCallback())

How does one get widget values with a button in ipython

I have a function createWidgets whose purpose is to take a list of strings and create a list of containers for each string -> 1 container = a textbox and checkbox. Each container is then put into a large container.
What I am trying to do is append a button to the container that on_click takes all the "True"s and puts all the modified strings and puts them in a dataframe
widgelist = e.options
txtBox_type = 'text_widget' # Define if Area box o regular txtbox
bigContainer = createWidgets(widgelist, txtBox_type)
Function
def createWidgets(widgelist, txtBox_type):
#containerList = []
i = 0
for k in widgelist:
## Build Container widgets
chBox_Widget = widgets.CheckboxWidget(description = str(i),value = False,)
if txtBox_type == 'textA_widget': # Check wether txtBox should be an area txt box or not.
txt_Widget = widgets.TextareaWidget( description = str(i), value = k)
else:
txt_Widget = widgets.TextWidget( description = str(i), value = k)
container = widgets.ContainerWidget()
container.children = [chBox_Widget, txt_Widget]
containerList.append(container)
i+= 1
button = widgets.ButtonWidget(description = 'Add')
bigContainer = widgets.ContainerWidget()
bigContainer.children = containerList
return bigContainer
I have gone to many websites and spent many days on this help is very much appreciated
As near as I can interpret the question, the code below should provide an answer:
import IPython.html.widgets as widgets
from IPython.display import display, clear_output
import pandas as pd
df = pd.DataFrame(columns=['Thing'])
def createWidgets(widgelist):
## Each CheckboxWidget and TextWidget are enclosed in a subwidget. We use a
## list comprehension to construct a list of these subwidgets.
containerList = [
widgets.ContainerWidget(children=(widgets.CheckboxWidget(description=k)
widgets.TextWidget(value=k)))
for k in widgelist]
bigContainer = widgets.ContainerWidget(children=containerList)
## To arrange the CheckboxWidget in a row with the TextWidget, we have to
## first display them, then remove_class('vbox') and add_class('hbox'). This
## bit of awkwardness in the IPython version 2.x notebook will hopefully
## be fixed in version 3.x. Displaying bigContainer also displays it's children.
display(bigContainer)
for c in containerList:
c.remove_class('vbox')
c.add_class('hbox')
return bigContainer
widgelist = ['ThingA', 'ThingB', 'ThingC', 'ThingD']
bigContainer = createWidgets(widgelist, txtBox_type)
## Callback for button.on_click.
def add_to_dataframe(a):
# The children of bigContainer are also containers,
# each with first child a CheckboxWidget and second
# child a TextWidget. We iterate through them and
# if checked, add the text to the dataframe df as
# an additional row.
for c in bigContainer.children:
if c.children[0].value:
df.loc[len(df)+1] = (c.children[1].value,)
display(df)
clear_output()
display(df)
button = widgets.ButtonWidget(description = 'Add')
button.on_click(add_to_dataframe)
display(button)
Here is a screen clip of the widget area and output after adding a few rows to the dataframe.
I would have designed the code to do this somewhat differently, but I tried to stay
close to your code organization.
This is updated version for Ipython3 on jupyternotebooks 4
Just rename:
widgets.ContainerWidget ->widgets.Box
widgets.CheckboxWidget -> widgets.Checkbox
widgets.TextWidget -> widgets.Text
Reference: [https://ipython.org/ipython-doc/3/whatsnew/version3_widget_migration.html]

Use Python for live search on MySQL db

I'm new to Python and am working on a simple desktop application to read records from a MySQL db. I need to make live search using tkinter entry through mysql db. When user strikes a keyboard key, an auto suggestion list should be generated with auto -omplete options to choose from...
At the moment the code below doesn't work. What is wrong?
#-*- coding: utf-8 -*-
import Tkinter
from Tkinter import *
import MySQLdb
top = Tkinter.Tk()
top.minsize(300,300)
top.geometry("500x500")
# here we make text input field
E1 = Entry(top, bd =2)
E1.pack(side = RIGHT)
Lb1 = Listbox( E1) # here the list generated from entry but covering it completely is bad ??
def clickme(x):
txtt=E1.get()
txt=txtt+"%"
#connection
db = MySQLdb.connect("127.0.0.1","root","123456","test2",use_unicode=True, charset="utf8" )
if db:print"connected"
cursor=db.cursor()
cursor.execute("SELECT name FROM `table` WHERE name LIKE '%s' " % (txt))
#------------
res=cursor.fetchall()
i=0
for query in res:
i+=1
lngth=len(query[0])
u=query[0].encode('utf-8')
Lb1.delete (0,lngth)
if len(txtt)>0:
Lb1.insert(i, u)
Lb1.pack()
else:
Lb1.delete (0,lngth)
Lb1.pack_forget()
top.bind("<Key>", clickme)
top.mainloop()
I don't work with Tkinker so I don't know how to put Listbox near Entry but I made some modification.
If you write text in Entry then Listbox is showing with data from db.
If you remove text from Entry then Listbox is hidding.
#!/usr/bin/python
#-*- coding: utf-8 -*-
import Tkinter
from Tkinter import *
import MySQLdb
#----------------------------------------------------------------------
class MainWindow():
def __init__(self, root):
frame = Frame(root, width=500, height=500)
#root.minsize(300,300)
frame.pack()
# here we make text input field
self.E1 = Entry(frame, bd=2)
self.E1.pack(side=TOP)
# here the list generated from entry but covering it completely is bad ??
self.Lb1 = Listbox(frame, bd=2)
#Lb1.pack(side=BOTTOM)
root.bind("<Key>", self.clickme)
# open database (only once) at start program
self.db = MySQLdb.connect("127.0.0.1", "root", "password", "test", use_unicode=True, charset="utf8")
#-------------------
def __del__(self):
# close database on exit
self.db.close()
#-------------------
def clickme(self, x):
txt = self.E1.get()
self.Lb1.delete(0, END) # delete all on list
if txt == '':
self.Lb1.pack_forget() # hide list
else:
self.Lb1.pack(side=BOTTOM) # show list
txt_for_query = txt + "%"
cursor = self.db.cursor()
cursor.execute("SELECT name FROM `table` WHERE name LIKE '%s'" % (txt_for_query))
res = cursor.fetchall()
for line in res:
self.Lb1.insert(END, line[0].encode('utf-8')) # append list
cursor.close()
#----------------------------------------------------------------------
root = Tk()
MainWindow(root)
root.mainloop()