Dynamically printing value of entry in another entry - python

My code:
import tkinter as tk
disp = tk.Tk()
hlabel=tk.Label(text="host")
hlabel.grid(column=0,row=0)
host_entry = tk.Entry(disp)
host_entry.grid(row=0,column=1)
plabel=tk.Label(text="port")
plabel.grid(column=0,row=1)
port_entry = tk.Entry(disp)
port_entry.grid(row=1,column=1)
ulabel=tk.Label(text="Url")
ulabel.grid(column=0,row=3)
url_entry=tk.Entry(disp)
url_entry.grid(row=3,column=1)
url_entry.insert(0,'http://{0}:{1}'.format(host_entry.get(),port_entry.get()))
url_entry.config(state='disabled')
disp.mainloop()
I looked through this awesome answer but couldn't figure out.
The 'host' and 'port' should be displayed in the 'url' Entry as
http://localhost:8080.
The text should be displayed dynamically in url.
Thanks for your help.

The simplest solution is to use a textvariable for each entry, put a trace on each variable, and then update the third entry whenever the trace fires.
First, define a function to update the third entry. It will be called by the trace functions, which automatically appends some arguments which we won't use:
def update_url(*args):
host = host_var.get()
port = port_var.get()
url = "http://{0}:{1}".format(host, port)
url_var.set(url)
Next, create the variables:
host_var = tk.StringVar()
port_var = tk.StringVar()
url_var = tk.StringVar()
Next, add a trace on the host and port:
host_var.trace("w", update_url)
port_var.trace("w", update_url)
Finally, associate the variables with the entries:
host_entry = tk.Entry(..., textvariable=host_var)
port_entry = tk.Entry(..., textvariable=port_var)
url_entry=tk.Entry(..., textvariable=url_var)
Here it is as a full working example:
import tkinter as tk
def update_url(*args):
host = host_var.get()
port = port_var.get()
url = "http://{0}:{1}".format(host, port)
url_var.set(url)
disp = tk.Tk()
host_var = tk.StringVar()
port_var = tk.StringVar()
url_var = tk.StringVar()
host_var.trace("w", update_url)
port_var.trace("w", update_url)
hlabel=tk.Label(text="host")
plabel=tk.Label(text="port")
ulabel=tk.Label(text="Url")
host_entry = tk.Entry(disp, textvariable=host_var)
port_entry = tk.Entry(disp, textvariable=port_var)
url_entry=tk.Entry(disp, textvariable=url_var)
url_entry.config(state='disabled')
hlabel.grid(column=0,row=0)
host_entry.grid(row=0,column=1)
plabel.grid(column=0,row=1)
port_entry.grid(row=1,column=1)
ulabel.grid(column=0,row=3)
url_entry.grid(row=3,column=1)
disp.mainloop()

Related

The radiobuttons cannot be unselected by default

