Related
Iam complete new to python,
this code i've been following steps from a book "python GUI programing cookbook "
the GUI works fine , but the methods wont work please help :
import tkinter as tk
from tkinter import ttk
from tkinter import scrolledtext
from tkinter import Menu
from tkinter import messagebox as mBox
from tkinter import Spinbox
class OOP:
def __init__(self):
self.win=tk.Tk()
self.win.title("silver and gold")
self.win.iconbitmap(r'E:\hydra-logo.ico')
self.GUI()
def click_me(self):
self.action.configure(text = "item has been added-- "+ self.matrial.get()+self.weight.get())
def quit(self):
self.win.quit()
self.win.destroy()
exit()
def msgbox(self):
answer=mBox.askyesno('','are you satisfied ? ')
if answer==True:
print("+1 satisfied ")
else:
print("+1 unsatisfied ")
def spin(self):
value= self.spin.get()
print(value)
self.scr.insert(tk.INSERT,value+'\n')
def GUI(self):
tabcontrol=ttk.Notebook(self.win)
tab1=ttk.Frame(tabcontrol)
tabcontrol.add(tab1,text = 'Entry')
tab2=ttk.Frame(tabcontrol)
tabcontrol.add(tab2,text = "Storage")
tab3=ttk.Frame(tabcontrol)
tabcontrol.add(tab3,text = "customers")
tab3=tk.Frame(tab3,bg = 'blue')
tab3.pack()
tabcontrol.pack(expand = 1,fill = "both")
safezone=ttk.LabelFrame(tab1,text = 'my comfort zone')
safezone.grid(column = 0,row = 0)
mBox.showinfo('',"Running ")
## my safe zone
storage=ttk.LabelFrame(tab2,text = 'your storage is here')
storage.grid(column = 0,row = 0)
for orangecolor in range(2):
canvas=tk.Canvas(tab3,width = 150,height = 80,highlightthickness = 0,bg = 'orange')
canvas.grid(row = orangecolor,column = orangecolor)
menuBar=Menu(self.win)
self.win.config(menu = menuBar)
fileMenu=Menu(menuBar,tearoff = 0)
HelpMenu=Menu(menuBar,tearoff = 0)
menuBar.add_cascade(label = "File",menu = fileMenu)
menuBar.add_cascade(label = "Help",menu = HelpMenu)
HelpMenu.add_command(label = "About",command = self.msgbox)
fileMenu.add_command(label = "New")
fileMenu.add_command(label = "Exit",command = quit)
fileMenu.add_checkbutton(label = "Night Mode")
labelsFrame=ttk.LabelFrame(storage,text = "made by essam")
labelsFrame.grid(column = 0,row = 9,padx = 10,pady = 0)
ttk.Label(safezone,text = "Choose a metal: ").grid(column = 0,row = 0)
ttk.Label(safezone,text = "type the weight: ").grid(column = 1,row = 0,sticky = 'W')
weight=tk.StringVar()
wightEntered=ttk.Entry(safezone,width = 12,textvariable = weight)
wightEntered.grid(column = 1,row = 1)
wightEntered.focus()
matrial=tk.StringVar()
matrialEntered=ttk.Combobox(safezone,width = 12,textvariable = matrial,state = 'readonly')
matrialEntered.grid(column = 0,row = 1)
matrialEntered [ 'values' ]=("Gold","silver")
matrialEntered.current(0)
action=ttk.Button(safezone,text = "add ",command = self.click_me)
action.grid(column = 4,row = 1)
radVar=tk.IntVar()
radVar.set(99)
colors=[ "blue","gold","red" ]
spin=Spinbox(safezone,values = (1,2,4,42,100),width = 5,borderwidth = 20,
relief = tk.SUNKEN,command = self.spin)
spin.grid(column = 2,row = 1)
scrolW=30
scrolH=3
scr=scrolledtext.ScrolledText(safezone,width = scrolW,height = scrolH,wrap = tk.WORD)
scr.grid(column = 0,columnspan = 5,row = 7)
#******
oop =OOP()
oop.win.mainloop()
Major programming noob here, and my very first question in stackoverflow. I'm trying to make a time reaction tester, with a simplistic Tkinter GUI.
Here's the code
#!/usr/bin/env python
import tkinter as tk
import time
import random
class TRTest(tk.Frame):
def __init__(self, master = None):
super().__init__()
self.grid()
self.canv()
self.createWidgets()
self.Test
self.totalt = []
def createWidgets(self):
self.quitbtn = tk.Button(self, text = "Quit", command=self.master.destroy)
self.quitbtn.grid(row = 3, column = 3)
self.label = tk.Label(self, text = "TRTest")
self.label.grid(row = 1, column = 3)
self.testbtn = tk.Button(self, text = "Start test", command = self.Test)
self.testbtn.grid(row = 1, column = 2)
def canv(self):
self.scrn = tk.Canvas(self, width = 400, height = 400, bg = "#E8E8E8")
self.scrn.grid(row = 2, column = 3)
def fixate(self):
self.scrn.create_line(190, 200, 210, 200, width = 2)
self.scrn.create_line(200, 190, 200, 210, width = 2)
def createCircle(self):
self.scrn.create_oval(150, 150, 250, 250, fill = "red", tag = "circle")
def Test(self):
if len(self.totalt) == 0:
self.fixate()
self.update()
self.bind_all("<Key>", self.gettime)
self.after(random.randint(1000, 5000))
self.t0 = time.clock()
self.createCircle()
def gettime(self, event):
t = time.clock() - self.t0
self.totalt.append(t)
self.scrn.delete("circle")
if len(self.totalt) < 6:
self.Test
else:
print(self.totalt)
a = tk.Tk()
b = TRTest(a)
b.mainloop()
It should be making 5 trials and returning the list of the measured TR times, but it freezes before showing a second circle. Where's the problem?
In addition to the answer from Patrick Haugh, you aren't using the .after method correctly.
Change this line of code
self.after(random.randint(1000, 5000))
to
self.after(random.randint(1000, 5000),self.Test)
and move it to after
if len(selftotalt) < 6:
This will call the self.Test function again after a random period of time between 1 and 5 seconds.
If more 6 or more reaction times have been captures it will no longer call the function again but print out the times.
Full code that seem to work for me
import tkinter as tk
import time
import random
class TRTest(tk.Frame):
def __init__(self, master = None):
super().__init__()
self.grid()
self.canv()
self.createWidgets()
self.totalt = []
def createWidgets(self):
self.quitbtn = tk.Button(self, text = "Quit", command=self.master.destroy)
self.quitbtn.grid(row = 3, column = 3)
self.label = tk.Label(self, text = "TRTest")
self.label.grid(row = 1, column = 3)
self.testbtn = tk.Button(self, text = "Start test", command = self.Test)
self.testbtn.grid(row = 1, column = 2)
def canv(self):
self.scrn = tk.Canvas(self, width = 400, height = 400, bg = "#E8E8E8")
self.scrn.grid(row = 2, column = 3)
def fixate(self):
self.scrn.create_line(190, 200, 210, 200, width = 2)
self.scrn.create_line(200, 190, 200, 210, width = 2)
def createCircle(self):
self.scrn.create_oval(150, 150, 250, 250, fill = "red", tag = "circle")
def Test(self):
if len(self.totalt) == 0:
self.fixate()
self.update()
self.bind_all("<Key>", self.gettime)
self.t0 = time.clock()
self.createCircle()
def gettime(self, event):
t = time.clock() - self.t0
self.totalt.append(t)
self.scrn.delete("circle")
if len(self.totalt) < 6:
self.after(random.randint(1000, 5000),self.Test)
else:
print(self.totalt)
a = tk.Tk()
b = TRTest(a)
b.mainloop()
I think you are trying to run the method Test with
self.Test
Try instead
self.Test()
This is my code:
from tkinter import *
class Car:
def __init__(self, car_id, name, num_seats, available):
self.car_id = car_id
self.name = name
self.num_seats = num_seats
self.available = available
available_cars.append(self.name)
def hire_car(self):
self.available = False
booked_cars.append(self.name)
available_cars.remove(self.name)
def return_car(self):
self.available = True
booked_cars.remove(self.name)
available_cars.append(self.name)
def display():
pass
class Carlist:
def __init__(self, available_cars):
self.available_cars = available_cars
def addCar():
pass
def displayAvailable():
print(available_cars)
def displayBooked():
print(booked_cars)
booked_cars = []
available_cars = []
Car(1,"Suzuki Van", 2, True)
id2 = Car(2,"Toyota Corolla", 4, True)
id3 = Car(3,"Honda Crv", 4, True)
id4 = Car(4,"Suzuki Swift", 4, True)
id5 = Car(5,"Mitsibishi Airtrek", 4, True)
id6 = Car(6,"Nissan DC Ute", 4, True)
id7 = Car(7,"Toyota Previa", 7, True)
Car.hire_car(id3)
Carlist.displayAvailable()
Carlist.displayBooked()
#Interface Code
root = Tk()
root.title("Car Booking System")
frameTop = Frame(root)
frameLeft = Frame(root)
frameRight = Frame(root)
frameBottom = Frame(root)
#Top
topLabel = Label(frameTop, text = "Car Booking System", font = 20).pack()
#Right Side
bookLabel = Label(frameRight, text = "Book:").pack()
varSelectedCar = StringVar()
varSelectedCar.set(available_cars[0])
optionHire = OptionMenu(frameRight, varSelectedCar, *available_cars).pack()
buttonHireCar = Button(frameRight, text = "Enter", command = Car.hire_car).pack()
#Left Side
returnLabel = Label(frameLeft, text = "Return:").pack()
varSelectedCar2 = StringVar()
varSelectedCar2.set(booked_cars[0])
optionReturn = OptionMenu(frameLeft, varSelectedCar2, *booked_cars).pack()
buttonHireCar2 = Button(frameLeft, text = "Enter", command = Car.hire_car).pack()
#Bottom
summaryLabel = Label(frameBottom, text = "Summary:").pack()
#INITIALISATION
frameTop.pack(side = TOP)
frameLeft.pack(side = LEFT)
frameRight.pack(side = RIGHT)
frameBottom.pack(side = BOTTOM)
root.mainloop()
I am trying to link the lists to the GUI interface so when enter is clicked it either runs hire_car or return_car and adds their name to the relevant list. Any idea how to do this? Help would be much appreciated.
The overall idea is to have a program which can book and return cars and as a summary at the bottom....
Although this site is not to make other's homework, you got lucky today. However, please try to figure out how it works. How to update OptionMenu info is from HERE.
from collections import namedtuple
from tkinter import *
Car = namedtuple('Car', 'name num_seats')
class CarList:
ID = 0
def __init__(self):
self.cars, self.hired = {}, set()
def add_car(self, car):
self.cars[self.ID] = car
self.ID += 1
def available_cars(self):
'''Returns the list of (id, Car) tuples sorted by Car.'''
return sorted(((car, id)
for id, car in self.cars.items()
if id not in self.hired))
#staticmethod
def labels(cars_seq):
return ['{} [{}]'.format(t[0].name, t[1])
for t in cars_seq]
def hire_car(self, id):
if id in self.hired:
raise ValueError('That car is already hired.')
self.hired.add(id)
def hired_cars(self):
return sorted(((self.cars[id], id)
for id in self.hired))
def return_car(self, id):
if id not in self.hired:
raise ValueError('That car is not even hired.')
self.hired.remove(id)
def add_car(car):
if not isinstance(car, Car):
raise TypeError('Invalid car object.')
carlist.add_car(car)
update_optionmenus()
def hire_car():
label = opt_hire.var.get()
if label:
id = int(label.rsplit(maxsplit=1)[-1][1:-1])
carlist.hire_car(id)
update_optionmenus()
def return_car():
label = opt_return.var.get()
if label:
id = int(label.rsplit(maxsplit=1)[-1][1:-1])
carlist.return_car(id)
update_optionmenus()
def _update_optionmenu(opt_menu_widget, car_seq):
cars = carlist.labels(car_seq)
if cars:
opt_menu_widget.var.set(cars[0])
else:
opt_menu_widget.var.set('')
opt_menu_widget['menu'].delete(0, END)
for lab in cars:
opt_menu_widget['menu'].add_command(label=lab,
command=lambda lab=lab: opt_menu_widget.var.set(lab))
def update_optionmenus():
_update_optionmenu(opt_hire, carlist.available_cars())
_update_optionmenu(opt_return, carlist.hired_cars())
# You have to initiate a carlist to make it work.
carlist = CarList()
#Interface Code
root = Tk()
root.title('Car Booking System')
frame_top = Frame(root)
frame_top.pack(side = TOP)
frame_left = Frame(root)
frame_left.pack(side = LEFT)
frame_right = Frame(root)
frame_right.pack(side = RIGHT)
frame_bottom = Frame(root)
frame_bottom.pack(side = BOTTOM)
#Top
label_top = Label(frame_top, text = 'Car Booking System',
font = 20).pack()
#Right Side
label_hire = Label(frame_right, text = 'Book:', width=25).pack()
gui_var_hire = StringVar()
opt_hire = OptionMenu(frame_right, gui_var_hire, 'anything')
opt_hire.var = gui_var_hire
del gui_var_hire
opt_hire.pack()
button_hire = Button(frame_right, text = 'Enter',
command = hire_car).pack()
#Left Side
label_return = Label(frame_left, text = 'Return:', width=25).pack()
gui_var_return = StringVar()
opt_return = OptionMenu(frame_left, gui_var_return, 'anything')
opt_return.var = gui_var_return
opt_return.pack()
del gui_var_return
button_return = Button(frame_left, text = 'Enter',
command = return_car).pack()
#Bottom
label_summary = Label(frame_bottom, text = 'Summary:').pack()
add_car(Car('Suzuki Van', 2))
add_car(Car('Toyota Corolla', 4))
add_car(Car('Honda Crv', 4))
add_car(Car('Suzuki Swift', 4))
add_car(Car('Mitsibishi Airtrek', 4))
add_car(Car('Nissan DC Ute', 4))
add_car(Car('Toyota Previa', 7))
add_car(Car('Honda Crv', 2))
root.mainloop()
what i have is a window that opens up and it has a list box. this is created using one class. when i click the search button and results are found using a different class, i want the list box to update without having to open up another window. below is my code so far\n
from Tkinter import *
class addTask:
def __init__(self):
self.addWindow = Tk()
self.addWindow.configure(background = "black")
self.addWindow.geometry("450x450")
self.addWindow.resizable(width = False, height = False)
self.addWindow.title("Add Task")
self.addNameLabel = Label(self.addWindow,text="Add the name of the task",font = ("Helvetica",10,"italic"),bg = "black",fg = "white")
self.addNameLabel.place(relx=0.01, rely=0.05)
self.nameWiget = Text (self.addWindow, width = 63, height = 1)
self.nameWiget.place(relx=0.0, rely=0.1)
self.addDateLabel = Label(self.addWindow,text="Add the date of the task",font = ("Helvetica",10,"italic"),bg = "black",fg = "white")
self.addDateLabel.place(relx=0.01, rely=0.2)
self.dateWiget = Text (self.addWindow, width = 63, height = 1)
self.dateWiget.place(relx=0.0, rely=0.25)
self.addTaskLabel = Label(self.addWindow,text="Add the details of the task",font = ("Helvetica",10,"italic"),bg = "black",fg = "white")
self.addTaskLabel.place(relx=0.01, rely=0.35)
self.taskWiget = Text (self.addWindow, width = 63, height = 1)
self.taskWiget.place(relx=0.0, rely=0.4)
addButton = Button(self.addWindow,height = 5, width = 20, text="Add Task",highlightbackground="black",font=("Helvetica",10,"bold"),command=lambda:self.saveFuntion())
addButton.place(relx=0.25, rely=0.55)
def saveFuntion(self):
nameInfo = (self.nameWiget.get(1.0, END))
dateInfo = self.dateWiget.get(1.0, END)
taskInfo = self.taskWiget.get(1.0, END)
print nameInfo
task1 = Task(nameInfo,dateInfo,taskInfo)
task1.save()
self.nameWiget.delete(1.0,END)
class Task:
def __init__(self,name,date,task):
self.__name = name
self.__date = date
self.__task = task
def save(self):
fileName = open("dataFile.txt","a")
fileName.write(self.__name)
fileName.write(self.__date)
fileName.write(self.__task)
class editTask:
def __init__(self):
self.editWindow = Tk()
self.newWindow = Tk()
self.newWindow.geometry("450x750")
self.editWindow.configure(background = "black")
self.editWindow.geometry("450x750")
self.editWindow.resizable(width = False, height = False)
self.editWindow.title("Edit Task")
self.listBox = Listbox(self.editWindow,heigh = 15, width = 30)
self.listBox.place(relx = 0.2, rely = 0.6)
#drop down menu
self.var = StringVar(self.editWindow)
self.var.set("Select search critria")
self.choices = ["Name","Date"]
self.option = OptionMenu(self.editWindow,self.var,*self.choices)
self.option.configure(bg = "black")
self.option.place(relx = 0.5, rely = 0.2)
#edit label and text box
self.editLabel = Label(self.editWindow,text="Add the name of the task",font = ("Helvetica",10,"italic"),bg = "black",fg = "white")
self.editLabel.place(relx=0.01, rely=0.05)
self.editInfoWiget = Text (self.editWindow, width = 63, height = 1)
self.editInfoWiget.place(relx=0.0, rely=0.1)
# search button
searchButton = Button(self.editWindow,height = 5, width = 20, text="Search for Task",highlightbackground="black",font=("Helvetica",10,"bold"),command=lambda:self.searchFuntion())
searchButton.place(relx=0.3, rely=0.4)
def searchFuntion(self):
critria = self.var.get()
info = self.editInfoWiget.get(1.0,END)
thing = info.split("\n")
thing2 = thing[0]
search = searchCritria(critria,thing2)
search.search()
# def openListBox(self):
class searchCritria():
def __init__(self,critria,info):
self.__critria = critria
self.__info = info
def search(self):
self.file = open("dataFile.txt", "r+")
fileData = self.file.readlines()
self.file.close()
lengthOfFile = len(fileData)
counter = 1
self.name = []
self.date = []
self.details = []
for i in range (lengthOfFile):
split = fileData[i].split("\n")
while counter == 1:
self.name.append(split)
break
while counter == 2:
self.date.append(split)
break
while counter == 3:
self.details.append(split)
break
counter = counter +1
if counter > 3:
counter = 1
if self.__critria == "Name":
for x in range (len(self.name)):
self.taskName = self.name[x]
self.taskName2 = self.taskName[0]
if self.__info == self.taskName2:
openWindow = True
else :
openWindow = False
if openWindow == True:
editTask().listBox.insert(END,self.taskName2)
if self.__critria == "Date":
for x in range (len(self.date)):
self.taskDate = self.date[x]
self.taskDate2 = self.taskDate[0]
if self.__info == self.taskDate2:
print "found"
else :
print"not found"
class editTask2():
def __init__(self):
self.edit2Window = Tk()
self.edit2Window.configure(background = "black")
self.edit2Window.geometry("450x350")
self.edit2Window.resizable(width = False, height = False)
self.edit2Window.title("Edit Task")
any help would be great
thanks
The biggest problem in your code is that you're creating multiple instances of Tk. Tkinter simply isn't designed to work that way. You should only ever create a single instance of Tk. If you need additional windows, create instances of Toplevel.
Also, you need to call the mainloop function of this instance of Tk exactly once. Without it, your GUI will not work.
If you want to update a listbox in another class than where it was created, the concept is pretty simple: if A needs to update B, A needs a reference to B. So, either pass in a reference to the listbox when you create the other class, or give the other class a method you can call where you pass in the reference to the listbox after it was created.
I am attempting to create a python script to calculate the shortest trip around a set of colleges. i need to add a starting point, but ive confused myself beyond belief to the point of no return. Can anyone help me figure out where to go from here
from Tkinter import *
import tkMessageBox, tkFileDialog
import json
import re
from urllib import urlopen
import math
class Application(Frame):
collegelist = []
collegelist1 = []
def __init__(self,master=None):
Frame.__init__(self,master)
self.pack()
self.createWidgets()
def createWidgets(self):
self.top_frame = Frame(self)
self.mid_frame = Frame(self)
self.bot_frame = Frame(self, bg = 'red')
self.top_frame.pack(side = 'top')
self.mid_frame.pack(side = 'top')
self.bot_frame.pack(side = 'top')
#top frame
self.label1 = Label(self.top_frame, text = "Your College Choices", bg ='red')
self.label1.pack(side = 'left', padx='40', pady='0')
self.label2 = Label(self.top_frame, text = "Your Tour Selections", bg ='green')
self.label2.pack(side = 'right', padx='40')
#mid frame
self.mylist = Listbox(self.mid_frame,
bg = 'black',
fg = 'gold')
self.mylist.pack(side='left')
self.my_button1 = Button(self.mid_frame, text = '>>>', command=self.getlist)
self.my_button2 = Button(self.mid_frame, text = '<<<', command=self.returnlist)
self.my_button1.pack(side="left")
self.my_button2.pack(side="left")
self.mylist1 = Listbox(self.mid_frame,
selectmode=DISABLED,
bg = 'black',
fg = 'gold')
self.mylist1.pack(side='right')
#bottom frame
self.openbutton = Button(self.bot_frame, text='Open File', command=self.openfile, fg ='green')
self.openbutton.pack(side='left')
self.my_button = Button(self.bot_frame, text = 'Route', fg ='green', command=self.collegeroute)
self.my_button.pack(side='left')
self.quit_button = Button(self.bot_frame, text = 'Quit',
command = self.quit, fg = 'green')
self.quit_button.pack(side='left')
def openfile(self):
filename = tkFileDialog.askopenfilename(title='Choose a file')
if filename:
clist = open(filename, "r")
for line in clist.readlines():
for i in line.split():
self.collegelist.append(i)
for college in self.collegelist:
self.mylist.insert(1,college)
def getlist(self):
# get selected line index
index = [int(x) for x in self.mylist.curselection()]
print index
for i in index:
seltext = self.mylist.get(i)
self.mylist.delete(i)
self.mylist1.insert(1,seltext)
self.collegelist1.append(seltext)
print seltext
def returnlist(self):
# get selected line index
index = [int(x) for x in self.mylist1.curselection()]
for i in index:
seltext = self.mylist1.get(i)
self.mylist1.delete(i)
seltext = seltext.strip()
seltext = seltext.replace(' ', '')
self.mylist.insert(0,seltext)
self.collegelist1.remove(seltext)
def collegeroute(self):
# get selected line index
global tuplist
self.tuplist =[]
for college in self.collegelist1:
f = urlopen('http://graph.facebook.com/%s' % college) #load in the events
d = json.load(f)
longitude = d["location"]["longitude"]
latitude = d["location"]["latitude"]
name = d['name']
self.tuplist.append((latitude, longitude))
cartesian_matrix(self.tuplist)
def cartesian_matrix(coords):
'''create a distance matrix for the city coords
that uses straight line distance'''
matrix={}
for i,(x1,y1) in enumerate(coords):
for j,(x2,y2) in enumerate(coords):
dx,dy=x1-x2,y1-y2
dist=math.sqrt(dx*dx + dy*dy)
matrix[i,j]=dist
tour_length(matrix,collegelist1)
return matrix
def tour_length(matrix,tour):
total=0
num_cities=len(tour)
print tour
print num_cities
for i in range(num_cities):
j=(i+1)%num_cities
city_i=tour[i]
city_j=tour[j]
total+=matrix[city_i,city_j]
print total
def getRad(x):
return float(x) * (math.pi/180.0)
def main():
app = Application()
app.master.title("My Application")
app.mainloop()
if __name__ == "__main__":
main()
Having trouble getting the tour_length to work
You are calling tour_length and returning from cartesian_matrix in the wrong place. You are only doing one row of the matrix, then calling tour_length and returning.
Having trouble getting the tour_length to work
The only obvious problem with tour_length that I see is that you're failing to return the result. Add the following at the end:
return total
Upon closer inspection, the following also looks suspect:
tour_length(matrix,collegelist1)
return matrix
Firstly, it's mis-indented. Secondly, you're ignoring the return value of tour_length.
The mis-indentation is probably what's causing the exception (you're calling tour_length before you have fully initialized matrix).