First I have open main window then through that I have another window called order .Now I have to make a button that get to the main window again
def back():
wn.destroy()
import purchase
Button(text="Back",width='30',height='5',command=back,fg='black',bg='green',bd='5',font=(40),command=back).place(x='100',y='600')
You need to make the button start a function to open the window.
Ex.
def OpenNewWindow:
newWindow = TopLevel(master)
B1 = tk.Button(text="example", command = OpenNewWindow
B1.pack()
Treat it like a normal window: geometry, title, etc.
but remember one thing:
KEEP THE TOPLEVEL IN THE MAIN LOOP
Related
I have this application in Python Tkinter. There is a Python file which is a main menu. When I click an option in the main menu it imports a python file with code that makes a new window (couldn't use Toplevel for the new window for some reasons). So when I close the main menu it should close all the other windows.
Here is my code for the main menu:
from tkinter import *
root = Tk()
root.geometry("600x600")
def newWindowImport():
import file1
def newWindowImport2():
import file2
newWindow = Button(text="new window", command=newWindowImport).pack()
newWindow2 = Button(text="new window", command=newWindowImport2).pack()
# Here is there a way so that when I exit it destroys the Main Menu as well as the opened windows
exitBtn = Button(text="Exit", command=root.destroy())
root.mainloop()
I tried the root.destroy method but it only destroys the main menu and not all the windows. Is there a way so that when I exit the main menu it destroys the main menu as well as the opened windows? If I were to use Toplevel - how would I use it in a separate file?
I am assuming that your other scripts have individual instances of Tk(), their own mainloop() and are not under a function, if that is the case, you can have all the code in your files under a function and use Toplevel(), example, file1 should look like
def something():
window=Toplevel()
#Rest of the code
And similarly file2, after that in your main program you could do something like this
from tkinter import *
import file1, file2
root = Tk()
root.geometry("600x600")
def newWindowImport():
file1.something()
def newWindowImport2():
file2.something()
newWindow = Button(text="new window", command=newWindowImport)
newWindow.pack()
newWindow2 = Button(text="new window", command=newWindowImport2)
newWindow2.pack()
# Here is there a way so that when I exit it destroys the Main Menu as well as the opened windows
exitBtn = Button(text="Exit", command=root.destroy)
root.mainloop()
You could also let go of the functions and make these changes to have it shorter
newWindow = Button(text="new window", command=file1.something)
newWindow.pack()
newWindow2 = Button(text="new window", command=file2.something)
newWindow2.pack()
The reason for your approach not working would be that each file had it's own mainloop() and hence they couldn't be destroyed when you called root.destroy in the main code.
Also note that I have removed the parentheses () from the command=root.destroy otherwise the it will be called as soon as the program initializes.
EDIT : As also suggested by #martineau in the comments, it's better to use .pack() on the Button instances separately as it provides more flexibility in using the instance later in the program, as opposed to having them hold the value None which is the return from .pack()
Using Toplevel is the correct way to do this, you need to find out why that is not working and correct it. If you did that this question would solve itself. Also, you need to remove the () from the command, it should be like this:
exitBtn = Button(text="Exit", command=root.destroy)
I'm new using tkinter on python and I would like to develop a program that can Drag and Drop a button pressing other one... I will try to explain : I have button 'A' that will create a new button 'B' and I want to Drag the New button to another place
Any help
Thanks
The tkinter.dnd module, as suggested by j_4321 in comments.
Here is some sample code using that library to do what you have said:
from tkinter import *
from tkinter.dnd import Tester as DragWindow, Icon as Dragable
# Make a root window and hide it, since we don't need it.
root = Tk()
root.withdraw()
# Make the actual main window, which can have dragable objects on.
main = DragWindow(root)
def make_btn():
"""Make a new test button."""
# The functional part of the main window is the canvas.
Dragable('B').attach(main.canvas)
# Make a button and bind it to our button creating function.
Button(main.top, text='A', command=make_btn).pack()
# Start the mainloop.
mainloop()
I got the following code from a tutorial. I then modified main() so that two windows are created as seperate threads. When I run it, only one window is created. Then when I press the Quit button in that window, a second window appears. In this new window the button has a different look than the first one (a look which I like better) and then if I press either of the two Quit buttons, both windows close and the program exits.
Why does the second window not appear until the first Quit button is pressed, and why does it look different when it does appear?
EDIT: This happens when no threads are used as well, where only one window is created at a time.
EDIT: This is a screenshot of the two windows that are created. The one on the left is created with the program is run, the one on the right is created after clicking the "Quit" button on the first.
from Tkinter import Tk, BOTH
from ttk import Frame, Button, Style
class Example(Frame):
def __init__(self, parent):
Frame.__init__(self, parent)
self.parent = parent
self.initUI()
def initUI(self):
self.parent.title("Quit button")
self.style = Style()
self.style.theme_use("default")
self.pack(fill=BOTH, expand=1)
quitButton = Button(self, text="Quit",
command=self.quit)
quitButton.place(x=50, y=50)
from threading import Thread
def main():
for i in range(2):
root = Tk()
root.geometry("250x150+300+300")
app = Example(root)
Thread(target=root.mainloop()).start()
if __name__ == '__main__':
main()
You cannot use tkinter this way. Tkinter isn't thread safe, you can only ever access tk widgets and commands except from the thread that created the root window.
As for one window only showing after the other is destroyed even without threading, it's hard to say since you don't show the code. If you're creating more than one instance of Tk, and calling mainloop more than once, that's the problem. Tkinter is designed to work when you create precisely one instance of Tk, and call mainloop precisely once.
If you want more than one window, create a single instance of Tk for the first window, and instances of Toplevel for additional windows.
Say I have some simple code, like this:
from Tkinter import *
root = Tk()
app = Toplevel(root)
app.mainloop()
This opens two windows: the Toplevel(root) window and the Tk() window.
Is it possible to avoid the Tk() window (root) from opening? If so, how? I only want the toplevel. I want this to happen because I am making a program that will have multiple windows opening, which are all Toplevel's of the root.
Thanks!
The withdraw() method removes the window from the screen.
The iconify() method minimizes the window, or turns it into an icon.
The deiconify() method will redraw the window, and/or activate it.
If you choose withdraw(), make sure you've considered a new way to exit the program before testing.
e.g.
from Tkinter import * # tkinter in Python 3
root = Tk()
root.withdraw()
top = Toplevel(root)
top.protocol("WM_DELETE_WINDOW", root.destroy)
but = Button(top, text='deiconify')
but['command'] = root.deiconify
but.pack()
root.mainloop()
The protocol() method can be used to register a function that will be called when the
Toplevel window's close button is pressed. In this case we can use destroy() to exit.
I have a (second) tkinter window, which, when opened, does not get the focus, but rather the first window remains focused (although the second window appears in front of the other).
It contains a textbox which I want to be able to type in, but I have to double-click it in order to type.
How do I focus the textbox when opening the window?
My tries:
textbox.focus_set(),
window.grab_set(),
window.focus_set()
None of them did what I wanted to do.
EDIT:
Instead, .focus_set() raises an error when (and only when) closing the main window: can't invoke "focus" command: application has been destroyed
This is my current code (tkWin is the main window, tkcWinis the second window):
def click(self, field):
import _tkinter
if field != None:
try:
self.tkcWin = Tk()#creating window
self.tkcWin.focus()
self.tkcWin.title(field)
self.tkcWin.geometry('300x100')
self.mainframe = Frame(master=self.tkcWin,background="#60BF98")
self.mainframe.place(x=0, y=0, width=300, height=300)
self.textb = Text(master=self.mainframe)
self.textb.place(x=0, y=50)
self.textb.bind("<Return>",lambda a: self.setM(field))
self.textb.bind("<Return>",lambda a: self.tkcWin.destroy(),True)
self.tkcWin.grab_set()
self.tkWin.wait_window(self.tkcWin)
self.textb.focus_set()
hwnd = self.tkcWin.winfo_id()
ctypes.windll.user32.SetFocus(hwnd)
self.tkcWin.mainloop()
except _tkinter.TclError:
self.tkcWin.destroy()
It turns out that you can simply call the secondary window's deiconify() method and then the widget's focus_set() method:
toplevel.deiconify()
text.focus_set()
Here's the original work-around for Windows (no longer recommended):
Start by adding import ctypes at the top.
Go ahead and focus your widget like you have with: text.focus_set()
Get the hwnd of the second window: top_hwnd = toplevel.winfo_id()
And finally activate the second window with: ctypes.windll.user32.SetFocus(top_hwnd)