#!/usr/bin/python
from bs4 import BeautifulSoup
from urllib2 import urlopen
import Tkinter, tkMessageBox
import threading
import time
class KitchenKomputerMain(Tkinter.Tk):
def __init__(self, parent):
Tkinter.Tk.__init__(self,parent)
self.w = Tkinter.Toplevel()
self.w.title('Weather')
self.parent = parent
self.initialize()
def initialize(self):
self.grid()
label = Tkinter.Label(self, text="Welcome to the Kitchen Komputer",fg = "yellow", bg="black")
label.grid(column=0,row=0, sticky="EW")
timerButton = Tkinter.Button(self, text=u"Timer", command=self.timer)
#button1 = Tkinter.Button(self, text=u"Radio", command = self.radio)
timerButton.grid(column=0, row=1)
#button1.grid(column=1,row=1)
self.bind("0", self.timer)
#self.bind("1", self.radio)
self.bind("<Escape>", self.kill)
self.resizable(False,False)
self.update()
self.geometry(self.geometry())
def kill(self, event):
self.destroy()
def timer(self,event='0'):
self.kill(self)
t = Timer(None)
t.title("Timer")
def weather(self):
day_of_week_dic = {
"Mon": "Monday",
"Tue": "Tuesday",
"Wed": "Wednesday",
"Thu": "Thursday",
"Fri": "Friday",
"Sat": "Saturday",
"Sun": "Sunday "
}
urlRead = urlopen('http://xml.weather.yahoo.com/forecastrss/63034_f.xml')
soup = BeautifulSoup(urlRead, "lxml")
print soup.title.string
for weather in soup.html.body.find_all('yweather:forecast'):
print weather.get('date')
print 'day:'+day_of_week_dic[(weather.get('day'))]
print 'high:'+(weather.get('high'))
print 'low:'+(weather.get('low'))
print 'conditions:'+(weather.get('text'))
time.sleep(60*15)
weather(self)
class Timer(Tkinter.Tk):
def __init__(self,parent):
Tkinter.Tk.__init__(self,parent)
self.parent = parent
self.initialize()
def initialize(self):
#saying we want to use a grid layout
self.grid()
self.lblText = Tkinter.StringVar()
label = Tkinter.Label(self, textvariable=self.lblText,fg = "yellow", bg="black")
label.grid(column=0,row=0,columnspan=5, sticky="EW")
self.lblText.set("Timer")
button1 = Tkinter.Button(self,text="1",command=self.buttonclicked,width=4)
button2 = Tkinter.Button(self,text="2",command=self.buttonclicked,width=4)
button3 = Tkinter.Button(self,text="3",command=self.buttonclicked,width=4)
button4 = Tkinter.Button(self,text="4",command=self.buttonclicked,width=4)
button5 = Tkinter.Button(self,text="5",command=self.buttonclicked,width=4)
button6 = Tkinter.Button(self,text="6",command=self.buttonclicked,width=4)
button7 = Tkinter.Button(self,text="7",command=self.buttonclicked, width=4)
button8 = Tkinter.Button(self,text="8",command=self.buttonclicked, width=4)
button9 = Tkinter.Button(self,text="9",command=self.buttonclicked, width=4)
button0 = Tkinter.Button(self,text="0",command=self.buttonclicked, width=4)
MinutesButton = Tkinter.Button(self,text="Minutes",underline=0,command=self.buttonclicked,width=4)
HoursButton = Tkinter.Button(self,text="Hours",underline=0,command=self.buttonclicked,width=4)
ClrButton = Tkinter.Button(self,text="Clear",underline=0,command=self.buttonclicked,width=4)
StartButton= Tkinter.Button(self,text="Start",underline=0,command=self.buttonclicked,width=4)
PauseButton = Tkinter.Button(self,text="Pause",underline=0,command=self.buttonclicked,width=4)
button1.grid(column=0, row=1)
button2.grid(column=1, row=1)
button3.grid(column=2, row=1)
button4.grid(column=0, row=2)
button5.grid(column=1, row=2)
button6.grid(column=2, row=2)
button7.grid(column=0, row=3)
button8.grid(column=1, row=3)
button9.grid(column=2, row=3)
button0.grid(column=0, row=4)
MinutesButton.grid(column=1,row=4)
HoursButton.grid(column=2, row=4)
ClrButton.grid(column=0,row=5)
StartButton.grid(column=1,row=5)
PauseButton.grid(column=2,row=5)
self.bind("0", self.buttonPressed)
self.bind("1", self.buttonPressed)
self.bind("2", self.buttonPressed)
self.bind("3", self.buttonPressed)
self.bind("4", self.buttonPressed)
self.bind("5", self.buttonPressed)
self.bind("6", self.buttonPressed)
self.bind("7", self.buttonPressed)
self.bind("8", self.buttonPressed)
self.bind("9", self.buttonPressed)
self.bind("p", self.buttonPressed)
self.bind("m", self.buttonPressed)
self.bind("h", self.buttonPressed)
self.bind("s", self.buttonPressed)
#self.bind("<Return>",self.buttonPressed)
self.bind("c", self.buttonPressed)
self.bind("<Escape>", self.kill)
self.resizable(False,False)
self.update()
self.geometry(self.geometry())
def kill(self, event):
self.destroy()
def buttonclicked(self):
pass
def buttonPressed(self,event):
#check if labels text is the default text first
txt = self.lblText.get()
char = event.char
if char == 'c':
self.lblText.set('')
elif txt == "Timer":
if char == 'm':
tkMessageBox.showerror('Error','must enter digits before entering minutes.')
elif char == 's':
tkMessageBox.showerror('Error', 'Must enter digits, minutes and/or hours before starting timer.')
elif char == 'h':
tkMessageBox.showerror('Error', 'Must enter digits before entering hours.')
else:
self.lblText.set(event.char)
#if get this far text != timer
else:
if 'hours' in txt and 'minutes' in txt:
#popup error box
tkMessageBox.showerror('Error','Hours and minutes already selected. Must clear screen or start timer.')
return
if char!= 'm' and char!='s' and char!='h':
self.lblText.set(txt+char)
return
elif char == 'm':
if 'minutes' in txt:
tkMessageBox.showerror('Error','Minutes already accounted for. Must clear screen, enter hours, or start timer.')
return
else:
if 'hours' in txt:
j = txt.split('hours')
self.lblText.set(j[0]+' hours & '+j[1]+' minutes')
return
else:
self.lblText.set(txt+' minutes ')
return
elif char == 'h' :
if 'minutes' in txt:
j = txt.split('minutes')
self.lblText.set(j[1]+' hours & '+j[0]+' minutes')
return
elif 'hours' in txt:
tkMessageBox.showerror('Error','Hours already selected. Start program or select minutes.')
return
else:
self.lblText.set(txt+' hours ')
return
else:
minutes = 0
if 'hours' in txt and 'minutes' in txt:
h = txt.split('hours')
minutes= 60 * int(h[0])
m = txt.split('minutes')
mintues+=int(m[0])
self.timer(minutes)
return
elif 'hours' in txt:
h = txt.split('hours')
minutes = 60 * 60* int(h[0])
self.timer(minutes)
return
elif 'minutes' in txt:
m = txt.split('minutes')
minutes = int(m[0])
self.timer(minutes*60)
return
def timer(self, remaining = None):
if remaining is not None:
self.remaining = remaining
if self.remaining <= 0:
self.lblText.set("time's up!")
else:
self.lblText.set("%d seconds" % self.remaining)
self.remaining = self.remaining - 1
self.after(1000, self.timer)
main = KitchenKomputerMain(None)
main.title = "Komputer"
main.mainloop()
Tkinter Windows Question
Page 1 of 13 Replies - 652 Views - Last Post: 21 November 2012 - 07:36 AM
#1
Tkinter Windows Question
Posted 18 November 2012 - 08:03 AM
Hello all, I have limited gui experience so I'm hoping this isn't a hard one to solve. Basically I have a program that starts by calling a kitchenkomputer class that displays a main menu. In the main menu it creates a main menu window and a seperate window called weather. What I want is the main menu window to go away when an option is selected, but I want the weather window to always be present. Enlighten me.
Replies To: Tkinter Windows Question
#2
Re: Tkinter Windows Question
Posted 20 November 2012 - 05:35 PM
I solved it so for anyone who may want to know. What I did was, first, abandon using toplevel and, second, create a weather class and in the main page at the very bottom initialize the weather class. Where to initialize it was huge. I can't do it in the main program because it's running an infinite loop for the main page. As a result weather doesn't pop up until the main page is closed, or vice versa. I hope this makes sense and will help someone down the line. Here's my work-in-progress code with the weather thing solved.
[edit] ok so I thought I had this solved. But it turns out Tkinter doesn't like drawing things on multiple windows. Well, at least I don't know enough about it to make it work. Sooo I believe I'm going to rewrite my program to just be one window with multiple frames. one frame is going to be a main menu, another frame will be weather, and another will be what the user selects from the main menu.
[edit] ok so I thought I had this solved. But it turns out Tkinter doesn't like drawing things on multiple windows. Well, at least I don't know enough about it to make it work. Sooo I believe I'm going to rewrite my program to just be one window with multiple frames. one frame is going to be a main menu, another frame will be weather, and another will be what the user selects from the main menu.
#!/usr/bin/python
from bs4 import BeautifulSoup
from urllib2 import urlopen
import Tkinter, tkMessageBox, Image, ImageTk
import thread
import time
class KitchenKomputerMain(Tkinter.Tk):
def __init__(self, parent):
Tkinter.Tk.__init__(self,parent)
self.parent = parent
self.initialize()
def initialize(self):
self.grid()
label = Tkinter.Label(self, text="Welcome to the Kitchen Komputer",fg = "yellow", bg="black")
label.grid(column=0,row=0, sticky="EW")
timerButton = Tkinter.Button(self, text=u"Timer", command=self.timer)
#button1 = Tkinter.Button(self, text=u"Radio", command = self.radio)
timerButton.grid(column=0, row=1)
#button1.grid(column=1,row=1)
self.bind("0", self.timer)
#self.bind("1", self.radio)
self.bind("<Escape>", self.kill)
self.resizable(False,False)
self.update()
self.geometry(self.geometry())
self.weather()
def kill(self, event):
self.destroy()
def weather(self):
weather = Weather(None)
weather.title('Weather')
weather.mainloop()
def timer(self,event='0'):
self.kill(self)
t = Timer(None)
t.title("Timer")
class Weather(Tkinter.Tk):
def __init__(self, parent):
Tkinter.Tk.__init__(self,parent)
self.parent = parent
self.initialize()
def initialize(self):
self.sun_data = Image.open('Sunny-128.png')
self.lightning_data = Image.open('lightning-128.png')
self.light_snow_data = Image.open('light-snow.png')
self.light_showers_data = Image.open('Light-Showers-128.png')
self.hail_data = Image.open('hail-128.png')
self.cloudy_data = Image.open('Cloudy-128.png')
self.fog_data = Image.open('fog-128.png')
self.light_rain_data = Image.open('light-rain-128.png')
self.overcast_data = Image.open('Overcast-128.png')
self.rain_data= Image.open('rain-128.png')
self.showers_data = Image.open('Showers-128.png')
self.snow_data = Image.open('snow-128.png')
self.sunny_period_data = Image.open('Sunny-Period-128.png')
self.thunder_data = Image.open('thunder-128.png')
self.thunderstorms_data = Image.open('Thunderstorms-128.png')
self.light_snow_image = ImageTk.PhotoImage(self.light_snow_data)
self.lightning_image = ImageTk.PhotoImage(self.lightning_data)
self.light_showers_image = ImageTk.PhotoImage(self.light_showers_data)
self.hail_image = ImageTk.PhotoImage(self.hail_data)
self.cloudy_image = ImageTk.PhotoImage(self.cloudy_data)
self.fog_image = ImageTk.PhotoImage(self.fog_data)
self.light_rain_image = ImageTk.PhotoImage(self.light_rain_data)
self.overcast_image = ImageTk.PhotoImage(self.overcast_data)
self.rain_image = ImageTk.PhotoImage(self.rain_data)
self.showers_image= ImageTk.PhotoImage(self.showers_data)
self.snow_image = ImageTk.PhotoImage(self.snow_data)
self.sunny_period_image = ImageTk.PhotoImage(self.sunny_period_data)
self.thunder_image = ImageTk.PhotoImage(self.thunder_data)
self.thunderstorms_image = ImageTk.PhotoImage(self.thunderstorms_data)
self.sunny_image = ImageTk.PhotoImage(self.sun_data)
thread.start_new_thread(self.weather,())
def weather(self):
day_of_week_dic = {
"Mon": "Monday",
"Tue": "Tuesday",
"Wed": "Wednesday",
"Thu": "Thursday",
"Fri": "Friday",
"Sat": "Saturday",
"Sun": "Sunday "
}
urlRead = urlopen('http://xml.weather.yahoo.com/forecastrss/63034_f.xml')
soup = BeautifulSoup(urlRead, "lxml")
print soup.title.string
for weather in soup.html.body.find_all('yweather:forecast'):
col+=1
rowSize+=1
self.day_label = Tkinter.Label(text = day_of_week_dic[(weather.get('day'))])
self.high_label = Tkinter.Label(text = weather.get('high'))
self.low_label = Tkinter.Label(text=weather.get('low'))
try:
self.conditions_pic = Tkinter.Label(image=weather.get('text'))
except Exception:
self.conditions_pic = Tkinter.Label(text = weather.get('text'))
time.sleep(60*15)
weather(self)
class Timer(Tkinter.Tk):
def __init__(self,parent):
Tkinter.Tk.__init__(self,parent)
self.parent = parent
self.initialize()
def initialize(self):
#saying we want to use a grid layout
self.grid()
self.lblText = Tkinter.StringVar()
label = Tkinter.Label(self, textvariable=self.lblText,fg = "yellow", bg="black")
label.grid(column=0,row=0,columnspan=5, sticky="EW")
self.lblText.set("Timer")
button1 = Tkinter.Button(self,text="1",command=self.buttonclicked,width=4)
button2 = Tkinter.Button(self,text="2",command=self.buttonclicked,width=4)
button3 = Tkinter.Button(self,text="3",command=self.buttonclicked,width=4)
button4 = Tkinter.Button(self,text="4",command=self.buttonclicked,width=4)
button5 = Tkinter.Button(self,text="5",command=self.buttonclicked,width=4)
button6 = Tkinter.Button(self,text="6",command=self.buttonclicked,width=4)
button7 = Tkinter.Button(self,text="7",command=self.buttonclicked, width=4)
button8 = Tkinter.Button(self,text="8",command=self.buttonclicked, width=4)
button9 = Tkinter.Button(self,text="9",command=self.buttonclicked, width=4)
button0 = Tkinter.Button(self,text="0",command=self.buttonclicked, width=4)
MinutesButton = Tkinter.Button(self,text="Minutes",underline=0,command=self.buttonclicked,width=4)
HoursButton = Tkinter.Button(self,text="Hours",underline=0,command=self.buttonclicked,width=4)
ClrButton = Tkinter.Button(self,text="Clear",underline=0,command=self.buttonclicked,width=4)
StartButton= Tkinter.Button(self,text="Start",underline=0,command=self.buttonclicked,width=4)
PauseButton = Tkinter.Button(self,text="Pause",underline=0,command=self.buttonclicked,width=4)
button1.grid(column=0, row=1)
button2.grid(column=1, row=1)
button3.grid(column=2, row=1)
button4.grid(column=0, row=2)
button5.grid(column=1, row=2)
button6.grid(column=2, row=2)
button7.grid(column=0, row=3)
button8.grid(column=1, row=3)
button9.grid(column=2, row=3)
button0.grid(column=0, row=4)
MinutesButton.grid(column=1,row=4)
HoursButton.grid(column=2, row=4)
ClrButton.grid(column=0,row=5)
StartButton.grid(column=1,row=5)
PauseButton.grid(column=2,row=5)
self.bind("0", self.buttonPressed)
self.bind("1", self.buttonPressed)
self.bind("2", self.buttonPressed)
self.bind("3", self.buttonPressed)
self.bind("4", self.buttonPressed)
self.bind("5", self.buttonPressed)
self.bind("6", self.buttonPressed)
self.bind("7", self.buttonPressed)
self.bind("8", self.buttonPressed)
self.bind("9", self.buttonPressed)
self.bind("p", self.buttonPressed)
self.bind("m", self.buttonPressed)
self.bind("h", self.buttonPressed)
self.bind("s", self.buttonPressed)
#self.bind("<Return>",self.buttonPressed)
self.bind("c", self.buttonPressed)
self.bind("<Escape>", self.kill)
self.resizable(False,False)
self.update()
self.geometry(self.geometry())
def kill(self, event):
self.destroy()
def buttonclicked(self):
pass
def buttonPressed(self,event):
#check if labels text is the default text first
txt = self.lblText.get()
char = event.char
if char == 'c':
self.lblText.set('')
elif txt == "Timer":
if char == 'm':
tkMessageBox.showerror('Error','must enter digits before entering minutes.')
elif char == 's':
tkMessageBox.showerror('Error', 'Must enter digits, minutes and/or hours before starting timer.')
elif char == 'h':
tkMessageBox.showerror('Error', 'Must enter digits before entering hours.')
else:
self.lblText.set(event.char)
#if get this far text != timer
else:
if 'hours' in txt and 'minutes' in txt:
#popup error box
tkMessageBox.showerror('Error','Hours and minutes already selected. Must clear screen or start timer.')
return
if char!= 'm' and char!='s' and char!='h':
self.lblText.set(txt+char)
return
elif char == 'm':
if 'minutes' in txt:
tkMessageBox.showerror('Error','Minutes already accounted for. Must clear screen, enter hours, or start timer.')
return
else:
if 'hours' in txt:
j = txt.split('hours')
self.lblText.set(j[0]+' hours & '+j[1]+' minutes')
return
else:
self.lblText.set(txt+' minutes ')
return
elif char == 'h' :
if 'minutes' in txt:
j = txt.split('minutes')
self.lblText.set(j[1]+' hours & '+j[0]+' minutes')
return
elif 'hours' in txt:
tkMessageBox.showerror('Error','Hours already selected. Start program or select minutes.')
return
else:
self.lblText.set(txt+' hours ')
return
else:
minutes = 0
if 'hours' in txt and 'minutes' in txt:
h = txt.split('hours')
minutes= 60 * int(h[0])
m = txt.split('minutes')
mintues+=int(m[0])
self.timer(minutes)
return
elif 'hours' in txt:
h = txt.split('hours')
minutes = 60 * 60* int(h[0])
self.timer(minutes)
return
elif 'minutes' in txt:
m = txt.split('minutes')
minutes = int(m[0])
self.timer(minutes*60)
return
def timer(self, remaining = None):
if remaining is not None:
self.remaining = remaining
if self.remaining <= 0:
self.lblText.set("time's up!")
else:
self.lblText.set("%d seconds" % self.remaining)
self.remaining = self.remaining - 1
self.after(1000, self.timer)
main = KitchenKomputerMain(None)
main.title("Komputer")
main.mainloop()
This post has been edited by alexr1090: 20 November 2012 - 06:45 PM
#3
Re: Tkinter Windows Question
Posted 20 November 2012 - 10:01 PM
Wow. That's some pretty hard to read code.
When I launch the app (the first set of code, the second contains references to images I don't have), I get a bigger box with nothing in it, title = 'Weather', then another box title='tk', a label "Welcome to the kitchen komputer" with single button "Timer" on it.
Clicking timer kills both windows. None of those things looked like a main menu to me...
Maybe if you could paint a better picture of what you're trying to do I could give you some better advice.
EDIT: I think I get what you're saying. You want a weather thing (displays info about the weather, etc) to always be present somewhere on the screen, and you also want other stuff going on, too. Keep them separate. You could share data between the weather thing and the rest of the app via a database (eg, sqlite), or a file, or by getter methods in the weather class that allow you to access the data you need.
But for now, here's a pretty fun (though probably just as hard to read) GUI I built a while ago in Tkinter that does some nifty stuff you might be interested in. Particularly "introduce", "configure", "add_dynamic_check_buttons", and "remove_dynamic_check_buttons"
Introduce seemed like a good idea at the time because I wanted the user to do something in a Tk window before the main app started if the user had not already done that stuff (IE, specify the paths to various inbound and outbound data directories so I could create check buttons to allow easy access to some but not others, or all at once, or none at all, and where they'd like to store things, and which text editor they use to look at data. )
It launches an independent Tk window from the main app. The main app calls it again when the user wants to edit their config file. So, this could be a way to achieve your main menu deal, by utilizing independent Tk windows that can call each other.
Note that I call mainloop from inside the class constructor, whereas you initialize the class first and then enter the mainloop. Doing it inside the constructor makes it easier to start a Tk app in a new thread.
When I launch the app (the first set of code, the second contains references to images I don't have), I get a bigger box with nothing in it, title = 'Weather', then another box title='tk', a label "Welcome to the kitchen komputer" with single button "Timer" on it.
Clicking timer kills both windows. None of those things looked like a main menu to me...
Maybe if you could paint a better picture of what you're trying to do I could give you some better advice.
EDIT: I think I get what you're saying. You want a weather thing (displays info about the weather, etc) to always be present somewhere on the screen, and you also want other stuff going on, too. Keep them separate. You could share data between the weather thing and the rest of the app via a database (eg, sqlite), or a file, or by getter methods in the weather class that allow you to access the data you need.
But for now, here's a pretty fun (though probably just as hard to read) GUI I built a while ago in Tkinter that does some nifty stuff you might be interested in. Particularly "introduce", "configure", "add_dynamic_check_buttons", and "remove_dynamic_check_buttons"
Introduce seemed like a good idea at the time because I wanted the user to do something in a Tk window before the main app started if the user had not already done that stuff (IE, specify the paths to various inbound and outbound data directories so I could create check buttons to allow easy access to some but not others, or all at once, or none at all, and where they'd like to store things, and which text editor they use to look at data. )
It launches an independent Tk window from the main app. The main app calls it again when the user wants to edit their config file. So, this could be a way to achieve your main menu deal, by utilizing independent Tk windows that can call each other.
Note that I call mainloop from inside the class constructor, whereas you initialize the class first and then enter the mainloop. Doing it inside the constructor makes it easier to start a Tk app in a new thread.
#!/usr/bin/python
#Track number of files scanned
#Track directories currently being scanned
#Add feature to specify num bytes to read from file for use in searching contents
import os
import sys
import re
import time
import math
from Tkinter import *
import threading
import shutil
blank_line = re.compile("^\s+(?!\S+)")
check_button = re.compile("checkbutton[0-9]+")
config_file = ".\\ls4.conf"
def config_file_as_str():
global config_file
return open(config_file, 'r').read()
def write_config_file(config):
conf = open(".\\ls4.conf", 'w')
conf.write(config)
conf.close()
def reload_config_file():
global checks
with open(".\\ls4.conf", 'r') as f:
checks = [str(x.strip()).replace("\\", "\\\\") for x in f if "#" not in x and x != "\n"]
def config_save(root, introduction_message):
my_config = introduction_message.get("1.0", END)
write_config_file(my_config)
reload_config_file()
root.destroy()
def introduce():
msg = """
#edit your config file below.
#lines beginning with a # are comments (IE, they won't be read by the program)
OUTGOING:
#eg, c:\\outgoing. No default because I don't know your drive lettering.
INCOMING:
#eg, c:\\incoming. No default because I don't know your drive lettering.
STORAGE:
#eg, c:\\where_i_store_data. Default is the directory you run the program from.
.\\edi_data
EDITOR:
#eg, c:\\windows\\system32\\notepad.exe. Default is notepad, can use /usr/bin/mousepad etc
c:\\windows\\system32\\notepad.exe
"""
rooti = Tk()
rooti.title("Editing your configuration file.")
introFrame = Frame(rooti)
introduction_label = Label(introFrame, text = "Configure your stuff: ")
introduction_message = Text(introFrame, width=80, height=20)
save_button = Button(introFrame, text = "Save Config", command=lambda: config_save(rooti,introduction_message))
introFrame.grid(row=0, column = 0)
introduction_label.grid(row=0, column = 0)
introduction_message.grid(row = 0, column = 2)
save_button.grid(row = 4, column = 2, sticky=W)
if not os.path.isfile(config_file):
introduction_message.insert(END, msg)
rooti.mainloop()
else:
introduction_message.insert(END, config_file_as_str())
rooti.mainloop(1)
try:
checks = [str(x.strip()).replace("\\", "\\\\") for x in open(".\\ls4.conf", 'r').readlines() if "#" not in x and x != "\n"]
except:
introduce()
checks = [str(x.strip()).replace("\\", "\\\\") for x in open(".\\ls4.conf", 'r').readlines() if "#" not in x and x != "\n"]
directories = []
#CONSTANTS
AOA = "X:\\as2\\outgoing\\archive\\"
AIA = "X:\\as2\\incoming\\archive\\"
UOA = "U:\\outgoing\\archive\\"
UIA = "U:\\incoming\\archive\\"
config_divisions = ['EDITOR:', 'STORAGE:', 'INCOMING:', 'OUTGOING:']
class MainUI(object):
stop = False
filename_list = []
def __init__(self):
self.master = Tk()
self.master.title("Company Search Utility v1.0A")
global directories
self.no_dump = False
self.no_editor = False
self.show_contents = False
self.ISAonly = False
self.reconfiguring = False
self.check_buttons = []
self.nexti = 0
self.dict = {}
self.after_time = None
self.before_time = None
self.InputFrame = Frame(self.master, bd=1, relief=SUNKEN)
self.InputFrame.grid(row=0, column=0)
self.InputFrame.rowconfigure(0, weight=1)
self.InputFrame.columnconfigure(0, weight=1)
self.filename_label = Label(self.InputFrame, text="Filename:")
self.filename_label.grid(row=0, column=0)
self.filename_entry = Entry(self.InputFrame, width=122)
self.filename_entry.grid(row=0, column=1, stick=W+E)
self.contents_label = Label(self.InputFrame, text="Contents:")
self.contents_label.grid(row = 1, column = 0)
self.contents_entry = Entry(self.InputFrame, width=50)
self.contents_entry.grid(row=1, column=1, stick=W+E)
self.directory_label = Label(self.InputFrame, text="Directories:")
self.directory_label.grid(row = 2, column = 0)
self.directory_entry = Entry(self.InputFrame, width=50)
self.directory_entry.grid(row=2, column=1, sticky=W+E)
self.shortcut_instructions_label = Label(self.InputFrame, text="aoa<yyyymm>, aia<yyyymm>, uoa<yyyymm>, uia<yyyymm> are shortcuts to protocol\\archive\\<yyyymm>")
self.shortcut_instructions_label.grid(row = 3, column = 1)
self.config_button = Button(self.InputFrame, text="Edit Config", width = 10, command=self.reconfigure)
self.config_button.grid(row=3, column=0)
self.search_button = Button(self.InputFrame, text="Search", width=10, command=self.search_callback)
self.search_button.grid(row=0, column=2)
self.stop_button = Button(self.InputFrame, text="Stop", width=10, command=self.stop_search)
self.stop_button.grid(row=1, column=2)
self.clear_button = Button(self.InputFrame, text="Clear", width=10, command=self.clear_textbox)
self.clear_button.grid(row=2, column=2)
self.report_status_button = Button(self.InputFrame, text="Edit", width=10, command=self.select_filenames)
self.report_status_button.grid(row=3, column=2)
# self.toggle_contents_button = Checkbutton(self.InputFrame, text="Toggle Contents", width=10, command=self.toggle_contents)
# self.toggle_contents_button.grid(row = 4, column = 2)
self.date_range_entry_label = Label(self.InputFrame, text="Date Range: ")
self.date_range_entry_label.grid(row=4, column=1, sticky=NE)
self.date_range_entry = Entry(self.InputFrame, width=25)
self.date_range_entry.grid(row=4, column=2, sticky=NE)
self.toggle_ISAONLY_button = Checkbutton(self.InputFrame, text="ISA Only", width=10, command=self.searchISAonly)
self.toggle_ISAONLY_button.grid(row=5, column=2)
self.masterCheckboxFrame = Frame(self.InputFrame, bd=1, relief=SUNKEN)
self.masterCheckboxFrame.grid(row=4, column=1)
self.Checkbox_Frame_outgoing = Frame(self.masterCheckboxFrame, bd=1, relief=SUNKEN)
self.Checkbox_Frame_outgoing.grid(row=1, column=0, sticky=W)
self.Checkbox_Frame_incoming = Frame(self.masterCheckboxFrame, bd=1, relief=SUNKEN)
self.Checkbox_Frame_incoming.grid(row=1, column=1, sticky=E)
self.configure()
self.output_frame = Frame(self.master, bd=1, relief=SUNKEN)
self.output_frame.grid(row=1, column=0, sticky=N)
self.output_frame.rowconfigure(0, weight=1)
self.output_frame.columnconfigure(0, weight=1)
self.results_box_frame = Frame(self.output_frame, bd=1, relief=SUNKEN)
self.results_box_frame.grid(row=0, column=1, sticky=W)
self.results_box_frame.rowconfigure(0, weight=1)
self.results_box_frame.columnconfigure(0, weight=1)
self.results_box = Text(self.results_box_frame, width = 100, height=6)
self.results_box.grid(row=1, column=1, sticky=S, pady = 5)
self.results_box.rowconfigure(0, weight=1)
self.results_box.columnconfigure(0, weight=1)
self.results_scrollbar = Scrollbar(self.results_box_frame)
self.results_scrollbar.grid(row=1, column=2, sticky=N+S)
self.results_scrollbar.config(command=self.results_box.yview)
self.results_box.config(yscrollcommand=self.results_scrollbar.set)
self.status_box = Text(self.output_frame, width=10, height=14)
self.status_box.grid(row=0, column=2)
self.report_frame = Frame(self.output_frame, bd=1, relief=SUNKEN)
self.report_frame.grid(row=0, column=1, sticky=NW)
self.status_updates = Text(self.report_frame, height=3, width=100)
self.status_updates.grid(row=1, column=1, pady = 5, sticky=NW)
listbox_row = 1
self.list_box_scroll = Scrollbar(self.output_frame)
self.list_box = Listbox(self.output_frame, width=132, height=5, selectmode = EXTENDED, yscrollcommand=self.list_box_scroll)
self.list_box.grid(row=listbox_row, column=1, sticky=NW, rowspan=5)
self.list_box_scroll.config(command=self.list_box.yview)
self.list_box_scroll.grid(row=listbox_row, column=1, sticky=E+N+S, rowspan = 5)
self.move_files_to_holding_tank = Button(self.output_frame, text="Move", command=self.mt_move_to_tank)
self.move_files_to_holding_tank.grid(row=listbox_row, column=2, sticky=W+N+S, rowspan = 5)
self.as2_label = Label(self.output_frame, text="AS2/VAN outgoing: .x12 file extension")
self.van_label = Label(self.output_frame, text="VAN/AS2 incoming: ._IE/.as2van file extension")
self.as2_label.grid(row=6, column=1, sticky=S)
self.van_label.grid(row=7, column=1, sticky=S)
mainloop()
def quit(self):
self.rooti.destroy()
def config_save(self):
my_config = self.introduction_message.get("1.0", END)
write_config_file(my_config)
def error(self, msg):
threading.Thread(target=self.error, args=[msg]).start()
def _error(self, msg):
root = Tk()
rootFrame = Frame(root)
error_label = Label(rootFrame, text = "Error: ")
error_message = Text(rootFrame, width=50, height=10)
exit_button = Button(rootFrame, text = "Quit", command=self.quit)
error_message.insert(END, msg)
rootFrame.grid(row=0, column = 0)
error_label.grid(row=0, column = 0)
error_message.grid(row = 0, column = 2)
exit_button.grid(row = 2, column = 1)
def reconfigure(self):
global checks
introduce()
self.configure(removing_checkbuttons = True)
self.configure()
def configure(self, removing_checkbuttons = False):
global checks
global directories
directories = []
config_frame = None
adding_checkbuttons = False
_dict = {}
config_frames = []
if not removing_checkbuttons:
for i in xrange(len(checks)):
if checks[i] == "OUTGOING:":
self.config_division = "OUTGOING"
print "Configuring ", self.config_division
adding_checkbuttons = True
config_frame = "self.Checkbox_Frame_outgoing"
_dict[config_frame] = []
config_frames.append(config_frame)
elif checks[i] == "INCOMING:":
self.config_division = "INCOMING"
print "Configuring ", self.config_division
adding_checkbuttons = True
config_frame = "self.Checkbox_Frame_incoming"
_dict[config_frame] = []
config_frames.append(config_frame)
elif checks[i] == "STORAGE:":
adding_checkbuttons = False
if blank_line.search(checks[i+1]) == None and checks[i+1] not in config_divisions:
self.dumping_ground = self.sanitize(checks[i+1])
else:
self.no_dump = True
continue
if not os.path.isdir(self.dumping_ground):
os.mkdir(self.dumping_ground)
if not os.path.isdir("{0}\\bak".format(self.dumping_ground)):
os.mkdir("{0}\\bak".format(self.dumping_ground))
elif checks[i] == "EDITOR:":
adding_checkbuttons = False
try:
if blank_line.search(checks[i+1]) == None and checks[i+1] not in config_divisions:
self.editor = "{0}".format(self.sanitize(checks[i+1]))
if not os.path.isfile(self.sanitize(checks[i+1])):
self.error("{0} doesn't exist.".format(self.editor))
else:
self.no_editor = True
self.error("No editor specified.")
continue
except:
self.no_editor = True
self.error("No editor specified.")
continue
elif blank_line.search(checks[i]):
print "BLANK!"
pass
else:
if adding_checkbuttons:
_dict[config_frame].append(checks[i])
if config_frames != []:
for frame in config_frames:
try:
self.dict[frame] = _dict[frame]
except:
self.dict[frame] = None
if not removing_checkbuttons:
self.add_dynamic_check_buttons(_dict)
self.toggle_empty_frame()
else:
self.remove_dynamic_check_buttons(_dict)
def add_dynamic_check_buttons(self, dict):
button_number = 0
for key in dict.keys():
i = 0
j = 0
k = 0
for i in xrange(0, len(dict[key])):
#print "self.add_dynamic_check_button({0}, {1}, {2}, {3}, {4})".format(button_number, j, k, key, dict[key][i])
self.check_buttons.append(button_number)
self.add_dynamic_check_button(button_number, j, k, key, dict[key][i])
button_number += 1
if j == 10:
j = 0
k += 1
else:
j += 1
def remove_dynamic_check_buttons(self, dict):
for button in self.check_buttons:
self.remove_dynamic_check_button(button)
self.check_buttons = []
def toggle_empty_frame(self):
nframes = len(self.dict.keys())
nframes_forgotten = 0
for frame in self.dict:
if self.dict[frame] == []:
print "forgot: ", frame
exec(compile("{0}.grid_forget()".format(frame), "<string>", "exec"))
nframes_forgotten += 1
else:
if "incoming" in frame:
exec(compile("{0}.grid(row=1, column=0)".format(frame), "<string>", "exec"))
elif "outgoing" in frame:
exec(compile("{0}.grid(row=1, column=1)".format(frame), "<string>", "exec"))
else:
pass
if nframes == nframes_forgotten:
exec(compile("self.masterCheckboxFrame.grid_forget()", "<string>", "exec"))
else:
exec(compile("self.masterCheckboxFrame.grid(row=4, column=1)", "<string>", "exec"))
def add_dynamic_check_button(self, ID, row, column, frame, dir):
objective1 = compile("""def check_checkbutton{0}():
dir = \"{1}\"
if dir in directories:
directories.remove(dir)
else:
directories.append(dir)
print directories""".format(ID, dir), "<string>", "exec")
objective2 = compile("self.checkbutton{0} = Checkbutton({1}, text=\"{2}\", command=check_checkbutton{0})".format(ID, frame, dir), "<string>", "exec")
print "ADDING: self.checkbutton{0}.grid(row={1}, column={2}, sticky=W) for: {3}".format(ID, row, column, dir)
objective3 = compile("self.checkbutton{0}.grid(row={1}, column={2}, sticky=W)".format(ID, row, column), "<string>", "exec")
exec(objective1)
exec(objective2)
exec(objective3)
def remove_dynamic_check_button(self, ID):
exec(compile("self.checkbutton{0}.destroy()".format(ID), "<string>", "exec"))
def clear_checkbuttons(self):
self.configure()
def sanitize(self, msg):
return msg.replace("\\", "\\\\")
def push_status_update(self, msg):
try:
self.status_updates.insert(END, msg + "\n")
self.status_updates.yview(END)
except:
pass
def push_files(self, message):
try:
self.list_box.insert(END, message)
self.list_box.yview(END)
except:
pass
def push_message(self, message):
try:
self.results_box.insert(END, message)
self.results_box.yview(END)
except:
pass
def push_report(self, message):
try:
self.status_box.insert(END, message)
self.status_box.yview(END)
except:
pass
# def push_dirs(self, message):
# try:
# #self.searching_directories.insert(END, message)
# pass
# except:
# pass
def searchISAonly(self):
if(self.ISAonly == False):
self.ISAonly = True
else:
self.ISAonly = False
def select_filenames(self):
#print [self.list_box.get(index) for index in self.list_box.curselection()]
filename_list = ["LAUNCH"]
for filename in [self.list_box.get(index) for index in self.list_box.curselection()]:
filename_list.append(filename.rstrip().lstrip())
self.open_in_nppp(filename_list)
def toggle_contents(self):
if not self.show_contents:
self.show_contents = True
else:
self.show_contents = False
def mt_move_to_tank(self):
if self.no_dump:
pass
else:
threading.Thread(target=self.move_to_tank).start()
def move_to_tank(self):
try:
filenames = [self.list_box.get(index) for index in self.list_box.curselection() if index is not None]
except TclError:
try:
filenames = [self.list_box.get(index) for index in self.list_box.curselection() if index is not None]
except TclError:
pass
self.cleanup_tank()
for filename in filenames:
try:
shutil.copy(filename, self.dumping_ground)
self.push_status_update("Copied {0} to {1}".format(filename, self.dumping_ground))
except:
self.configure()
try:
shutil.copy(filename, self.dumping_ground)
self.push_status_update("Copied {0} to {1}".format(filename, self.dumping_ground))
except:
self.push_status_update("Failed to Copy {0} to {1}".format(filename, self.dumping_ground))
pass
pass
def cleanup_tank(self):
print self.dumping_ground
try:
for file in os.listdir(self.dumping_ground):
if file in os.listdir("{0}\\bak".format(self.dumping_ground)):
if os.path.isfile("{0}\\{1}".format(self.dumping_ground, file)):
#os.system("del /F {0}\\{1}".format(self.dumping_ground, file))
os.remove("{0}\\{1}".format(self.dumping_ground, file))
self.push_status_update("Removed {0}".format(file))
else:
pass
else:
if os.path.isfile("{0}\\{1}".format(self.dumping_ground, file)):
shutil.move("{0}\\{1}".format(self.dumping_ground, file), "{0}\\bak\\{1}".format(self.dumping_ground,file))
self.push_status_update("Moved {0} to bak".format(file))
else:
pass
except WindowsError:
self.configure()
self.move_to_tank()
def file_accessor(self, directory, file_pattern = re.compile("[a-zA-Z0-9-_.]*"), content_pattern = re.compile("\S*"), threadIDx = 0):
start_time = time.clock()
assert directory is not str, "Directory is " + str(type(directory))
filename_list_from_dir = [x for x in os.listdir(directory) if os.path.isfile(os.path.join(directory, x)) and os.stat(os.path.join(directory, x)).st_ctime >= self.after_time and os.stat(os.path.join(directory, x)).st_ctime <= self.before_time]
print filename_list_from_dir
try:
for filename in filename_list_from_dir:
if(self.stop):
self.push_report("T%d:Stopped\n" % threadIDx)
sys.exit()
if file_pattern.search(filename):
if(self.stop):
self.push_report("T%d:Stopped\n" % threadIDx)
sys.exit()
#print "Found [", file_pattern.pattern, "] in (", filename, ")"
#print file_pattern_str + " is in " + filename
if(os.path.isfile(directory+os.path.sep+filename)):
#print directory+ "\\" + file_pattern.search(filename).group() + "----> Is a file"
file_path = (directory + os.path.sep + filename)
if(self.ISAonly):
if(self.stop):
self.push_report("T%d:Stopped\n" % threadIDx)
sys.exit()
file_contents = re.sub("\n","",open(file_path, 'r').read(106))
else:
file_contents = re.sub("\n","",open(file_path, 'r').read())
if(content_pattern.search(file_contents)):
if(self.stop):
self.push_report("T%d:Stopped\n" % threadIDx)
sys.exit()
elapsed_time = time.clock() - start_time
abspath = directory + os.path.sep + filename
if(self.show_contents == False):
file_contents = ""
message = "FOUND: {0}\n".format(abspath)
self.push_files(abspath)
self.push_message(message)
self.filename_list.append(abspath)
# print message
# message_list.append(message)
else:
#patter not matched
pass
#
else:
if(self.stop):
self.push_report("T%d:Stopped\n" % threadIDx)
sys.exit()
pass
elapsed_time = time.clock() - start_time
report = "T%d:%.1fs\n" % (threadIDx, elapsed_time)
self.push_report(report)
except WindowsError:
if(self.stop):
self.push_report("T%d:Stopped\n" % threadIDx)
sys.exit()
try:
self.file_accessor(directory, file_pattern, content_pattern, threadIDx)
except:
pass
def get_date_range(self):
try:
date_range = self.date_range_entry.get()
sp = date_range.split("-")
only_this_day = False
pattern = '%m/%d/%Y %H:%M:%S'
if sp[0] != '' and len(sp) == 1:
if "*" in sp[0]:
only_this_day = True
sp[0] = sp[0].strip("*")
date_time = sp[0]+" 0:0:0"
pattern = '%m/%d/%Y %H:%M:%S'
self.after_time = int(time.mktime(time.strptime(date_time, pattern)))
if only_this_day:
self.before_time = self.after_time + 86399
else:
self.before_time = time.time()
elif len(sp) == 2:
date_time0 = sp[0]+" 0:0:0"
self.after_time = int(time.mktime(time.strptime(date_time0, pattern)))
date_time1 = sp[1]+" 0:0:0"
self.before_time = int(time.mktime(time.strptime(date_time1, pattern)))
else:
self.after_time = int(time.mktime(time.strptime(time.strftime("01/01/1970 0:0:0"), pattern)))
self.before_time = int(time.mktime(time.strptime(time.strftime("%m/%d/%Y %H:%M:%S"), pattern)))
except:
self.after_time = int(time.mktime(time.strptime(time.strftime("01/01/1970 0:0:0"), pattern)))
self.before_time = int(time.mktime(time.strptime(time.strftime("%m/%d/%Y %H:%M:%S"), pattern)))
print "after ", time.ctime(self.after_time)
print "before ", time.ctime(self.before_time)
def search_callback(self):
self.stop = False
self.filenames = re.compile(self.filename_entry.get())
self.contents = re.compile(self.contents_entry.get())
self.date_range = self.get_date_range()
global directories
directories.extend([entry.strip() for entry in self.directory_entry.get().split(",") if entry not in directories])
for i in range(0, len(directories)):
if not ":" in directories[i]:
if "aoa" in directories[i].lower():
dir = AOA+directories[i][3:]
if not os.path.isdir(dir):
directories.pop(i)
else:
directories[i] = dir
elif "aia" in directories[i].lower():
dir = AIA+directories[i][3:]
if not os.path.isdir(dir):
directories.pop(i)
else:
directories[i] = dir
elif "uoa" in directories[i].lower():
dir = UOA+directories[i][3:]
if not os.path.isdir(dir):
directories.pop(i)
else:
directories[i] = dir
elif "uia" in directories[i].lower():
dir = UIA+directories[i][3:]
if not os.path.isdir(dir):
directories.pop(i)
else:
directories[i] = dir
temp = directories
directories = []
for i in temp:
if i not in directories:
directories.append(i)
for thread_no in xrange(len(directories)):
if not directories[thread_no] == "":
threading.Thread(target=self.file_accessor, args=[directories[thread_no], self.filenames, self.contents, thread_no]).start()
self.push_report("T%d:Started\n" % thread_no )
else:
directories.pop(thread_no)
def stop_search(self):
self.stop = True
def clear_textbox(self):
global directories
self.clear_checkbuttons()
directories = []
self.filename_list = []
self.results_box.delete("%d.%d" % (1, 0), END)
self.status_box.delete("%d.%d" % (1, 0), END)
#self.searching_directories.delete("%d.%d" % (1,0), END)
self.list_box.delete(0, END)
self.status_updates.delete("1.0", END)
#self.active_files.delete("%d.%d" % (1,0), END)
def launch_nppp(self, path, args):
#os.execl(path, args)
if "notepad.exe" in self.editor:
for arg in args[1:]:
arg = ["notepad", arg]
os.spawnv(os.P_NOWAIT, path, arg)
else:
os.spawnv(os.P_NOWAIT, path, args)
#os.system("{0} {1}".format(path, args))
def open_in_nppp(self, filename_str):
if self.no_editor:
pass
else:
nppp_thread = threading.Thread(target=self.launch_nppp, args=[self.editor, filename_str])
nppp_thread.start()
MainUI()
This post has been edited by Python_4_President: 20 November 2012 - 10:38 PM
#4
Re: Tkinter Windows Question
Posted 21 November 2012 - 07:36 AM
Python_4_President, on 20 November 2012 - 11:01 PM, said:
Wow. That's some pretty hard to read code.
When I launch the app (the first set of code, the second contains references to images I don't have), I get a bigger box with nothing in it, title = 'Weather', then another box title='tk', a label "Welcome to the kitchen komputer" with single button "Timer" on it.
Clicking timer kills both windows. None of those things looked like a main menu to me...
Maybe if you could paint a better picture of what you're trying to do I could give you some better advice.
EDIT: I think I get what you're saying. You want a weather thing (displays info about the weather, etc) to always be present somewhere on the screen, and you also want other stuff going on, too. Keep them separate. You could share data between the weather thing and the rest of the app via a database (eg, sqlite), or a file, or by getter methods in the weather class that allow you to access the data you need.
But for now, here's a pretty fun (though probably just as hard to read) GUI I built a while ago in Tkinter that does some nifty stuff you might be interested in. Particularly "introduce", "configure", "add_dynamic_check_buttons", and "remove_dynamic_check_buttons"
Introduce seemed like a good idea at the time because I wanted the user to do something in a Tk window before the main app started if the user had not already done that stuff (IE, specify the paths to various inbound and outbound data directories so I could create check buttons to allow easy access to some but not others, or all at once, or none at all, and where they'd like to store things, and which text editor they use to look at data. )
It launches an independent Tk window from the main app. The main app calls it again when the user wants to edit their config file. So, this could be a way to achieve your main menu deal, by utilizing independent Tk windows that can call each other.
Note that I call mainloop from inside the class constructor, whereas you initialize the class first and then enter the mainloop. Doing it inside the constructor makes it easier to start a Tk app in a new thread.
When I launch the app (the first set of code, the second contains references to images I don't have), I get a bigger box with nothing in it, title = 'Weather', then another box title='tk', a label "Welcome to the kitchen komputer" with single button "Timer" on it.
Clicking timer kills both windows. None of those things looked like a main menu to me...
Maybe if you could paint a better picture of what you're trying to do I could give you some better advice.
EDIT: I think I get what you're saying. You want a weather thing (displays info about the weather, etc) to always be present somewhere on the screen, and you also want other stuff going on, too. Keep them separate. You could share data between the weather thing and the rest of the app via a database (eg, sqlite), or a file, or by getter methods in the weather class that allow you to access the data you need.
But for now, here's a pretty fun (though probably just as hard to read) GUI I built a while ago in Tkinter that does some nifty stuff you might be interested in. Particularly "introduce", "configure", "add_dynamic_check_buttons", and "remove_dynamic_check_buttons"
Introduce seemed like a good idea at the time because I wanted the user to do something in a Tk window before the main app started if the user had not already done that stuff (IE, specify the paths to various inbound and outbound data directories so I could create check buttons to allow easy access to some but not others, or all at once, or none at all, and where they'd like to store things, and which text editor they use to look at data. )
It launches an independent Tk window from the main app. The main app calls it again when the user wants to edit their config file. So, this could be a way to achieve your main menu deal, by utilizing independent Tk windows that can call each other.
Note that I call mainloop from inside the class constructor, whereas you initialize the class first and then enter the mainloop. Doing it inside the constructor makes it easier to start a Tk app in a new thread.
Thanks for the code. And yes, what I wanted to do was always have a weather window open. However I'm thinking about changing that up now that I had some problems with running code with multiple windows. So basically disregard my earlier code. I'm going to switch that around. So right now my buddy and I are both making the same program. I've included a screen shot of his to give you a better idea about what I'm trying to do and also to show off his great work. If you have any suggestions on how to accomplish this please let me know.
Also I'm a tkinter noob so I'm reading an online book right now that has a lot of good stuff in it. I'd suggest it to other tkinter noobs as well.
Attached image(s)
This post has been edited by alexr1090: 21 November 2012 - 07:38 AM
Page 1 of 1
|
|

New Topic/Question
Reply



MultiQuote



|