def booking(self):
self.book_win = tk.Tk()
self.book_win.geometry('1000x600')
self.fm7 = tk.Frame(self.book_win,width=300,height=500)
self.fm7.grid(row=0,column=0,rowspan=3,columnspan=2)
self.fm8 = tk.Frame(self.book_win,width=300,height=500)
self.fm8.grid(row=0,column=2,rowspan=3,columnspan=2)
self.book_title = tk.Label(self.fm7,text='Room Prices per night',font=('Helvetica',24))
self.book_title.grid(row=0,columnspan=2,padx=10,pady=10)
self.lb_deluxe = tk.Label(self.fm7,text='Deluxe Room',font=('Helvetica',20))
self.lb_deluxe.grid(row=1,column=0,padx=10,pady=10)
self.pr1 = tk.Label(self.fm7,text=2050,font=('Helvetica',20))
self.pr1.grid(row=1,column=1,padx=10,pady=10)
self.lb_twin = tk.Label(self.fm7,text='Twin Bedroom',font=('Helvetica',20))
self.lb_twin.grid(row=2,column=0,padx=10,pady=10)
self.pr2 = tk.Label(self.fm7,text=2500,font=('Helvetica',20))
self.pr2.grid(row=2,column=1,padx=10,pady=10)
self.lb_king = tk.Label(self.fm7,text='King Bedroom',font=('Helvetica',20))
self.lb_king.grid(row=3,column=0,padx=10,pady=10)
self.pr3 = tk.Label(self.fm7,text=2890,font=('Helvetica',20))
self.pr3.grid(row=3,column=1,padx=10,pady=10)
self.lb_harbour = tk.Label(self.fm7,text='Harbour View Room',font=('Helvetica',20))
self.lb_harbour.grid(row=4,column=0,padx=10,pady=10)
self.pr4 = tk.Label(self.fm7,text=3120,font=('Helvetica',20))
self.pr4.grid(row=4,column=1,padx=10,pady=10)
self.var1 = tk.BooleanVar()
self.ck_breakfast = tk.Checkbutton(self.fm8,text='Breakfast',variable=self.var1,font=('Helvetica',20))
self.ck_breakfast.grid(row=0,columnspan=2,padx=10,pady=10)
self.lb_room = tk.Label(self.fm7,text='Type of Room',font=('Helvetica',20))
self.lb_room.grid(row=6,columnspan=2,padx=10,pady=10)
self.var2 = tk.StringVar()
self.var2.set(' ')
self.rb1 = tk.Radiobutton(self.fm7,text='Deluxe Room',variable=self.var2,value='Deluxe Room')
self.rb1.grid(row=7,column=0,padx=10,pady=10)
self.rb2 = tk.Radiobutton(self.fm7,text='Twin Bedroom',variable=self.var2,value='Twin Bedroom')
self.rb2.grid(row=7,column=1,padx=10,pady=10)
self.rb3 = tk.Radiobutton(self.fm7,text='King Bedroom',variable=self.var2,value='King Bedroom')
self.rb3.grid(row=8,column=0,padx=10,pady=10)
self.rb4 = tk.Radiobutton(self.fm7,text='Harbour View Room',variable=self.var2,value='Harbour View Room')
self.rb4.grid(row=8,column=1,padx=10,pady=10)
In this program, I would like to set all the radiobuttons at the beginning to be unselected. Although I tried self.var2.set(' ') it still does not work. I have already tried to find the solution and change thoroughly but there may have some problems occur. If possible can anyone help me to find out the problem?
The problem with your code was that it has more than one instance of Tk() hence the StringVar() doesnt know which instance to belong to(by default the first created Tk()). So make all additional child windows to Toplevel() and just keep one Tk() for the entire code, unless you exactly know what your doing.
Or if you still wish to keep multiple Tk() then give a master to almost all the extra widgets or variables created(StringVar,IntVar,PhotoImage,etc) like:
self.var2 = tk.StringVar(master=self.book_win)
This is might not work
self.var2 = tk.StringVar()
self.var2.set(None) #set this to none
self.rb1 = tk.Radiobutton(self.fm7,text='Deluxe Room',variable=self.var2,value='Deluxe Room')
self.rb1.grid(row=7,column=0,padx=10,pady=10)
self.rb2 = tk.Radiobutton(self.fm7,text='Twin Bedroom',variable=self.var2,value='Twin Bedroom')
self.rb2.grid(row=7,column=1,padx=10,pady=10)
self.rb3 = tk.Radiobutton(self.fm7,text='King Bedroom',variable=self.var2,value='King Bedroom')
self.rb3.grid(row=8,column=0,padx=10,pady=10)
self.rb4 = tk.Radiobutton(self.fm7,text='Harbour View Room',variable=self.var2,value='Harbour View Room')
self.rb4.grid(row=8,column=1,padx=10,pady=10)

python tkinter Combobox doesn't populate windows hard drives

Dear Folks,
My python Combobox doesn't populate the windows drives. Please Help!!!
import tkinter as tk
from tkinter import ttk
from tkinter import font
import os.path
win = tk.Tk()
win.title("AR Duplicate File Search")
win.geometry("600x600")
win.configure(bg = 'green')
#----------------------------------Combo Box-----------------------------
dl = ['ABCDEFGHIJKLMNOPQRSTUVWXYZ']
drives = ['%s:' % d for d in dl if os.path.exists('%s:' % d)]
def convert(list):
return tuple(list)
listdrive = convert(drives)
search_loc_var = tk.StringVar()
search_loc_cmbbx1 = ttk.Combobox(win, width = 22, textvariable =
search_loc_var, state = 'readonly', values = drives)
# Defining the state readonly will restrict the user from typing anything
# in the combobox.
search_loc_cmbbx1['values'] = listdrive
search_loc_cmbbx1.grid(row = 2, column = 1)
win.mainloop()
I tried to populate the combobox from the tuple and list. But the combobox remains blank.
I suppose you want to populate your ttk.Combobox vertically with your existing drives on the local PC, such as :
C:
D:
E:
To provide this, just need to convert dl to an ordinary string as
dl = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'

Change the color of a single word in a tk option menu?

