web-dev-qa-db-ja.com

Python tkinter?で子ウィンドウを作成するにはどうすればよいですか?

Python 3.3とtkinterを使用して、歩行者の逃亡シミュレーション用のGUIインターフェースを作成しています。

2つのシミュレーションプログラムを作成しましたが、うまく機能しました。しかし、メインアプリケーションからそれらを呼び出そうとすると、行き詰まりました。シミュレーションウィンドウを別のウィンドウに表示する(メインウィンドウの子ウィンドウを作成する)。

#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()

メインアプリケーションからtkinterで子ウィンドウを起動するにはどうすればよいですか?

10
Chenxiao

子ウィンドウを作成するには、Toplevelのインスタンスを作成します。詳細については、 http://effbot.org/tkinterbook/toplevel.htm を参照してください。

ボタンをクリックして新しいウィンドウを作成できる例を次に示します。

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()
41
Bryan Oakley