0

I'm trying to create a little game where when you type in 'inventory' it opens a little window to display your items. However it doesn't work and give me an error every time. This is my code, and the error is below it. If anybody knows how to solve this that would make my day ;)

I am using graphics.py which is a little graphics library that simplifies the use of graphics for python beginners. I am required to use it as this is a school project, also I am running python 3.10.

I am using multithreading as the game takes choices from the player using if statements, and I don't want to copy the inventory code for each choice as that would end the branch.


    from threading import Thread
    from graphics import *
    import time
    choice = ""
    inv_open = False
    open = True
    win = GraphWin("game", 500, 500, )
    input_box = Entry(Point(250,250),30)
    input_box.draw(win).setFill("white")
    
    
    def get_choice():
        global choice
        while True:
            choice = input()
    
    def play_game():
        global choice
        while True:
            if choice == "hi":
                print("hello there")
                choice = ""
    
                while True:
                    if choice == "no":
                        print("why no?")
                        choice = ""
    
                    elif choice == "yes":
                        print("why yes?")
                        choice = ""
    
    def quit_game():
        global choice
        while True:
    
            if choice == "quit game":
                print("quitting game")
                choice = ""
    
    def help():
        global choice
        while open == True:
    
            if choice == "help":
                print("Figure it out stupid")
                choice = ""
    
    def set_inventory():
        global inv_open
        while open == True:
            if choice == "inventory":
                print("opening inventory")
                win_i = GraphWin("inventory", 200, 200)
                win_i.getMouse()
                win_i.close()
                choice = ""
    
    t2 = Thread(target = play_game)
    t3 = Thread(target = quit_game)
    t4 = Thread(target = help)
    t5 = Thread(target = set_inventory)
    
    if __name__ == "__main__":
    
        t2.start()
        t3.start()
        t4.start()
        t5.start()
    
    while open == True:
        win.getMouse()
        choice = input_box.getText()
        input_box.setText("")

Error I get:

Exception in thread Thread-4 (set_inventory):
Traceback (most recent call last):
  File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/threading.py", line 1009, in _bootstrap_inner
    self.run()
  File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/threading.py", line 946, in run
    self._target(*self._args, **self._kwargs)
  File "/Users/PycharmProjects/game/new/mprocessing.py", line 55, in set_inventory
    win_i = GraphWin("inventory", 200, 200)
  File "/Users/PycharmProjects/game/new/graphics.py", line 213, in __init__
    master = tk.Toplevel(_root)
  File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/tkinter/__init__.py", line 2650, in __init__
    BaseWidget.__init__(self, master, 'toplevel', cnf, {}, extra)
  File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/tkinter/__init__.py", line 2601, in __init__
    self.tk.call(
RuntimeError: main thread is not in main loop
JVR
  • 1
  • 2
  • Well the error tells you what's wrong, you cannot create a `GraphWin` instance in a thread that isn't `__main__`. – pstatix May 13 '22 at 17:06
  • Does this answer your question? [RuntimeError: main thread is not in main loop](https://stackoverflow.com/questions/14694408/runtimeerror-main-thread-is-not-in-main-loop) – pstatix May 13 '22 at 17:06
  • @pstatix So what exactly do you reckon I need to do to fix my code? Or will I just not be able to use Graphics and multithreading? – JVR May 14 '22 at 16:43
  • @pstatix If I can't use multithreading, might multiprocessing be able to solve this problem? – JVR May 14 '22 at 16:46
  • My guess is that `GraphWin` attempts to create a new root, a `tkinter.Tk()` instance, which you cannot use in a thread outside of `__main__`. Simply "throwing" multiprocessing at this would, in theory, solve the problem as each process gets its own new main thread, but this is bad design. What you should do is have a single `GraphWin` instance in your main thread, and perhaps solve the issue in an OOD way. – pstatix May 15 '22 at 16:26

0 Answers0