python-3.x 如何将透明图像放置在另一个图像上(Tkinter)

dkqlctbz  于 2023-02-10  发布在  Python
关注(0)|答案(1)|浏览(143)

我的尴尬和可能的火焰代码(这将最终变成一个象棋游戏)

import chess
#from stockfish import Stockfish
import tkinter as tk
import time

board = chess.Board()

def boardtoarr(board): #converts chess board string to 2d array
    boardlist = []
    linelist = []
    for b in range(0,128,2):
        linelist.append(str(board)[b])
        if len(linelist) == 8:
            boardlist.append(linelist)
            linelist = []
    return boardlist


#given the square of a piece on the board, returns the legal squares the piece can move to
def piecelegalmoves(square,cboard):
    ans = ''
    for a in cboard.legal_moves:
        a = str(a)
        if a[0:2] == square:
            ans += a[2::]+' '
    return ans

def alllegalmoves(cboard):
    x = str(cboard.legal_moves)[38:-2]
    x = x.split(', ')
    return x


squarevariable = ''

def squareclicked(event):
    global squarevariable
    print(topleftpixelstosquare(event.x,event.y))
    print(lsquaretocsquare(topleftpixelstosquare(event.x,event.y)))
    squarevariable = lsquaretocsquare(topleftpixelstosquare(event.x,event.y))
    
def topleftpixels(x,y): #returns top left pixel of given square
    return [x*100,y*100]

def topleftpixelstosquare(x,y):
    x = ('000' + str(x))
    x = x[len(x)-3::]
    y = ('000' + str(y))
    y = y[len(y)-3::]
    return [int(y[0]),int(x[0])]

def csquaretolsquare(square): #converts chess square notation to list square notation
    ans = []
    letterorder = 'abcdefgh'
    ans.append(8-int(square[1]))
    ans.append(letterorder.index(square[0]))
    return ans

def lsquaretocsquare(square): #converts list square notation to chess square notation
    ans = ''
    letterorder = 'abcdefgh'
    ans += (letterorder[square[1]])
    ans += str(8-square[0])
    return ans 

def boardtoimage(root,boardstr): #places all pieces onto the window graphically
    global wQueen,wKing,wKnight,wBishop,wPawn,wRook,bQueen,bKing,bKnight,bBishop,bPawn,bRook

    for y in range(8):
            for x in range(8):
                piece = boardtoarr(boardstr)[y][x]
                xcoord = topleftpixels(x,y)[0]
                ycoord = topleftpixels(x,y)[1]
                if piece == 'Q':
                    tk.Label(root, image = wQueen).place(x = xcoord,y = ycoord)
                if piece == 'K':
                    tk.Label(root, image = wKing).place(x = xcoord,y = ycoord)
                if piece == 'R':
                    tk.Label(root, image = wRook).place(x = xcoord,y = ycoord)
                if piece == 'P':
                    tk.Label(root, image = wPawn).place(x = xcoord,y = ycoord)
                if piece == 'B':
                    tk.Label(root, image = wBishop).place(x = xcoord,y = ycoord)
                if piece == 'N':
                    tk.Label(root, image = wKnight).place(x = xcoord,y = ycoord)
                
                if piece == 'q':
                    tk.Label(root, image = bQueen).place(x = xcoord,y = ycoord)
                if piece == 'k':
                    tk.Label(root, image = bKing).place(x = xcoord,y = ycoord)
                if piece == 'r':
                    tk.Label(root, image = bRook).place(x = xcoord,y = ycoord)
                if piece == 'p':
                    tk.Label(root, image = bPawn).place(x = xcoord,y = ycoord)
                if piece == 'b':
                    tk.Label(root, image = bBishop).place(x = xcoord,y = ycoord)
                if piece == 'n':
                    tk.Label(root, image = bKnight).place(x = xcoord,y = ycoord)
                
                

def CMI_clicked(): #check if the chess menu image was clicked
    global root
    global BoardImage
    for widget in root.winfo_children(): #code to clear page
        widget.destroy()
    boardbackground = tk.Label(root, image = BoardImage) #place the board image at the background
    boardbackground.pack()

    board.push_san('e2e4')

    boardtoimage(root,str(board))
    #while True: 
        #print('x')
        #boardstr = str(board)

    root.bind('<Button-1>', squareclicked)

