簡體   English   中英

在Tkinter畫布上繪制圖像

[英]Drawing a image to a tkinter canvas

我已經搜索過,但沒有找到與該主題相關的任何內容,因此我將在這里詢問。

我開始開發非常基礎的游戲,並且希望將圖片加載到背景中。 我正在使用Python上的電子書來幫助我做到這一點,並且據此,以下代碼是正確的:

from tkinter import *
import time
import random

Width = 1000
Height = (Width/12)*9

class Game:

    def __init__(self):
        self.tk = Tk()
        self.tk.title("Monster Rush")
        self.tk.resizable(0, 0)
        self.tk.wm_attributes("-topmost", 1)
        self.canvas = Canvas(self.tk, width=Width, height=Height, highlightthickness=0)
        self.canvas.pack()
        self.tk.update()
        self.canvas_height = 500
        self.canvas_width = 500
        self.bg = PhotoImage(file="anipedra.gif")
        w = self.bg.width()
        h = self.bg.height()
        for x in range(0, 5):
            for y in range(0, 5):
                self.canvas.create_image(x * w, y * h, image=self.bg, anchor='nw')
        self.sprites = []
        self.running = True

    def mainloop(self):
        while 1:
            if self.running == True:
                for sprite in self.sprites:
                    sprite.move()
                    self.tk.update_idletasks()
        self.tk.update()
        time.sleep(0.01)

class Enemy(Game):
    def __init__(self):
        self.e = Game()
        self.e.mainloop()

class Player(Game):
    def __init__(self):
        self.e = Game()
        self.e.mainloop()

Troll = Enemy()
Grunt = Enemy()
Minion = Enemy()
Player = Player()

但是每次我運行這個:

  1. 如果是.gif,則IDLE通常顯示以下內容:
  Traceback (most recent call last):
    File "C:\Users\Nuno\Desktop\Python\Projectos\Monster Rush\Monster Rush (T.D.).py", line 47, in <module>
  Troll = Enemy()
    File "C:\Users\Nuno\Desktop\Python\Projectos\Monster Rush\Monster Rush (T.D.).py", line 39, in __init__
  self.e = Game()
    File "C:\Users\Nuno\Desktop\Python\Projectos\Monster Rush\Monster Rush (T.D.).py", line 20, in __init__
  self.bg = PhotoImage(file="background.gif")
    File "C:\Users\Nuno\AppData\Local\Programs\Python\Python35\lib\tkinter\__init__.py", line 3393, in __init__
  Image.__init__(self, 'photo', name, cnf, master, **kw)
    File "C:\Users\Nuno\AppData\Local\Programs\Python\Python35\lib\tkinter\__init__.py", line 3349, in __init__
  self.tk.call(('image', 'create', imgtype, name,) + options)
  _tkinter.TclError: couldn't recognize data in image file "background.gif"
  1. 如果是上述代碼(或任何其他格式)中的.gif:

    該文件停止響應並崩潰。

誰能幫我?

您的堆棧跟蹤中的錯誤表明該文件不是真正的GIF文件。 您確定它實際上是一個gif文件,還是其他人重新命名為.gif后綴的文件?

您也有幾個關鍵的設計缺陷。

  1. 在設計良好的tkinter應用中,您必須始終只有一個根窗口。 您要創建四個(或八個...)-每個玩家和一個敵人對象一個。

  2. 您有既可以從Game繼承又可以自己創建Game實例的類。 這絕對沒有道理。 從Game繼承或創建實例,但不要兩者都做。 但是,由於Game創建了一個根窗口,因此創建多個Game對象沒有任何意義。

  3. 您沒有正確使用事件循環。 您永遠不會讓tkinter處理某些事件。 您有自己的無限循環,可以在其中調用update_idletasks() ,但這僅處理屏幕刷新和其他“空閑”事件。 它不會處理按鍵或鼠標單擊。 您調用了update但是它在無限循環之外,因此它永遠不會被調用。

    1. 作為一般經驗法則,您不應在GUI中調用sleep 它完全按照它說的去做:它使您的應用程序進入睡眠狀態。 在睡眠狀態下,它不會刷新屏幕,也不會處理鼠標或鍵盤事件。 該應用程序確實死了。

雖然我不清楚您的意圖是什么,但您可以通過執行mainloop來重寫自己的自定義mainloop循環以利用真實事件循環:

def mainloop(self): 
    if self.running == True: 
        for sprite in self.sprites: 
            sprite.move() 
        self.tkafter(30, self.mainloop)

您需要設置30以表示您希望顯示器更新的速度。 該值以毫秒為單位,因此30表示30fps。 另外,您需要只調用根窗口的mainloop函數一次,以便它可以處理事件。

也許這! 某些圖像軟件可以並且有時會將擴展名結尾更改為圖像文件。 他們可以按需利用擴展名。 例如.gif到.GIF或jpeg到JPEG等。只有將文件上傳到網站上之后,您才會意識到這一點,然后您將看到大寫的擴展名。 Google臭名昭著的Picaso Download在我的計算機上做到了這一點,我必須重新安裝系統才能修復它。 無關,但Windows在某些較舊的XP版本中也會秘密更改jpeg格式。 有人在另一台機器上測試您的代碼。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM