Smith Jr
Smith Jr

Reputation: 59

Pygame GUI - Not Loading

Basically I have created a pygame menu for my game and it will load all other pygame windows when I click on them, however for some aspects like adding a user and so on,
I created in a Tkinter GUI. When I click to load them on my pygame it won't load the Tkinter GUI, does anyone know how I can solve this or if there's something I need to add in to make it work.

It acts as if its going to load something but doesn't, the first one called "mathsvaders" loads fine as it a pygame program, but the high-score is in tkinter and doesn't load:

...
pos = 1
while True:
    #events
    for e in pygame.event.get():
        if e.type == pygame.QUIT:
            pygame.quit()
            sys.exit()
        elif e.type == pygame.KEYDOWN:
            if e.key == pygame.K_DOWN:
               pos += 1
               if pos > 5:
                   pos = 1
            elif e.key == pygame.K_UP:
               pos -= 1
               if pos < 1:
                   pos = 5
            elif e.key == pygame.K_RETURN:
               if pos == 1:
                   import MathsvadersReal
            elif e.key == pygame.K_RETURN:
               if pos == 2:
                    import Highscore
            elif pos == 5:
                 pygame.quit()
                 sys.exit()

The code for the form is as follows:

import Tkinter import Databaseconnector

class simpleapp_tk(Tkinter.Tk):
    def __init__(self,parent):
        Tkinter.Tk.__init__(self,parent)
        self.parent = parent
        self.initialize()

    def initialize(self):
        def create_widgets(self):
            # create welcome label
            label1 = Tkinter.Label(self, text = "Hello world")
            label1.grid(row = 0, column = 2, columnspan = 4, sticky = 'E')

if __name__ == "__main__":
    app = simpleapp_tk(None)
    app.title('my application')
    app.geometry("250x200")
    app.mainloop()    

Upvotes: 0

Views: 1047

Answers (1)

abarnert
abarnert

Reputation: 365657

When you import the second module, you're not doing the if __name__ == "__main__": part. (That's the whole point of that idiom—to provide code that runs when you're the top-level script, but not when you're imported.) So, you never create the Tk app and main event loop, meaning no Tk code can do anything, and your GUI never gets displayed.

But before you try to fix this by just moving that code into a function and calling it, you can't just call the tkinter main event loop from the pygame one, because then the pygame loop will be blocked until the tkinter app exits.

I think your confusion here is that you're mixing up modules and scripts and processes and a bunch of other things and calling them all "programs". See below for a primer on the differences.

If you really want to do this, there are a few possibilities:

  • pygame can work with any event loop you want, as long as you hook things up right. Which means you can create a top-level tkinter app and run the pygame code under that.
  • You can keep your existing pygame loop, and run the tkinter loop in another thread.
  • Recode your tkinter stuff in one of the pygame GUI toolkits instead.
  • If you actually want to treat each module as "running a program", as you say in your description, actually do that: use subprocess to launch sys.executable with the other script as its first argument.

The same Python file like highscore.py can be run as a script, or imported as a module. These are similar in some ways, and different in others.

You run it as a script by, e.g., typing python highscore.py at your DOS/bash/whatever shell (or by using something like subprocess.Popen(sys.executable, 'highscore.py') from within another program). This starts up a new process, running the Python interpreter, which executes the code from highscore.py, and then quits. This doesn't affect any other processes, because your OS knows how to run separate processes at the same time. While the highscore.py code is being executed, __name__ is set to "__main__".

You import it as a module by doing an import highscore from within a running Python program. This does not start up a new process, it just executes the code from highscore.py in the middle of the existing Python program, and then goes on to the next line. While the highscore.py code is being executed, __name__ is set to "highscore".

Either way, all of the top-level module code will be executed, including defining classes and functions, as well as any other statements you write. You use the if __name__ == "__main__": check to have extra code that gets executed when your file is run as a script, but not when it's imported as a module.


It's also worth pointing something out. You have this in your code:

 elif e.key == pygame.K_RETURN:
    if pos == 1:
         import MathsvadersReal
    elif e.key == pygame.K_RETURN:
     if pos == 2:
        import Highscore
    elif pos == 5:
     pygame.quit()
     sys.exit()

If this is your real indentation, the elif e.key == pygame.K_RETURN will always be True, so it's unnecessary, and there's no way you can get to the elif pos == 5:, so there's no way to quit.

Upvotes: 3

Related Questions