简体   繁体   中英

How to pass a class with Toplevel widget in Tkinter

在此处输入图像描述

I have a readymade game( 2048 ), where the game starts without a welcome window, so, I have just made a welcome window with a bunch of buttons like New Game and AI mode, now when I click the New Game button, I expect to get a new window where the game can be played. However, the game displays at the bottom of the main window, and another window that is supposed to display the actual game displays nothing.

# mainwindow.py file:
from tkinter import *
from PIL import ImageTk, Image
import game_2048
 
root = Tk()
 
root.iconbitmap('unnamed.ico')
root.title('2048')
 
 
bg = ImageTk.PhotoImage(Image.open("welcome.png"))
 
my_canvas = Canvas(root, width=780, height=550)
my_canvas.grid()
 
my_canvas.create_image(0, 0, image=bg, anchor=NW)
 
button1 = Button(root, text="New Game", fg="black", bg="#ddf0d0", padx=3,
                 pady=3, font=('Helvetica', '12', 'bold'), activebackground="#94d3c3", command=lambda: game_2048.mains(root)
                 )
button2 = Button(root, text="AI Mode", fg="black", bg="#ddf0d0",
                 padx=3, pady=3, font=('Helveica', '12', 'bold'), activebackground="#94d3c3")
 
button1_window = my_canvas.create_window(10, 10, anchor=NW, window=button1)
button2_window = my_canvas.create_window(120, 10, anchor=NW, window=button2)

root.mainloop()

And I have tried to modify the game_2048 file ie 2048 game like this:

def mains(root):
    Top = Toplevel(root)
    l1 = Button(Top, command=lambda:Game())
    l1.pack()
 
 
class Game(tkinter.Frame):
    def __init__(self):
        tkinter.Frame.__init__(self)
        self.grid()
        self.master.title('2048')
 
        self.main_grid = tkinter.Frame(
            self, bg=c.GRID_COLOR, bd=3, width=400, height=400)
        self.main_grid.grid(pady=(80, 0))
        self.make_GUI()
        self.start_game()
 
        self.master.bind("<Left>", self.left)
        self.master.bind("<Right>", self.right)
        self.master.bind("<Up>", self.up)
        self.master.bind("<Down>", self.down)
 
        self.mainloop()
 
if __name__ == "__main__":
    mains()

I am pretty sure that I have made some mistakes in the mains() function as a result of which I am not getting the desired output. So my question is what should I do to rectify these mistakes?

Here are the changes I made to your code:

  • Removed import mainwindow from game_2048.py , as it will lead to circular import calling the functions twice.

  • You created a class inheriting from a Frame , this frame is just like any other tkinter widget, requires to be placed in the window using geometric manager, like pack() / grid() / place() , you did not do that

  • I also destroyed the root window before creating another new root window. Also note that instead of using Toplevel , I used Tk . This is done, so that closing the game window will close the app. But if using Toplevel , you will have to close the menu window too.

from tkinter import *
import tkinter
import random
import colors as c

def mains(root):
    root.destroy()
    root = Tk()
    
    def init(root):
        l1.destroy()
        game = Game(root)
        game.pack()

    l1 = Button(root, text='Start Game',command=lambda: init(root))
    l1.pack()

class Game(tkinter.Frame):
    def __init__(self, parent):
        tkinter.Frame.__init__(self, parent)
        .......

But if you were to ask me, I would not go for such structure, but this will work here too. Understand this, work on it, implement your own structure that does not call more than one Tk() .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM