Lets say I have two python files. Both with an GUI. First is "Main" second is "Calculator". From Main I will start Calculator. So I have to import calculator. In Calculator I will do a calculation. Lets keep I easy an say 1+1=2. Now I want to "send" this Result to an Text in Main.
How do I do that without an circular import? I cant find an good tutorial/example for that!
My code so far:
Main:
from tkinter import *
import Test_2
window = Tk()
window.title("First Window")
def start():
Test_2.start_second()
Input1 = Entry(window)
Input1.grid(row=0,column=0, padx=10, pady=5)
Start = Button(window,text="Start", command=start)
Start.grid(row=1,column=0, padx=10, pady=5)
window.mainloop()
Second:
from tkinter import *
def start_second():
window2 = Tk()
window2.title("Second Window")
def send():
x = Input.get()
Input2 = Entry(window2)
Input2.grid(row=0,column=0, padx=10, pady=5)
Send = Button(window2,text="Send", command=send)
Send.grid(row=1,column=0, padx=10, pady=5)
window2.mainloop()
This code does exactly what you asked for (as opposed to what I suggested in the comment; but anyway, you either get a value from a module function or you send a reference for it to alter)
I tried to follow your structure.
Basically it is a matter of sending the parent window and the first entry as parameters to the second window creation function. Don't call mainloop two times, just once in the end, and use Toplevel for all other windows after the main Tk one. This is not to say that I like the use of an inner function and of the lambda, for readability, but lambdas are necessary in tkinter everytime you want to send parameters to a command callback, otherwise it will get called right way in command definition.
tkinter_w1.py (your main.py)
from tkinter import Tk, ttk
import tkinter as tk
from tkinter_w2 import open_window_2
root = Tk()
entry1 = ttk.Entry(root)
button1 = ttk.Button(root, text='Open Window 2',
command=lambda parent=root, entry=entry1:open_window_2(parent, entry))
entry1.pack()
button1.pack()
root.mainloop()
tkinter_w2.py (your Test_2.py)
from tkinter import Tk, ttk, Toplevel
import tkinter as tk
def open_window_2(parent, entry):
def send():
entry.delete(0,tk.END)
entry.insert(0,entry2.get())
window2 = Toplevel(parent)
entry2 = ttk.Entry(window2)
button2 = ttk.Button(window2, text='Send', command=send)
entry2.pack()
button2.pack()
Related
import tkinter as tk
from subprocess import check_call
def copy_name():
cmd = 'echo ' + name.strip() + '|clip'
return check_call(cmd, shell=True)
root = tk.Toplevel(background="black")
root.title("Copying")
root.resizable(False, False)
T = tk.Label(root, text=name, height=2, width=len(name) + 25, background="black", foreground="white")
T.pack()
button = tk.Button(root, text="Copy", command=copy_name, background="black", foreground="white")
button.pack()
tk.mainloop()
This is my code.
I just wanted to test this way of copying text...
About my expectations... i want to understand from where those windows are appearing, and how to stop it.
Im just a newbie in Python and Tkinter... so please, tell me what i did wrong
You are not using Toplevel(). You just wanted single window. Just replaced Toplevel to tk()
Code:
import tkinter as tk
from subprocess import check_call
def copy_name():
cmd = 'echo ' + name.strip() + '|clip'
return check_call(cmd, shell=True)
root = tk.Tk()
root.title("Copying")
root.resizable(False, False)
T = tk.Label(root, text='name', height=2, width=25, background="black", foreground="white")
T.pack()
button = tk.Button(root, text="Copy", command=copy_name, background="black", foreground="white")
button.pack()
tk.mainloop()
Screenshot:
Every tkinter window requires a root window - an instance of Tk. If you don't create one, one will be created automatically. When you do root = tk.Toplevel(background="black"), tkinter will first create an instance of Tk and then it will create your Toplevel, resulting in two windows.
The solution in this case is to call Tk instead of Toplevel. Also, you'll need to remove the background="black" argument and instead configure the background in a separate step.
root = tk.Tk()
root.configure(background="black")
As #Bryan said, you should forget about Toplevel(). The normal way is Tk().
Try this:
import tkinter as tk
import tkinter.ttk as ttk
root = tk.Tk()
label = tk.Label( root, text='Select:', background='green').pack(side='top')
btn1 = ttk.Button( root, text='Discard').pack()
btn2 = ttk.Button( root, text='Quit').pack()
while True:
root.mainloop()
And you should get:
I wonder if someone could tell me if its possible to update toplevel windows using external functions. I've replicated my issue below what I need to do is update the Toplevel(master) using the function updatelabel(). I have used similar external function to update items in root which works like a dream. However, with the top level window I always get the
NameError: name 'newWindow' is not defined
The only work around I found was to kill the newWindow using newWindow.destroy() on each load but this method makes the screen pop up and then close again which doesn't look pretty. Any help most welcome thanks.
from tkinter import *
from tkinter.ttk import *
master = Tk()
master.geometry("200x200")
def updatelabel():
Label(newWindow,
text="I changed").pack()
def openNewWindow():
# Toplevel object which will
# be treated as a new window
newWindow = Toplevel(master)
# sets the title of the
# Toplevel widget
newWindow.title("New Window")
# sets the geometry of toplevel
newWindow.geometry("200x200")
# A Label widget to show in toplevel
Label(newWindow,
text="I want to change").pack()
button1 = Button(newWindow,
text="Click me to change label", command=updatelabel).pack()
btn = Button(master,
text="open a new window",
command=openNewWindow)
btn.pack(pady=10)
mainloop()
Your “newWindow” is defined in your “openNewWindow” function and so it basically only exists in there, you could probably fix this by either defining “newWindow” outside of the function, or by using it as an argument(just add it to the brackets and give it a name in the function itself’s brackets) calling “updateLabel”
I think this should work, though I haven’t worked with tkinter in a bit so don’t blame me if it doesn’t
from tkinter import *
from tkinter.ttk import *
master = Tk()
master.geometry("200x200")
def updatelabel(newWindow):
Label(newWindow,
text="I changed").pack()
def openNewWindow():
# Toplevel object which will
# be treated as a new window
newWindow = Toplevel(master)
# sets the title of the
# Toplevel widget
newWindow.title("New Window")
# sets the geometry of toplevel
newWindow.geometry("200x200")
# A Label widget to show in toplevel
Label(newWindow,
text="I want to change").pack()
button1 = Button(newWindow,
text="Click me to change label", command= lambda: updatelabel(newWindow)).pack()
btn = Button(master,
text="open a new window",
command=openNewWindow)
btn.pack(pady=10)
mainloop()
I'm creating a tkinter gui that I would like to run. This app will do some house cleaning of sorts. It would check files, check for updates, give the user some information etc. Then I would like it to start another tkinter application and then close it self.
import tkinter as tk
import os
def StartProgram():
os.startfile("C:/WINDOWS/system32/notepad.exe")
root = tk.Tk()
frame = tk.Frame(root)
frame.pack()
button = tk.Button(frame, text="QUIT", fg="red", command= lambda: quit())
button.pack( side=tk.LEFT)
button2 = tk.Button(frame,text="Start my exe", command=lambda: StartProgram())
button2.pack(side=tk.LEFT)
root.maxsize(200,200)
root.minsize(200,200)
root.mainloop()
The problem I have so far is when I attempt to close the original app it closes the one it started as well.
EDIT: I also tried root.destroy(), root.quit()
Any suggestion how I might correct this?
filename p1.py
import tkinter as tk
def action():
import p2
root=tk.Tk()
root.title('part1')
root.geometry('200x200+50+50')
btn=tk.Button(root,text='click me',command=action)
btn.pack()
root.mainloop()
filename p2.py
After closing this window, I want to reopen it on clicking the click me button but it does not open once I close this window.
import tkinter as tk
root=tk.Toplevel()
root.title('part2')
root.geometry('200x200+50+50')
lbl=tk.Label(root,text='Hello everybody \n I have problem',font=("times new roman",20,'bold'))
lbl.pack()
root.mainloop()
Here's a solution for you:
Module_one:
import tkinter as tk
def action():
import action_module
action_module.page_two()
root = tk.Tk()
root.title('part1')
root.geometry('200x200+50+50')
btn = tk.Button(root, text='click me', command=action)
btn.pack()
root.mainloop()
action_module:
def page_two():
import tkinter as tk
root = tk.Toplevel()
root.title('part2')
root.geometry('200x200+50+50')
lbl = tk.Label(root, text='Hello everybody \n I think the problem is fixed',
font=("times new roman", 20, 'bold'))
lbl.pack()
root.mainloop()
Just put the code in the second module inside a function. Then call it inside the first file's action function.
Is there any way to put the textvariable in another variable and not have to use the ".get()"? I've been doing a lot of sifting thorugh tutorials and articles for what I realize is a very small issue but I'm probably misunderstanding something pretty key so i'm hoping someone can help me develop some intuition for the entry widget and .get() method.
Below is part of a script that I've been working on where I want to take the text entered in the entry box and use it later. I can use it if I use search_word.get(), but I don't why I can't do something like New_variable=search_word.get() so that from that point on I can just use "New_variable".
import tkinter as tk
from tkinter import *
from tkinter import ttk
Text_input_window = Tk()
Text_input_window.geometry('600x350+100+200')
Text_input_window.title("Test")
label_1=ttk.Label(Text_input_window, text="Enter word to search:", background="black", foreground="white")
label_1.grid(row=1, column=0, sticky=W)
search_word=StringVar()
entry_1=ttk.Entry(Text_input_window,textvariable=search_word, width=40, background="white")
entry_1.grid(row=2, column=0, sticky=W)
New_variable=StringVar()
New_variable=search_word.get()
def click():
print(New_variable)
print(search_word.get())
Text_input_window.destroy()
btn_1=ttk.Button(Text_input_window, text="submit", width=10, command=click)
btn_1.grid(row=3, column=0, sticky=W)
Text_input_window.mainloop()
Problem is not .get() but how all GUIs works.
mainloop() starts program so new_variable = search_word.get() is executed before you even see window - so it tries to get text before you put text in Entry.
You have to do it inside click() which is executed after you put text in entry and click button.
import tkinter as tk
# --- functions ---
def click():
global new_variable # inform function to use external/global variable instead of creating local one
#new_variable = entry.get() # you can get it directly from `Entry` without StringVar()
new_variable = search_word.get()
root.destroy()
# --- main ---
new_variable = '' # create global variable with default value
root = tk.Tk()
search_word = tk.StringVar()
entry = tk.Entry(root, textvariable=search_word)
entry.pack()
btn = tk.Button(root, text="submit", command=click)
btn.pack()
root.mainloop() # start program
# --- after closing window ---
print('new_variable:', new_variable)
print('search_word:', search_word.get()) # it seems it still exists
# print('entry:', entry.get()) # `Entry` doesn't exists after closing window so it gives error
Is there any way to put the textvariable in another variable and not have to use the ".get()"?
No, there is not. Tkinter variables are objects, not values. Anytime you want to use a value from a tkinter variable (StringVar, IntVar, etc) you must call the get method.