Tkinter new windows won't close properly - python

I want my GUI to have a 'new window' option that will be just the same as the first one.
The problem is that it also has an exit(quit) button that won't work as it should - whenever I open the new window and then press the button, in the first click nothing happens and in the second one it closes both windows (if 3 windows are open so it'll close everything in the third click and so on).
This the relevant code:
from Tkinter import *
from ttk import *
class Application(Tk):
def __init__(self):
self.root = Tk()
self.root.geometry("250x150")
self.app = Frame(self.root)
self.app.grid()
self.create_menu()
self.create_widgets()
self.root.mainloop()
def create_menu(self):
menu = Menu(self.root)
self.root.config(menu=menu)
sub_menu = Menu(menu)
menu.add_cascade(label="File", menu=sub_menu)
sub_menu.add_command(label="New", command=self.__init__)
sub_menu.add_command(label="Run", command=self.enter)
sub_menu.add_separator()
sub_menu.add_command(label="Exit", command=self.app.quit)
I also tried to change:
sub_menu.add_command(label="New", command=self.__init__)
to:
sub_menu.add_command(label="New", command=self.new window)
Where:
def new_window(self):
class App(Application):
Application.__init__(self)
Both do the same thing.
How can I fix it?

In a Tkinter-Application there may only be one Tk-object. If the object is destroyed or destroyed by the garbage collector, Tkinter will be disabled. Use Toplevel for other other windows instead.
Try this instead:
from Tkinter import *
from ttk import *
class Application(object):
def __init__(self, master):
self.root = master
self.root.geometry("250x150")
self.app = Frame(self.root)
self.app.grid()
self.create_menu()
self.create_widgets()
def create_menu(self):
menu = Menu(self.root)
self.root.config(menu=menu)
sub_menu = Menu(menu)
menu.add_cascade(label="File", menu=sub_menu)
sub_menu.add_command(label="New", command=self.new)
sub_menu.add_command(label="Run", command=self.enter)
sub_menu.add_separator()
sub_menu.add_command(label="Exit", command=self.quit)
def new(self):
window = Toplevel(tk)
return Application(window)
def quit(self):
tk.destroy()
tk = Tk()
Application(tk)
tk.mainloop()

Related

Tkinter Get Text entry in Notebook page

I have created a notebook and added a frame to it:
nb = ttk.Notebook(root, style="TNotebook")
page1 = ttk.Frame(nb, style='Frame1.TFrame')
layout1(page1)
nb.add(page1, text='Welcome')
So i have a function layout1, the first page of the notebook,
i added to it a Text:
def layout1(page):
entry = Text(page, width=20)
entry.place(relx=0.03, rely=0.1, height=400)
Button(page, text='EXECUTE', command=import_entry).place(relx=0.5, rely=0.6)
And next i have my import_entry function:
def import_entry():
result = entry.get()
print(result)
I can't get the entry because of accessibilty of variables in function. So, how can i get it?
Here is an example of how you should structure your app with a class:
import tkinter
import tkinter.ttk as ttk
class App(tkinter.Tk):
def __init__(self):
super().__init__()
# assign on_closing method to window close event
self.protocol("WM_DELETE_WINDOW", self.on_closing)
self.title("Example App")
self.geometry("600x500")
self.button_1 = tkinter.Button(master=self, text="Test", command=self.button_event)
self.button_1.pack(pady=10)
# create more widgets ...
def button_event(self, event):
print("button pressed")
def on_closing(self):
# code that needs to happen when gets closed
self.destroy() # controlled closing of window with .destroy()
if __name__ == "__main__":
app = App()
app.mainloop()

Why does adding a custom menu break keyboard event binding in Python3/tkinter?

