0

enter image description here

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 i.e. 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?

BigPy
  • 127
  • 1
  • 2
  • 9
  • why do You call mainloop when inheriting from Frame? also You are not passing the argument `root` to the `mains` function. btw `Toplevel` doesn't need `mainloop` – Matiiss May 08 '21 at 09:53
  • Hi, are you implying that ```self.mainloop()``` should be removed? I just passed root to the ```mains``` function, also, I did not understand the third part of your comment. Thanks!! – BigPy May 08 '21 at 10:06
  • all that is needed to show `Toplevel` is just calling it like this `Toplevel(parent)` (and passing the parent/master argument), there is no need for `mainloop` for `Toplevel`. `self.mainloop()` is certainly not necessary and I would say it should get removed. mainloop is usually called as `Tk` method, for example `root.mainloop()` also don't do it in this specific class. – Matiiss May 08 '21 at 10:19
  • Hey, I just removed the ```self.mainloop```, I have passed root as the argument, and modified to ```l1 = Button(Top, command=lambda: Game())``` from ```l1 = Button(Top, command=Game())```, yet, the game still appears below the mainwindow and not in the other window that I made using Toplevel. What do you think I should do next? Thanks for your kind help!! – BigPy May 08 '21 at 10:40
  • Does the duplicate marked answer your question – Delrius Euphoria May 08 '21 at 11:42
  • @martineau The OP did ask somewhat same question before and it was marked as same duplicate, I don't think the duplicate is the only problem, could you reopen it. – Delrius Euphoria May 08 '21 at 11:44
  • yes, I rectified that part of the problem, and it looks like @martineau glanced at my question, saw that part where I had missed the lambda, and just shut the question down, it's so frustrating, I have been trying to work this project out for so many days and at the end, it gets shut down without being fully analyzed – BigPy May 08 '21 at 11:51
  • or should I ask the question again and hope it doesn't get shut this time? – BigPy May 08 '21 at 11:51
  • No do not ask a new question, it can get you flagged. Be patient – Delrius Euphoria May 08 '21 at 12:11
  • 1
    What you can try right now is `def __init__(self,parent):` and then `tkinter.Frame.__init__(self,parent)` and then `l1 = Button(Top, command=lambda:Game(Top))` – Delrius Euphoria May 08 '21 at 12:20
  • by parent you mean 'root', right? – BigPy May 08 '21 at 12:27
  • 1
    Define it as `parent`, no It means `Top`. – Delrius Euphoria May 08 '21 at 12:29
  • When I run the code, I get a new window that asks me for New Game or AI mode, without any changes – Delrius Euphoria May 08 '21 at 12:32
  • Hey, @CoolCloud, here is the code: https://github.com/SUSHANT-REGMI/2048, do check this out, if you could help, it would be great!!! – BigPy May 08 '21 at 12:40
  • Tell me what is wrong and what you expect it to become – Delrius Euphoria May 08 '21 at 12:45
  • Okay, 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. – BigPy May 08 '21 at 12:48
  • So, my speculation is that the reason I am not getting the desired output is because the way I modified my mains function inside of the game_2048 is not correct. However, I don't know the correct way. Btw I just added you on facebook – BigPy May 08 '21 at 12:53
  • Okay this game right, when you press the button that is inside `mains` where do you want to show the game, in the same window? Or a separate one. – Delrius Euphoria May 08 '21 at 12:54
  • I want to show it on the separate window – BigPy May 08 '21 at 12:56

1 Answers1

1

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

Delrius Euphoria
  • 14,910
  • 3
  • 15
  • 46