So I'm grabbing links of events off a website and putting them into a drop down menu to be selected. My code for the menu:
import Tkinter as tk
from Tkinter import StringVar
selectMenu = tk.Tk()
# #-> this is what I have
# Followed by what you can use
#var = Vars()
#events = var.GetVars('Event')
events = " "
options = []
links = []
#forms = (driver.find_elements_by_class_name("with-cats")) #This is what I have
forms = ["Yolo ","Dad? Closed","Anotha One","Normies! Closed"] #This is so you can try it for yourself
for x in forms:
#info = x.text
info = x #Again, this is so you can try it for yourself
if events in info.lower():
links.append(x)
for link in range(0,len(links)):
#options.append(links[link].text)
options.append(links[link])
list(set(options))
selection = []
for link in range(0,len(options)):
selection.append(options[link])
select = StringVar(selectMenu)
select.set("--None Selected--")
menu = tk.OptionMenu(selectMenu, select, *(selection))
msg = "Which one would you like to attend?"
label = tk.Label(selectMenu, text=msg, font="Helvedica 14")
label.pack(side='top', pady=10)
menu.pack(side="top", pady=10)
selectMenu.attributes('-topmost', True)
selectMenu.mainloop()
So this works fine and dandy, but I would like to improve the look to make it more obvious which events are open. To clarify, an event found that is open and put into the menu may look like "This is a cool event", but one that is closed would be read as "This is a cool event Closed". My aim is to be able to make the foreground red of either just the word Closed or the string containing Closed, whichever is possible if any (And I'm not sure if it's possible because menus and buttons on osx are usually defaulted to system settings, maybe there is a way around this?).
Current: Desired:
According to the documentation for OptionMenu here and here I don't think there is a way to set the color of text.
You might be able to get something close to what you want by using a listBox instead. See post here for the listBox example.
Found a solution! Using a Menu inside of a MenuButton the same way Tkinter creates MenuOptions, I was able to create a custom MenuOption. If you want to add more options, you can use the menbutton.configure() option to edit the button, and menbutton.menu to edit the menu items.
import Tkinter as tk
from Tkinter import Menu, Menubutton
class Vars():
global vari
vari = {}
def GetVars(self, var):
return vari.get(str(var))
def SendVars(self, var, val):
vari[str(var)] = val
class App():
def buttselect(self, link, menbutton, selectMenu):
var = Vars()
var.SendVars("Selection", link) # Store selected event
menbutton.configure(text=link) # Set menu text to the selected event
def prnt(self, link):
var = Vars()
print var.GetVars("Selection") # Print event
def __init__(self, selectMenu):
events = " "
options = []
links = []
forms = ["Yolo ","Dad? Closed","Anotha One","Normies! Closed"] #This is so you can try it for yourself
menbutton = Menubutton (selectMenu, text="--None Selected--", relief="raised")
menbutton.grid()
menbutton.menu = Menu (menbutton, tearoff=0)
menbutton["menu"] = menbutton.menu
#Get a list of event names
for x in forms:
info = x #Again, this is so you can try it for yourself
#If desired event keyword is in an event name, add it to the correct links
if events in info.lower():
links.append(x)
#Remove duplicates
for link in range(0,len(links)):
options.append(links[link])
list(set(options))
#Final list of event names turned into menu commands
for link in options:
if "Closed" in link:
menbutton.menu.add_command( label= link, command= lambda link=link: self.buttselect(link, menbutton, selectMenu), foreground='red')
else:
menbutton.menu.add_command( label= link, command= lambda link=link: self.buttselect(link, menbutton, selectMenu))
b = tk.Button(selectMenu, text="Selection", command= lambda link=link: self.prnt(link)) #Print selected event
b.pack()
msg = "Which one would you like to attend?"
label = tk.Label(selectMenu, text=msg, font="Helvedica 14")
label.pack(side='top', pady=10)
menbutton.pack(side="top", pady=10)
selectMenu = tk.Tk()
selectMenu.attributes('-topmost', True)
app = App(selectMenu)
selectMenu.mainloop()
This results in exactly the result desired:
I found a way!
Let's say x is an optionmenu with options:
options=['Red','Blue','Green']
defopt=tk.StringVar(options[0]) #StringVariable to hold the selected option.
x=tk.OptionMenu(self.optmenuframe,defopt,*options)
Now, get the menu object from the optionmenu and use entryconfig method. That's it!
x.children['menu'].entryconfig(0,foreground='red')
x.children['menu'].entryconfig(1,foreground='blue')
x.children['menu'].entryconfig(2,foreground='green')
#0 is the index of the option you want to apply the configurations to.

Changing image label dynamically causes entire window to grow