def Menu():
    global root
    global ChessMenuImage
    #Menu
    ChessMenuOption = tk.Button(root ,image = ChessMenuImage, command = CMI_clicked) #create button using chess menu image and call function 'CMI_clicked' when pressed
    ChessMenuOption.place(x = 380, y = 380) #place the chess menu image at given coordinates



root = tk.Tk()

ChessMenuImage = tk.PhotoImage(file = r'C:\Users\benja\Documents\Python\Chess project\Chess_Selection_Image.png') #Load chess menu image file

BoardImage = tk.PhotoImage(file = r'C:\Users\benja\Documents\Python\Chess project\ChessBoardImage.png') #Load board image file

#Piece image loading
#White
wQueen = tk.PhotoImage(file = r'C:\Users\benja\Documents\Python\Chess project\wQueen.png')
wKing = tk.PhotoImage(file = r'C:\Users\benja\Documents\Python\Chess project\wKing.png')
wPawn = tk.PhotoImage(file = r'C:\Users\benja\Documents\Python\Chess project\wPawn.png')
wBishop = tk.PhotoImage(file = r'C:\Users\benja\Documents\Python\Chess project\wBishop.png')
wKnight = tk.PhotoImage(file = r'C:\Users\benja\Documents\Python\Chess project\wKnight.png')
wRook = tk.PhotoImage(file = r'C:\Users\benja\Documents\Python\Chess project\wRook.png')

#Black
bQueen = tk.PhotoImage(file = r'C:\Users\benja\Documents\Python\Chess project\bQueen.png')
bKing = tk.PhotoImage(file = r'C:\Users\benja\Documents\Python\Chess project\bKing.png')
bPawn = tk.PhotoImage(file = r'C:\Users\benja\Documents\Python\Chess project\bPawn.png')
bBishop = tk.PhotoImage(file = r'C:\Users\benja\Documents\Python\Chess project\bBishop.png')
bKnight = tk.PhotoImage(file = r'C:\Users\benja\Documents\Python\Chess project\bKnight.png')
bRook = tk.PhotoImage(file = r'C:\Users\benja\Documents\Python\Chess project\bRook.png')

root.geometry('800x800')

Menu()

root.mainloop()

第68 - 100行是我放置棋子的地方,第110行是我放置棋盘作为背景的地方,但是当我运行代码时,它看起来像这样:

我知道通过运行以下代码:

import tkinter as tk

win = tk.Tk()

photoimage = tk.PhotoImage(file=r'C:\Users\benja\Documents\Python\Chess project\wQueen.png')

width, height = photoimage.width(), photoimage.height()
canvas = tk.Canvas(win, bg="blue", width=width, height=height)
canvas.pack()

canvas.create_image(0, 0, image=photoimage, anchor='nw')

win.mainloop()

python在返回以下代码时将这些片段识别为透明的

我哪里做错了?

dzhpxtsq

dzhpxtsq1#

由于您使用了Label小部件来显示棋盘和棋子的图像,因此Label不支持透明背景。
如第二个示例所示,可以使用Canvas来显示这些透明图像。下面是修改后的boardtoimage()CMI_clicked()函数,使用Canvas代替Label

...

def boardtoimage(root, boardstr): #places all pieces onto the window graphically
    piece_mapping = {
        'r': bRook, 'n': bKnight, 'b': bBishop, 'q': bQueen, 'k': bKing, 'p': bPawn,
        'R': wRook, 'N': wKnight, 'B': wBishop, 'Q': wQueen, 'K': wKing, 'P': wPawn,
    }

    for y in range(8):
        for x in range(8):
            piece = boardtoarr(boardstr)[y][x]
            # get the corresponding piece image
            image = piece_mapping.get(piece, None)
            if image:
                xcoord = topleftpixels(x,y)[0]
                ycoord = topleftpixels(x,y)[1]
                # show the piece image
                canvas.create_image(xcoord, ycoord, image=image, anchor="nw")

def CMI_clicked(): #check if the chess menu image was clicked
    global canvas

    for widget in root.winfo_children(): #code to clear page
        widget.destroy()

    # create the canvas to show those transparent images
    canvas = tk.Canvas(root, width=BoardImage.width(), height=BoardImage.height(), highlightthickness=0)
    canvas.pack()

    # show the chess board image
    canvas.create_image(0, 0, image=BoardImage, anchor="nw")

    board.push_san('e2e4')

    boardtoimage(root,str(board))

    root.bind('<Button-1>', squareclicked)

...

结果:

相关问题