Tkinter Bilder einfügen.

Fragen zu Tkinter.
Antworten
karl.frederik
User
Beiträge: 1
Registriert: Montag 10. Dezember 2018, 15:18

Hallo,
Ich muss im moment in der Schule(8 Klasse) mit Python Programmieren.
Ich habe eine Vorlage gefunden, in der ich Bilder einfügen soll.
Leider geht dies nicht mit dem Fehlercode:

Code: Alles auswählen

Traceback (most recent call last):
  File "C:\Users\effi_\Downloads\ttt.py", line 3, in <module>
    background1 = PhotoImage(file="H:/bilderpython/Small-mario.png")
  File "C:\Users\effi_\AppData\Local\Programs\Python\Python37-32\lib\tkinter\__init__.py", line 3542, in __init__
    Image.__init__(self, 'photo', name, cnf, master, **kw)
  File "C:\Users\effi_\AppData\Local\Programs\Python\Python37-32\lib\tkinter\__init__.py", line 3486, in __init__
    raise RuntimeError('Too early to create image')
RuntimeError: Too early to create image
Mein den ich benutzt habe ist:

Code: Alles auswählen

from tkinter import *

background1 = PhotoImage(file="H:/bilderpython/Small-mario.png")
# PARAMETERS
# graphics
WINDOW_SIZE = 600 # pixels
GRID_LINE_WIDTH = 2 # pixels
SYMBOL_WIDTH = WINDOW_SIZE/12 # pixels - adjust ratio

# 0-1 : size of a symbol relative to it's cell
# bigger than 1 is too much
SYMBOL_SIZE = 0.5

X_COLOR = 'purple'
O_COLOR = 'fuchsia'
# background color of the 'draw' gameover screen
DRAW_SCREEN_COLOR = 'black'
GRID_COLOR = 'black'
BG_COLOR = 'grey'


# gameplay
FIRST_PLAYER = 2 # 1 - X, 2 = O

# OTHER
CELL_SIZE = WINDOW_SIZE / 3

# game states
STATE_TITLE_SCREEN = 0
STATE_X_TURN = 1
STATE_O_TURN = 2
STATE_GAME_OVER = 3

# symbol notation in the board memory
EMPTY = 0
X = 1
O = 2