I'm trying to make my UI (which does other things ordinarily, this is the barebones version) update an image label from a web resource. When you press the button, the entire window grows instead of the image being replaced. I thought that my call to pack would take care of this, but apparently not.
Thanks for the input!
from Tkinter import *
import base64
import urllib2
BTNTEXT_NEW_COMIC = "New Comic"
def get_random_xkcd():
COMIC_PREFIX = 'http://imgs.xkcd.com/comics/'
response = urllib2.urlopen('http://c.xkcd.com/random/comic/')
html = response.read()
if COMIC_PREFIX in html:
index = html.find(COMIC_PREFIX)
substring = html[index:]
endquote = substring.find("\"")
url = substring[:endquote]
return url
else:
return
class LoggerWindow:
def __init__(self, master):
global frame
frame = Frame(master)
frame.pack()
self.newcomic_button = Button(frame, text=BTNTEXT_NEW_COMIC, command=self.new_xkcd)
self.newcomic_button.pack(side=LEFT)
self.new_xkcd()
def new_xkcd(self):
global frame
url = get_random_xkcd()
print url
u = urllib2.urlopen(url)
raw_data = u.read()
u.close()
b64_data = base64.encodestring(raw_data)
self.xkcd_image = PhotoImage(data=b64_data)
self.xkcd_label = Label(image=self.xkcd_image)
self.xkcd_label.pack()
root = Tk()
app = LoggerWindow(root)
root.mainloop()
You should be able to call self.xkcd_label.configure(image=self.xkcd_image) instead of creating a new image like you do. If that doesn't work, try calling self.xkcd_label.pack_forget() to remove the label before repacking it.

How can i make the browsed file the target for process, instead of it being hard coded in?

Instead of "mbox = ?????????" in the def start_processing(self) section, how do i make it the file that has been uploaded. This was originaly hard coded however have changed it to a file upload? Thanks
class App:
def __init__(self, master):
self.master = master
# call start to initialize to create the UI elemets
self.start()
def start(self):
self.master.title("Extract Email Headers")
self.now = datetime.datetime.now()
# CREATE A TEXT/LABEL
# create a variable with text
label01 = "Please select the .mbox file you would like to analyse"
# put "label01" in "self.master" which is the window/frame
# then, put in the first row (row=0) and in the 2nd column (column=1),
# align it to "West"/"W"
tkinter.Label(
self.master, text=label01).grid(row=0, column=0, sticky=tkinter.W)
# CREATE A TEXTBOX
self.filelocation = tkinter.Entry(self.master)
self.filelocation["width"] = 60
self.filelocation.focus_set()
self.filelocation.grid(row=1, column=0)
# CREATE A BUTTON WITH "ASK TO OPEN A FILE"
# see: def browse_file(self)
self.open_file = tkinter.Button(
self.master, text="Browse...", command=self.browse_file)
# put it beside the filelocation textbox
self.open_file.grid(row=1, column=1)
# now for a button
self.submit = tkinter.Button(
self.master, text="Execute!", command=self.start_processing,
fg="red")
self.submit.grid(row=3, column=0)
def start_processing(self):
date1= "Tue, 18 Jan 2015 15:00:37"
date2="Wed, 23 Jan 2015 15:00:37"
date1 = parser.parse(date1)
date2 = parser.parse(date2)
f = open("results.txt","w")
mbox = ????????????????????
count = 0
for msg in mbox:
pprint.pprint(msg._headers, stream = f)
tempdate = parser.parse(msg['Date'])
print(tempdate)
f.close()
print(count)
pass
def browse_file(self):
# put the result in self.filename
self.filename = filedialog.askopenfilename(title="Open a file...")
# this will set the text of the self.filelocation
self.filelocation.insert(0, self.filename)
I'm assuming you want to store the file path in a StringVar. TK uses special control variables to provide functionality for Entry objects. You can create a string control variable by calling the function tk.StringVar().
You want to create the variable when you initialize your UI, so in your start() method:
# CREATE A TEXTBOX
self.filepath = tkinter.StringVar() # This will hold the value of self.filelocation
# We set it to the "textvariable" option of the new entry
self.filelocation = tkinter.Entry(self.master, textvariable=self.filepath)
self.filelocation["width"] = 60
self.filelocation.focus_set()
self.filelocation.grid(row=1, column=0)
Now when we want to retrieve the value of it we use the get() method. In your start_processing() method:
# Here it opens the file, but you may want to do something else
mbox = open(self.filepath.get(),'r')
The way you set the value in your browse_file() method can be updated to use the control variable quite easily. Instead of inserting into the entry box directly, we'll set the value of our control variable and it will automatically update in the text entry field. In browse_file():
# this will set the text of the self.filelocation
self.filepath.set( self.filename )
Now you can properly set and retrieve the value of self.filelocation the intended way. You can change the name of self.filepath to whatever you want, of course.
For more information:
Tkinter 8.5 Reference - Control Variables
TkDocs - Tk Tutorial - Basic Widgets - Entry
I don't know for certain if mbox is supposed to be an open file, a list, a tuple, or some custom object. I'm going to assume it's an open file, since you have a function to pick a filename.
If that's the case, all you need to do is call the get method of the entry widget to get whatever the user typed:
mbox_name = self.filelocation.get()
mbox = open(mbox_name, "r")
for msg in mbox:
...

Categories