so here's the problem. I have started using python for a little while and I have come across a problem. Although it may seem basic at first, it has had me busy for hours on end. *I do not receive any syntax errors when running the program, although the program fails to write the new IP to file.
I am making a function for a program, that asks the client for a new IP address as the servers(my IP) is currently not static. As my IP changes quite frequently, i would like to give clients (that are attempting to establish a connection with me) the option to change the IP that they are trying to connect to.
So here is the function:
#CONFIGURE NEW IP
def IpConfigNew():
#Creates new window
IpConfig = Tk()
IpConfig.configure(background = 'white')
IpConfig.title('Configure IP')
IpConfig.geometry('300x60+260+380')
IpNew = StringVar()
Label(IpConfig, font = ('Helvetica',12), text = 'Please enter the IP address of the server', bg = 'white').place(x=0,y=4)
#Creates box for user to type IP in.
Entry(IpConfig,textvariable=IpNew, bg = "light blue").place(x=4,y=35)
#Store New Ip NOTE that it is nested within IpConfigNew
def IpStore():
#Retrieves new IP from text box and stores it in variable
GetIpNew = IpNew.get()
mypath = str('Latest Server')
#Creates directory to write new IP to.
if not os.path.isdir(mypath):
os.makedirs(mypath)
StoreLatestServer = open('Latest Server\NewIp.txt', 'w')
#Writes new IP
StoreLatestServer.write("%s"%(GetIpNew))
StoreLatestServer.close()
IpConfig.destroy()#Closes window
#Calls on function IpStore in order to store the new IP
Button(IpConfig,text = 'Done', command = IpStore).place(x=150,y=30)
IpConfig.mainloop()
def PromptIpReconfig():
confirm = tkMessageBox.askyesno(title = "Configure Server IP", message = "Are you sure?")
#Checks to see if the user chose to change IP
if confirm >0:
#In the event that the user said yes go to IpConfigNew
IpConfigNew()
else:
return
#Configure Menu Bar #Sets up Menu Bar for parent Window(app)
menubar = Menu(app)
filemenu = Menu(menubar,tearoff = 0)
# Goes to PromptIpReconfig (Prompts user to Reconfigure the IP after clicking button)
filemenu.add_command(label="Configure IP", command = PromptIpReconfig)
filemenu.add_command(label="Quit", command=app.destroy)
menubar.add_cascade(label='Options',menu = filemenu)
app.config(menu=menubar)#Draws menubar on parent window(app)
I am not sure why its not working as I have done this before expect slightly differently. When I attempt to write the new IP to file, nothing gets written to the file. The new directory is created, so I know that the function is working. I contrasted between the program that I made a while back that work and this one. What i found was that if I did this it worked fine:
#CONFIGURE NEW IP
#Creates new window
IpConfig = Tk()
IpConfig.configure(background = 'white')
IpConfig.title('Configure IP')
IpConfig.geometry('300x60+260+380')
IpNew = StringVar()
Label(IpConfig, font = ('Helvetica',12), text = 'Please enter the IP address of the server', bg = 'white').place(x=0,y=4)
#Creates box for user to type IP in.
Entry(IpConfig,textvariable=IpNew, bg = "light blue").place(x=4,y=35)
#Store New Ip
def IpStore():
#Retrieves new IP from text box and stores it in variable GetIpNew
GetIpNew = IpNew.get()
mypath = str('Latest Server')
#Creates directory to write new IP to.
if not os.path.isdir(mypath):
os.makedirs(mypath)
StoreLatestServer = open('Latest Server\NewIp.txt', 'w')
#Writes new IP
StoreLatestServer.write("%s"%(GetIpNew))
StoreLatestServer.close()
#Closes window
IpConfig.destroy()
#Calls on function IpStore in order to store the new IP
Button(IpConfig,text = 'Done', command = IpStore).place(x=150,y=30)
IpConfig.mainloop()
I found that if I initiate without using the menu bar and instead just initiate it at program start, it works fine. I am not sure whether the problem is calling the IpConfigNew function from the menu bar or whether it has something to do with the fact that I am nesting functions.
I would love it if someone could help me out here as its been bugging me for days!
I would move those 2 lines inside IpConfigNew
, at the end:
#Calls on function IpStore in order to store the new IP
Button(IpConfig,text = 'Done', command = IpStore).place(x=150,y=30)
IpConfig.mainloop()
EDIT : it seems there is a kind of bug with multiple event loops and StringVar, see Tkinter Folklore . Anyway in your case you want to show a dialog, you don't need another Tk loop. So change your code like this:
def IpConfigNew():
#Creates a Toplevel window instead of a new "main" window in a new loop
IpConfig = Toplevel(app)
...
#IpConfig.mainloop()
app.wait_window(IpConfig)
This solves your problem in my test.
I didnt make the layout of my program very clear beforehand, I will try and explain it now.
What i have is my main window and inside my main window(called "app") i have set up a menu bar. This menu bar has aa cascade called "options" and a command called "PromptIpReconfig":
app = Tk()
filemenu.add_command(label="Configure IP", command = PromptIpReconfig)
filemenu.add_command(label="Quit", command=app.destroy)
menubar.add_cascade(label='Options',menu = filemenu)
When I call the function "PromptIpReconfig" the following happens:
def PromptIpReconfig():
confirm = tkMessageBox.askyesno(title = "Configure Server IP", message = "Are you sure?")
if confirm >0:
IpConfigNew()
else:
return
If the user decides to say yes then IpConfigNew()
is called:
#CONFIGURE NEW IP
def IpConfigNew():
IpConfig = Tk()
IpConfig.configure(background = 'white')
IpConfig.title('Configure IP')
IpConfig.geometry('300x60+260+380')
IpNew = StringVar()
Label(IpConfig, font = ('Helvetica',12), text = 'Please enter the IP address of the server', bg = 'white').place(x=0,y=4)
Entry(IpConfig,textvariable=IpNew, bg = "light blue").place(x=4,y=35)
#Store New Ip
def IpStore():
GetIpNew = IpNew.get()
mypath = str('Latest Server')
if not os.path.isdir(mypath):
os.makedirs(mypath)
StoreLatestServer = open('Latest Server\NewIp.txt', 'w')
StoreLatestServer.write("%s"%(GetIpNew))
StoreLatestServer.close()
IpConfig.destroy()
Button(IpConfig,text = 'Done', command = IpStore).place(x=150,y=30)
IpConfig.mainloop()
IpConfigNew opens a child window IpConfig = Tk()
within the main window. The child window provides a button to click after the new IP has been entered. Once the button is clicked it calls the command "IpStore":
#Store New Ip
def IpStore():
GetIpNew = IpNew.get()
mypath = str('Latest Server')
if not os.path.isdir(mypath):
os.makedirs(mypath)
StoreLatestServer = open('Latest Server\NewIp.txt', 'w')
StoreLatestServer.write("%s"%(GetIpNew))
StoreLatestServer.close()
IpConfig.destroy()
So basically the overall layout of my program looks like this:
from Tkinter import *
import os
import tkMessageBox
#Create parent window
app = Tk()
def IpConfigNew():
#Creates new window
IpConfig = Tk()
IpNew = StringVar()
Label(IpConfig, font = ('Helvetica',12), text = 'Please enter the IP address of the server', bg = 'white').place(x=0,y=4)
#Creates box for user to type IP in.
Entry(IpConfig,textvariable=IpNew, bg = "light blue").place(x=4,y=35)
#Store New Ip NOTE that it is nested within IpConfigNew
def IpStore():
#Retrieves new IP from text box and stores it in variable
GetIpNew = IpNew.get()
mypath = str('Latest Server')
#Creates directory to write new IP to.
if not os.path.isdir(mypath):
os.makedirs(mypath)
StoreLatestServer = open('Latest Server\NewIp.txt', 'w')
#Writes new IP
StoreLatestServer.write("%s"%(GetIpNew))
StoreLatestServer.close()
IpConfig.destroy()#Closes window
#Calls on function IpStore in order to store the new IP
Button(IpConfig,text = 'Done', command = IpStore).place(x=150,y=30)
IpConfig.mainloop()
def PromptIpReconfig():
confirm = tkMessageBox.askyesno(title = "Configure Server IP", message = "Are you sure?")
if confirm >0:
#In the case that the user says yes
IpConfigNew()
else:
return
#Create menu bar
filemenu.add_command(label="Configure IP", command = PromptIpReconfig)
filemenu.add_command(label="Quit", command=app.destroy)
menubar.add_cascade(label='Options',menu = filemenu)
app.mainloop()
I am pretty sure the problem is the function IpConfigNew as this seems to work:
from Tkinter import *
import tkMessageBox
import os
#Creates new window
IpConfig = Tk()
IpNew = StringVar()
Label(IpConfig, font = ('Helvetica',12), text = 'Please enter the IP address of the server', bg = 'white').place(x=0,y=4)
#Creates box for user to type IP in.
Entry(IpConfig,textvariable=IpNew, bg = "light blue").place(x=4,y=35)
#Store New Ip NOTE that it is nested within IpConfigNew
def IpStore():
#Retrieves new IP from text box and stores it in variable
GetIpNew = IpNew.get()
mypath = str('Latest Server')
#Creates directory to write new IP to.
if not os.path.isdir(mypath):
os.makedirs(mypath)
StoreLatestServer = open('Latest Server\NewIp.txt', 'w')
#Writes new IP
StoreLatestServer.write("%s"%(GetIpNew))
StoreLatestServer.close()
IpConfig.destroy()#Closes window
#Calls on function IpStore in order to store the new IP
Button(IpConfig,text = 'Done', command = IpStore).place(x=150,y=30)
IpConfig.mainloop()
This should give you guys a much clearer understanding of what I am dealing with. Thanks
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.