1

I'm trying to build a chess game in pygame. For pawn promotion I settled to use the function "get_piece_name" which opened a tkinter window with buttons to choose the "promotion piece".

What I want is make the tkinter window to appear on top of the pygame one whenever it is on focus; and make the tk win. minimize when the pg win. is.

The script is as follows:

import pygame as pg
import tkinter as tk

def get_piece_name():
    global name
    name = ""

    root = tk.Tk()
    
    def destroy_win(string):
        global name
        name = string
        root.destroy()

    queen_bt = tk.Button(root, text="queen", command=lambda: destroy_win("queen"))
    queen_bt.grid(row=0, column=0)

    rook_bt = tk.Button(root, text="rook", command=lambda: destroy_win("rook"))
    rook_bt.grid(row=0, column=1)

    knight_bt = tk.Button(root, text="knight", command=lambda: destroy_win("knight"))
    knight_bt.grid(row=0, column=2)

    bishop_bt = tk.Button(root, text="bishop", command=lambda: destroy_win("bishop"))
    bishop_bt.grid(row=0, column=3)


    root.attributes('-topmost', True)  ### win. is on top of every other one

    root.mainloop()

    return name


def main():
    pg.init
    pg.font.init()

    WIN = pg.display.set_mode((500, 500))
    WIN.fill((0,0,0))

    running = True
    while running:

        for event in pg.event.get():
            if event.type == pg.QUIT:
                running = False
            
            if event.type == pg.MOUSEBUTTONDOWN and event.button == 1: # left-click on the screen 
                WIN.fill((0,0,0))

                piece_name = get_piece_name()
        
                font = pg.font.SysFont("Heveltica", 50)
                text = font.render(piece_name, True, (0,225,0))

                WIN.blit(text, (200, 200))

        pg.display.update()

    pg.quit()

if __name__ == "__main__":
    main()

I've also tried root.lift(), but in only works on startup. I know you can use it like this: root.lift(aboveThis=parameter). Parameter being a tkinter window. When I try to input the name of my pygame window it throws an error: bad window path name "chess". Is there a way to get the pygame window path name and assign it as the parameter?

  • 2
    I don't know where you're calling `get_piece_name()` from, but note that `root.mainloop()` will not return until the tkinter window is closed — so `get_piece_name()` itself won't be able to `return name` until then. Please provide a runnable [mre]. – martineau Jul 03 '21 at 12:29
  • I edited my question and added extra code, but the website is still telling me its closed. Should I wait or open a new question? – Daniel Alegria Sallo Jul 03 '21 at 16:58
  • I voted to re-open. However I noticed the what I said about `get_piece_name()` not returning until the tkinter window is closed still applies — which implies that your pygame display loop will freeze until that happens. – martineau Jul 03 '21 at 17:29
  • Thank you for the re-open vote. By the way, it doesn't freeze, the pygame win. closes when "root.destroy()" is called in "get_piece_name()". – Daniel Alegria Sallo Jul 03 '21 at 18:11
  • See [Embedding a Pygame window into a Tkinter or WxPython frame](https://stackoverflow.com/questions/23319059/embedding-a-pygame-window-into-a-tkinter-or-wxpython-frame/23464185#23464185) – Rabbid76 Nov 06 '22 at 14:15

1 Answers1

0

The combination of pygame and tkinter is not fully featured (see Embedding a Pygame window into a Tkinter or WxPython frame). It is never a good idea to mix frameworks. The frameworks may interact poorly with each other or conflict completely. If it works on your (operating) system, that doesn't mean it will work on another (operating) system or with a different version of one of the frameworks. Mixing frameworks always means some kind of undefined behavior.

Rabbid76
  • 202,892
  • 27
  • 131
  • 174