In the following code, when I press the button to add some secondary windows, and then try to close a window by using "Command-w" it does not always close the active window. But if I disable the menu creation by commenting the line self.gerar_menu(), windows are opened and closed as expected (I mean, by clicking the red 'x' button or by pressing Command-W in OS X). Any idea about what is wrong here?
Here is my current test code:
#!/usr/bin/env python3.6
# encoding: utf-8
import tkinter as tk
import tkinter.font
from tkinter import ttk
class baseApp(ttk.Frame):
"""
Parent classe for main app window (will include some aditional methods and properties).
"""
def __init__(self, master, *args, **kwargs):
super().__init__(master, *args, **kwargs)
self.master = master
self.mainframe = ttk.Frame(master)
self.mainframe.pack()
class App(baseApp):
""" Base class for the main application window """
def __init__(self, master, *args, **kwargs):
super().__init__(master, *args, **kwargs)
self.master = master
#self.gerar_menu() # This line breaks "Command-w" functionality
self.lbl_text = ttk.Label(self.mainframe, text="This is the Main Window")
self.lbl_text.pack()
self.btn = ttk.Button(self.mainframe, text="Open Second window",
command=lambda: self.create_detail_window(self, number=0))
self.btn.pack()
self.newDetailsWindow = {}
self.windows_count=0
def gerar_menu(self):
""" generate the application menu """
self.menu = tk.Menu(root)
root.config(menu=self.menu)
self.fileMenu = tk.Menu(self.menu)
self.menu.add_cascade(label="File", menu=self.fileMenu)
self.fileMenu.add_command(label="New Document", command=None, accelerator="Command+n")
def create_detail_window(self, *event, number=None):
self.windows_count += 1
self.newDetailsWindow[self.windows_count]=tk.Toplevel()
self.newDetailsWindow[self.windows_count].geometry('900x600+80+130')
self.newDetailsWindow[self.windows_count].title(f'Detail: {self.windows_count}')
self.newDetailsWindow[self.windows_count].wm_protocol("WM_DELETE_WINDOW", self.newDetailsWindow[self.windows_count].destroy)
self.newDetailsWindow[self.windows_count].bind("Command-w", lambda event: self.newDetailsWindow[-1].destroy())
self.detail_window = detailWindow(self.newDetailsWindow[self.windows_count], self.windows_count)
self.newDetailsWindow[self.windows_count].focus()
print(self.newDetailsWindow)
class detailWindow(ttk.Frame):
""" Base class for secondary windows """
def __init__(self, master, rep_num, *args,**kwargs):
super().__init__(master,*args,**kwargs)
self.num_rep = rep_num
self.master.minsize(900, 600)
self.master.maxsize(900, 600)
print(f"Showing details about nr. {self.num_rep}")
self.mainframe = ttk.Frame(master)
self.mainframe.pack()
self.lbl_text = ttk.Label(self.mainframe,
text=f"Showing details about nr. {self.num_rep}")
self.lbl_text.pack()
if __name__ == "__main__":
root = tk.Tk()
janela_principal = App(root)
root.title('Main Window')
root.bind_all("<Mod2-q>", exit)
root.mainloop()
If you want to create a binding for closing a window, you need the function to act upon the actual window that received the event. Your code is always deleting the last window that was opened no matter which window received the event.
The first step is to bind to a function rather than using lambda. While lambda has its uses, binding to a named function is much easier to debug and maintain.
Once the function is called, the event object can tell you which window got the event via the widget attribute of the event object. Given this window, you can get the toplevel window that this window is in (or itself, if it's a toplevel window) via the winfo_toplevel command.
For example:
window = tk.Toplevel(...)
...
window.bind("<Command-w>", self.destroy_window)
...
def destroy_window(self, event):
window = event.widget.winfo_toplevel()
window.destroy()

How do I create child windows with Python tkinter?

I am using Python 3.3 and tkinter to make a GUI interface for a pedestrian fleeing simulation.
I've written two simulation programs, and they worked well. However,I got stuck when trying to call them from my main application. I want the simulation window to appear in a separate window (create a child window of the main window).
#flee_GUI.py
#!/usr/bin/env python
import tkinter
class MenuBar(tkinter.Menu):
def __init__(self,parent):
tkinter.Menu.__init__(self,parent)
###File###
fileMenu = tkinter.Menu(self, tearoff=False)
self.add_cascade(label="File",underline=0, menu=fileMenu)
fileMenu.add_command(label='Open',underline=1)
fileMenu.add_separator()
fileMenu.add_command(label="Exit", underline=1, command=self.quit)
###Run###
runMenu=tkinter.Menu(self,tearoff=False)
self.add_cascade(label='Run',underline=1,menu=runMenu)
runMenu.add_command(label='Open Bounary Model',underline=1,command=runModel1)
class Frame(tkinter.Tk):
def __init__(self,parent):
tkinter.Frame.__init__(self,parent)
self.parent=parent
def runModel1():
from drawcanvas_Alpha_7_0_open_border import cell
I=cell(None)
class App(tkinter.Tk):
def __init__(self,parent):
tkinter.Tk.__init__(self,parent)
self.parent=parent
runModel1()
menubar=MenuBar(self)
self.config(menu=menubar)
if __name__=='__main__':
app=App(None)
app.mainloop()
#drawcanvas_Alpha_7_0_open_border.py
#!/usr/bin/env python
# -*- coding:utf-8 -*-
#Run this by python3.x.
#If you are using Python2.x,be aware of the difference such as print,Tkinter and tkinter,etc.
#from tkinter import *
import tkinter
import random
#class cell(Frame):
class cell(tkinter.Tk):
def __init__(self,parent):
tkinter.Tk.__init__(self,parent)
self.parent=parent
self.channel_length=40#aisle length (1 unit for 10 pixel)
self.channel_width=40#aisle width
self.origin_x=0
self.origin_y=0
self.pixel_unit=10
self.speed=100
self.alltime=0
self.PN=100#Number of pedestrian
self.Pu=0.1
self.Pd=0.9#probability of going down if the right side were occupied
self.window_width=self.origin_x+self.channel_length*self.pixel_unit
self.window_height=self.origin_y+self.channel_width*self.pixel_unit+2*self.pixel_unit
self.canvas=tkinter.Canvas(
self.parent,width=self.window_width,height=self.window_height,bg='lightblue')
self.Ped_x=[]
self.Ped_y=[]
self.block_flag=[]
self.block_occupy=[]
self.draw_canvas()
self.draw_grid()
self.draw_architecture()
self.draw_pedestrian_init()
self.draw_pedestrian()
def draw_canvas(self):
self.canvas.pack()
def destroy_canvas(self):
self.canvas.destroy()
def destroy_architecture(self):
pass
def draw_grid(self):
for i in range(2,self.channel_width+1):
self.draw_line(0,i,self.channel_length,i)
for i in range(1,self.channel_length):
self.draw_line(i,0,i,self.channel_width+1)
def draw_line(self,x0,y0,x1,y1,linedash=1):
self.canvas.create_line(
self.origin_x+x0*self.pixel_unit,
self.origin_y+y0*self.pixel_unit,
self.origin_x+x1*self.pixel_unit,
self.origin_y+y1*self.pixel_unit,dash=linedash)
def draw(self,x0,y0,x1,y1,color='black'):
self.canvas.create_rectangle(
self.origin_x+x0*self.pixel_unit,
self.origin_y+y0*self.pixel_unit,
self.origin_x+x1*self.pixel_unit,
self.origin_y+y1*self.pixel_unit,
fill=color)
for i in range(y0,y1):
for j in range(x0,x1):
self.block_occupy[i][j]=1
#print(j,i)
def draw_architecture(self):
for i in range(0,(self.channel_width+1)+1):
self.block_occupy.append([])
for j in range(0,self.channel_length):
self.block_occupy[i].append(0)
self.draw(0,0,self.channel_length,1)
self.draw(0,self.channel_width+1,self.channel_length,self.channel_width+2)
self.draw(30,1,31,int(self.channel_width/2-1),'red')
#self.draw(30,int(self.channel_width/2+1),31,self.channel_width+1,'red')
def draw_pedestrian_init(self):
Ped_count=0
while Ped_count<self.PN:
self.Ped_x.append(
int(random.randrange(
self.origin_x,self.origin_x+30*self.pixel_unit)/self.pixel_unit)*self.pixel_unit)
self.Ped_y.append(
int(random.randrange(
self.origin_y+self.pixel_unit,self.origin_y+(self.channel_width+1)*self.pixel_unit)/self.pixel_unit)*self.pixel_unit)
tmp_x=int((self.Ped_x[Ped_count]-self.origin_x)/self.pixel_unit)
tmp_y=int((self.Ped_y[Ped_count]-self.origin_y)/self.pixel_unit)
if self.block_occupy[tmp_y][tmp_x]==1:
self.Ped_x.pop()
self.Ped_y.pop()
else:
self.block_occupy[tmp_y][tmp_x]=1
Ped_count=Ped_count+1
self.block_flag=[self.canvas.create_rectangle(self.Ped_x[i],self.Ped_y[i],
self.Ped_x[i]+self.pixel_unit,self.Ped_y[i]+self.pixel_unit,fill='green') for i in range(0,self.PN)]
def draw_pedestrian(self):
for i in range(0,self.PN):
self.canvas.delete(self.block_flag[i])
#print(self.block_occupy)
#count_f=self.PN
for i in range(0,self.PN):
if self.Ped_x[i]>self.origin_x+(self.channel_length-1)*self.pixel_unit-1:
#self.Ped_x[i]=self.Ped_x[i]-self.channel_length*self.pixel_unit
dummy_x=int((self.Ped_x[i]-self.origin_x)/self.pixel_unit)
dummy_y=int((self.Ped_y[i]-self.origin_y)/self.pixel_unit)
self.block_occupy[dummy_y][dummy_x]=0
#count_f=self.PN-1
self.Ped_x[i]=-1
self.Ped_y[i]=-1
temp_block_flag1=[]
temp_block_flag2=[]
for i in range(0,self.PN):
if self.Ped_x[i]!=-1:
temp_block_flag1.append(self.block_flag[i])
else:
temp_block_flag2.append(self.block_flag[i])
self.block_flag=temp_block_flag1
for i in range(0,len(temp_block_flag2)):
self.canvas.delete(temp_block_flag2[i])
self.Ped_x=[self.Ped_x[i] for i in range(0,self.PN) if self.Ped_x[i]!=-1]
self.Ped_y=[self.Ped_y[i] for i in range(0,self.PN) if self.Ped_y[i]!=-1]
self.PN=len(self.Ped_x)
for i in range(0,self.PN):
print(self.PN,i,len(self.Ped_x))
tmp_x=int((self.Ped_x[i]-self.origin_x)/self.pixel_unit)
tmp_y=int((self.Ped_y[i]-self.origin_y)/self.pixel_unit)
if self.block_occupy[tmp_y][tmp_x+1]==0:
self.block_occupy[tmp_y][tmp_x]=0
self.block_occupy[tmp_y][tmp_x+1]=1
self.Ped_x[i]=self.Ped_x[i]+self.pixel_unit
elif (self.block_occupy[tmp_y+1][tmp_x]==0
and self.block_occupy[tmp_y-1][tmp_x]==0):#The right side is occupied,while the up and down side is free
if random.uniform(0,1)<self.Pd:#go down
self.block_occupy[tmp_y][tmp_x]=0
self.block_occupy[tmp_y+1][tmp_x]=1
self.Ped_y[i]=self.Ped_y[i]+self.pixel_unit
else:#go up
self.block_occupy[tmp_y][tmp_x]=0
self.block_occupy[tmp_y-1][tmp_x]=1
self.Ped_y[i]=self.Ped_y[i]-self.pixel_unit
elif (self.block_occupy[tmp_y+1][tmp_x]==1 #the up side is occupied,while the down side is free
and self.block_occupy[tmp_y-1][tmp_x]==0):
self.block_occupy[tmp_y][tmp_x]=0
self.block_occupy[tmp_y-1][tmp_x]=1
self.Ped_y[i]=self.Ped_y[i]-self.pixel_unit
elif (self.block_occupy[tmp_y+1][tmp_x]==0 #the up side is free,while the down side is occupied
and self.block_occupy[tmp_y-1][tmp_x]==1):
self.block_occupy[tmp_y][tmp_x]=0
self.block_occupy[tmp_y+1][tmp_x]=1
self.Ped_y[i]=self.Ped_y[i]+self.pixel_unit
#print(self.block_occupy)
self.block_flag=[self.canvas.create_rectangle(self.Ped_x[i],self.Ped_y[i],
self.Ped_x[i]+self.pixel_unit,self.Ped_y[i]+self.pixel_unit,fill='green') for i in range(0,self.PN)]
self.alltime+=1
self.after(self.speed,self.draw_pedestrian)
if self.PN==0:
print("Fleeing complete!,total time:",self.alltime)
self.destroy_canvas()
if __name__=='__main__':
Io=cell(None)
Io.mainloop()
How can I launch a child window from my main application with tkinter?
You create child windows by creating instances of Toplevel. See http://effbot.org/tkinterbook/toplevel.htm for more information.
Here's an example that lets you create new windows by clicking on a button:
import Tkinter as tk
class MainWindow(tk.Frame):
counter = 0
def __init__(self, *args, **kwargs):
tk.Frame.__init__(self, *args, **kwargs)
self.button = tk.Button(self, text="Create new window",
command=self.create_window)
self.button.pack(side="top")
def create_window(self):
self.counter += 1
t = tk.Toplevel(self)
t.wm_title("Window #%s" % self.counter)
l = tk.Label(t, text="This is window #%s" % self.counter)
l.pack(side="top", fill="both", expand=True, padx=100, pady=100)
if __name__ == "__main__":
root = tk.Tk()
main = MainWindow(root)
main.pack(side="top", fill="both", expand=True)
root.mainloop()

tkinter app adding a right click context menu?

I have a python-tkinter gui app that I've been trying to find some way to add in some functionality. I was hoping there would be a way to right-click on an item in the app's listbox area and bring up a context menu. Is tkinter able to accomplish this? Would I be better off looking into gtk or some other gui-toolkit?
You would create a Menu instance and write a function that calls
its post() or tk_popup() method.
The tkinter documentation doesn't currently have any information about tk_popup().
Read the Tk documentation for a description, or the source:
library/menu.tcl in the Tcl/Tk source:
::tk_popup --
This procedure pops up a menu and sets things up for traversing
the menu and its submenus.
Arguments:
menu - Name of the menu to be popped up.
x, y - Root coordinates at which to pop up the menu.
entry - Index of a menu entry to center over (x,y).
If omitted or specified as {}, then menu's
upper-left corner goes at (x,y).
tkinter/__init__.py in the Python source:
def tk_popup(self, x, y, entry=""):
"""Post the menu at position X,Y with entry ENTRY."""
self.tk.call('tk_popup', self._w, x, y, entry)
You associate your context menu invoking function with right-click via:
the_widget_clicked_on.bind("<Button-3>", your_function).
However, the number associated with right-click is not the same on every platform.
library/tk.tcl in the Tcl/Tk source:
On Darwin/Aqua, buttons from left to right are 1,3,2.
On Darwin/X11 with recent XQuartz as the X server, they are 1,2,3;
other X servers may differ.
Here is an example I wrote that adds a context menu to a Listbox:
import tkinter # Tkinter -> tkinter in Python 3
class FancyListbox(tkinter.Listbox):
def __init__(self, parent, *args, **kwargs):
tkinter.Listbox.__init__(self, parent, *args, **kwargs)
self.popup_menu = tkinter.Menu(self, tearoff=0)
self.popup_menu.add_command(label="Delete",
command=self.delete_selected)
self.popup_menu.add_command(label="Select All",
command=self.select_all)
self.bind("<Button-3>", self.popup) # Button-2 on Aqua
def popup(self, event):
try:
self.popup_menu.tk_popup(event.x_root, event.y_root, 0)
finally:
self.popup_menu.grab_release()
def delete_selected(self):
for i in self.curselection()[::-1]:
self.delete(i)
def select_all(self):
self.selection_set(0, 'end')
root = tkinter.Tk()
flb = FancyListbox(root, selectmode='multiple')
for n in range(10):
flb.insert('end', n)
flb.pack()
root.mainloop()
The use of grab_release() was observed in an example on effbot.
Its effect might not be the same on all systems.
I made some changes to the conext menu code above in order to adjust my demand and I think it would be useful to share:
Version 1:
import tkinter as tk
from tkinter import ttk
class Main(tk.Frame):
def __init__(self, master):
tk.Frame.__init__(self, master)
master.geometry('500x350')
self.master = master
self.tree = ttk.Treeview(self.master, height=15)
self.tree.pack(fill='x')
self.btn = tk.Button(master, text='click', command=self.clickbtn)
self.btn.pack()
self.aMenu = tk.Menu(master, tearoff=0)
self.aMenu.add_command(label='Delete', command=self.delete)
self.aMenu.add_command(label='Say Hello', command=self.hello)
self.num = 0
# attach popup to treeview widget
self.tree.bind("<Button-3>", self.popup)
def clickbtn(self):
text = 'Hello ' + str(self.num)
self.tree.insert('', 'end', text=text)
self.num += 1
def delete(self):
print(self.tree.focus())
if self.iid:
self.tree.delete(self.iid)
def hello(self):
print ('hello!')
def popup(self, event):
self.iid = self.tree.identify_row(event.y)
if self.iid:
# mouse pointer over item
self.tree.selection_set(self.iid)
self.aMenu.post(event.x_root, event.y_root)
else:
pass
root = tk.Tk()
app=Main(root)
root.mainloop()
Version 2:
import tkinter as tk
from tkinter import ttk
class Main(tk.Frame):
def __init__(self, master):
master.geometry('500x350')
self.master = master
tk.Frame.__init__(self, master)
self.tree = ttk.Treeview(self.master, height=15)
self.tree.pack(fill='x')
self.btn = tk.Button(master, text='click', command=self.clickbtn)
self.btn.pack()
self.rclick = RightClick(self.master)
self.num = 0
# attach popup to treeview widget
self.tree.bind('<Button-3>', self.rclick.popup)
def clickbtn(self):
text = 'Hello ' + str(self.num)
self.tree.insert('', 'end', text=text)
self.num += 1
class RightClick:
def __init__(self, master):
# create a popup menu
self.aMenu = tk.Menu(master, tearoff=0)
self.aMenu.add_command(label='Delete', command=self.delete)
self.aMenu.add_command(label='Say Hello', command=self.hello)
self.tree_item = ''
def delete(self):
if self.tree_item:
app.tree.delete(self.tree_item)
def hello(self):
print ('hello!')
def popup(self, event):
self.aMenu.post(event.x_root, event.y_root)
self.tree_item = app.tree.focus()
root = tk.Tk()
app=Main(root)
root.mainloop()
from tkinter import *
root=Tk()
root.geometry("500x400+200+100")
class Menu_Entry(Entry):
def __init__(self,perant,*args,**kwargs):
Entry.__init__(self,perant,*args,**kwargs)
self.popup_menu=Menu(self,tearoff=0,background='#1c1b1a',fg='white',
activebackground='#534c5c',
activeforeground='Yellow')
self.popup_menu.add_command(label="Cut ",command=self.Cut,
accelerator='Ctrl+V')
self.popup_menu.add_command(label="Copy ",command=self.Copy,compound=LEFT,
accelerator='Ctrl+C')
self.popup_menu.add_command(label="Paste ",command=self.Paste,accelerator='Ctrl+V')
self.popup_menu.add_separator()
self.popup_menu.add_command(label="Select all",command=self.select_all,accelerator="Ctrl+A")
self.popup_menu.add_command(label="Delete",command=self.delete_only,accelerator=" Delete")
self.popup_menu.add_command(label="Delete all",command=self.delete_selected,accelerator="Ctrl+D")
self.bind('<Button-3>',self.popup)
self.bind("<Control-d>",self.delete_selected_with_e1)
self.bind('<App>',self.popup)
self.context_menu = Menu(self, tearoff=0)
self.context_menu.add_command(label="Cut")
self.context_menu.add_command(label="Copy")
self.context_menu.add_command(label="Paste")
def popup(self, event):
try:
self.popup_menu.tk_popup(event.x_root, event.y_root, 0)
finally:
self.popup_menu.grab_release()
def Copy(self):
self.event_generate('<<Copy>>')
def Paste(self):
self.event_generate('<<Paste>>')
def Cut(self):
self.event_generate('<<Cut>>')
def delete_selected_with_e1(self,event):
self.select_range(0, END)
self.focus()
self.event_generate("<Delete>")
def delete_selected(self):
self.select_range(0, END)
self.focus()
self.event_generate("<Delete>")
def delete_only(self):
self.event_generate("<BackSpace>")
def select_all(self):
self.select_range(0, END)
self.focus()
ent=Menu_Entry(root)
ent.pack()
root.mainloop()
Important Caveat:
(Assuming the event argument that contains the coordinates is called "event"): Nothing will happen or be visible when you call tk_popup(...) unless you use "event.x_root" and "event.y_root" as arguments. If you do the obvious of using "event.x" and "event.y", it won't work, even though the names of the coordinates are "x" and "y" and there is no mention of "x_root" and "y_root" anywhere within it.
As for the grab_release(..), it's not necessary, anywhere. "tearoff=0" also isn't necessary, setting it to 1 (which is default), simply adds a dotted line entry to the context menu. If you click on it, it detaches the context menu and makes it its own top-level window with window decorators. tearoff=0 will hide this entry. Moreover, it doesn't matter if you set the menu's master to any specific widget or root, or anything at all.

why do I get a blank tkinter window?

so when i run this code and click the button:
from Tkinter import *
import thread
class App:
def __init__(self, master):
print master
def creatnew():
admin=Tk()
lab=Label(admin,text='Workes')
lab.pack()
admin.minsize(width=250, height=250)
admin.maxsize(width=250, height=250)
admin.configure(bg='light green')
admin.mainloop()
def other():
la=Label(master,text='other')
la.pack()
bu=Button(master,text='clicks',command=lambda: thread.start_new_thread(creatnew,()))
bu.pack()
other()
Admin = Tk()
Admin.minsize(width=650, height=500)
Admin.maxsize(width=650, height=500)
app = App(Admin)
Admin.mainloop()
i get a second tkinter window but its a white blank screen that makes both programs not respond.
any ideas
Don't use threads. It's confusing the Tkinter mainloop. For a second window create a Toplevel window.
Your code with minimal modifications:
from Tkinter import *
# import thread # not needed
class App:
def __init__(self, master):
print master
def creatnew(): # recommend making this an instance method
admin=Toplevel() # changed Tk to Toplevel
lab=Label(admin,text='Workes')
lab.pack()
admin.minsize(width=250, height=250)
admin.maxsize(width=250, height=250)
admin.configure(bg='light green')
# admin.mainloop() # only call mainloop once for the entire app!
def other(): # you don't need define this as a function
la=Label(master,text='other')
la.pack()
bu=Button(master,text='clicks',command=creatnew) # removed lambda+thread
bu.pack()
other() # won't need this if code is not placed in function
Admin = Tk()
Admin.minsize(width=650, height=500)
Admin.maxsize(width=650, height=500)
app = App(Admin)
Admin.mainloop()

Categories

Resources