class Game(Tk):
    """
    Main class
    """
    def __init__(self):
        Tk.__init__(self)
        self.canvas = Canvas(
            height=WINDOW_SIZE, width=WINDOW_SIZE,
            bg=BG_COLOR)

        self.canvas.pack()

        self.bind('<x>', self.exit)
        self.canvas.bind('<Button-1>', self.click)

        self.gamestate = STATE_TITLE_SCREEN
        self.title_screen()

        self.board = [
            [EMPTY, EMPTY, EMPTY],
            [EMPTY, EMPTY, EMPTY],
            [EMPTY, EMPTY, EMPTY]]
    def title_screen(self):
    # placeholder title screen
        self.canvas.delete('all') #just in case 

        self.canvas.create_rectangle(
            0, 0,
            WINDOW_SIZE, WINDOW_SIZE,
            fill=O_COLOR,
            outline='')

        self.canvas.create_rectangle(
            int(WINDOW_SIZE/15), int(WINDOW_SIZE/15),
            int(WINDOW_SIZE*14/15), int(WINDOW_SIZE*14/15),
            width=int(WINDOW_SIZE/20),
            outline=X_COLOR)    

        self.canvas.create_rectangle(
            int(WINDOW_SIZE/10), int(WINDOW_SIZE/10),
            int(WINDOW_SIZE*9/10), int(WINDOW_SIZE*9/10),
            fill=X_COLOR,
            outline='')

        self.canvas.create_text(
            WINDOW_SIZE/2,
            WINDOW_SIZE/3,
            text='TIC TAC STAHL', fill='white',
            font=('Franklin Gothic', int(-WINDOW_SIZE/12), 'bold'))

        self.canvas.create_text(
            int(WINDOW_SIZE/2),
            int(WINDOW_SIZE/2.5),
            text='[SPIEL ODER STIRB]', fill='white',
            font=('Franklin Gothic', int(-WINDOW_SIZE/25)))

    def new_board(self):
        """
        Clears canvas and game board memory, draws a new board on the canvas
        """

        # delete all objects
        self.canvas.delete('all')

        # reset
        self.board = [
            [EMPTY, EMPTY, EMPTY],
            [EMPTY, EMPTY, EMPTY],
            [EMPTY, EMPTY, EMPTY]]

        # draw grid
        for n in range(1, 3):
            # vertical
            self.canvas.create_line(
                CELL_SIZE*n, 0,
                CELL_SIZE*n, WINDOW_SIZE,
                width=GRID_LINE_WIDTH, fill=GRID_COLOR)
            # horizontal
            self.canvas.create_line(
                0, CELL_SIZE*n,
                WINDOW_SIZE, CELL_SIZE*n,
                width=GRID_LINE_WIDTH, fill=GRID_COLOR)

    def gameover_screen(self, outcome):
        #placeholder gameover screen

        self.canvas.delete('all')

        if outcome == 'X WINS':
            wintext = 'X hat gewonnen'
            wincolor = X_COLOR

        elif outcome == 'O WINS':
            wintext = 'O wins'
            wincolor = O_COLOR

        elif outcome == 'DRAW':
            wintext = 'Schlecht!'
            wincolor = DRAW_SCREEN_COLOR

        self.canvas.create_rectangle(
            0, 0,
            WINDOW_SIZE, WINDOW_SIZE,
            fill=wincolor, outline='')

        self.canvas.create_text(
            int(WINDOW_SIZE/2), int(WINDOW_SIZE/2),
            text=wintext, fill='white',
            font=('Franklin Gothic', int(-WINDOW_SIZE/6), 'bold'))

        self.canvas.create_text(
                int(WINDOW_SIZE/2), int(WINDOW_SIZE/1.65),
                text='[Willst du wieder Spielen?]', fill='white',
                font=('Franklin Gothic', int(-WINDOW_SIZE/25)))

    def click(self, event):
        """
        Handles most of the game logic
        I probably should move it elswhere but it's pretty short
        """

        x = self.ptgrid(event.x)
        y = self.ptgrid(event.y)

        if self.gamestate == STATE_TITLE_SCREEN:
            self.new_board()
            self.gamestate = FIRST_PLAYER


        #duplication /!\
        elif (self.gamestate == STATE_X_TURN and
                self.board[y][x] == EMPTY):
            self.new_move(X, x, y)

            if self.has_won(X):
                self.gamestate = STATE_GAME_OVER
                self.gameover_screen('X WINS')

            elif self.is_a_draw():
                self.gamestate = STATE_GAME_OVER
                self.gameover_screen('DRAW')

            else:
                self.gamestate = STATE_O_TURN

        elif (self.gamestate == STATE_O_TURN and
                self.board[y][x] == EMPTY):
            self.new_move(O, x, y)

            if self.has_won(O):
                self.gamestate = STATE_GAME_OVER
                self.gameover_screen('O WINS')

            elif self.is_a_draw():
                self.gamestate = STATE_GAME_OVER
                self.gameover_screen('DRAW')

            else:
                self.gamestate = STATE_X_TURN

        elif self.gamestate == STATE_GAME_OVER:
            #reset
            self.new_board()
            self.gamestate = FIRST_PLAYER

    def new_move(self, player, grid_x, grid_y):
        """
        player is either X or O
        x and y are 0-based grid coordinates

          0 1 2
        0 _|_|_
        1 _|_|_
        2  | |

        """
        #duplication /!\
        if player == X:
            self.draw_X(grid_x, grid_y)
            self.board[grid_y][grid_x] = X

        elif player == O:
            self.draw_O(grid_x, grid_y)
            self.board[grid_y][grid_x] = O

    def draw_X(self, grid_x, grid_y):
        """
        draw the X symbol at x, y in the grid
        """

        x = self.gtpix(grid_x)
        y = self.gtpix(grid_y)
        delta = CELL_SIZE/2*SYMBOL_SIZE

        self.canvas.create_line(
            x-delta, y-delta,
            x+delta, y+delta,
            width=SYMBOL_WIDTH, fill=X_COLOR)

        self.canvas.create_line(
            x+delta, y-delta,
            x-delta, y+delta,
            width=SYMBOL_WIDTH, fill=X_COLOR)

    def draw_O(self, grid_x, grid_y):
        """
        draw an O symbol at x, y in the grid

        note : a big outline value appears to cause a visual glitch in tkinter
        """

        x = self.gtpix(grid_x)
        y = self.gtpix(grid_y)
        delta = CELL_SIZE/2*SYMBOL_SIZE

        self.canvas.create_oval(
            x-delta, y-delta,
            x+delta, y+delta,
            width=SYMBOL_WIDTH, outline=O_COLOR)

    def has_won(self, symbol):
        for y in range(3):
            if self.board[y] == [symbol, symbol, symbol]:
                return True

        for x in range(3):
            if self.board[0][x] == self.board[1][x] == self.board[2][x] == symbol:
                return True

        if self.board[0][0] == self.board[1][1] == self.board[2][2] == symbol:
            return True

        elif self.board[0][2] == self.board[1][1] == self.board[2][0] == symbol:
            return True

        # no win sequence found
        return False

    def is_a_draw(self):
        for row in self.board:
            if EMPTY in row:
                return False

        #no empty cell left, the game is a draw
        return True

    def gtpix(self, grid_coord):
        # gtpix = grid_to_pixels
        # for a grid coordinate, returns the pixel coordinate of the center
        # of the corresponding cell

        pixel_coord = grid_coord * CELL_SIZE + CELL_SIZE / 2
        return pixel_coord

    def ptgrid(self, pixel_coord):
        # ptgrid = pixels_to_grid
        # the opposit of gtpix()

        # somehow the canvas has a few extra pixels on the right and bottom side
        if pixel_coord >= WINDOW_SIZE:
            pixel_coord = WINDOW_SIZE - 1    

        grid_coord = int(pixel_coord / CELL_SIZE)
        return grid_coord

    def exit(self, event):
        self.destroy()


def main():

    root = Game()
    root.mainloop()

main()
 
Ich hoffe ihr könnt mir Helfen, denn es ist relativ wichtig und ich bin nicht so erfahren.
Karl-Frederik
Benutzeravatar
__blackjack__
User
Beiträge: 13004
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Bevor man `PhotoImage`-Objekte erstellen kann, muss das `Tk`-Objekt erstellt worden sein.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
Antworten