14

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?

1
  • 3
    The example code should be replaced with a minimal complete verifiable example. It's fairly lengthy, and mostly unrelated to the specific issue. Commented Feb 15, 2018 at 16:02

1 Answer 1

48

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()
Sign up to request clarification or add additional context in comments.

5 Comments

can you also plz tell whether we can show or hide this window? meaning is there an alternative to pack and pack_forget for it?
Oh thanks, I have found out the answer for my question from your other post so I decided why not add it to the answer of yours to make it easier for other people who have this problem to get the full basic understanding.
Oh, now I have ran into an error with these functions, -:
_tkinter.TclError: bad window path name ".!toplevel"
Can you plz help

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.