【问题标题】:Drawing a image to a tkinter canvas将图像绘制到 tkinter 画布
【发布时间】:2016-03-23 15:15:41
【问题描述】:

我已经搜索过,没有找到关于这个主题的内容,所以我会在这里问。

我开始开发非常基本的游戏,我想将图片加载到我的背景中。我正在使用 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(或其他任何格式):

      文件停止响应并崩溃。

谁能帮帮我?

【问题讨论】:

  • TCL 图像类对某些图像类型有困难,请查看PIL(python 图像库)和它的替换 pillowpypi.python.org/pypi/Pillow/3.1.1
  • 您确定您的文件实际上是 gif 文件,还是您只是将文件从 .png 重命名为 .gif?
  • 为什么要创建四个根窗口?敌人和玩家真的应该在一个单独的窗口中吗?

标签: python image tkinter tkinter-canvas


【解决方案1】:

堆栈跟踪中的错误表明该文件不是真正的 GIF 文件。您确定它实际上是一个 gif 文件,还是有人重命名为以 .gif 作为后缀的其他文件?

你还有几个严重的设计缺陷。

  1. 在设计良好的 tkinter 应用程序中,您必须始终只有一个根窗口。您正在创建四个(或八个......) - 每个玩家和敌人对象一个。

  2. 您的类既继承自 Game,又创建了 Game 实例本身。这完全没有意义。从 Game 继承或创建实例,但不要两者都做。不过,由于Game 创建了一个根窗口,因此创建多个Game 对象是没有意义的。

  3. 您没有正确使用事件循环。您永远不会让 tkinter 处理某些事件。您有自己的无限循环,您可以在其中调用update_idletasks(),但它只处理屏幕刷新和其他“空闲”事件。它不会处理按键或鼠标点击。你调用update,但它在无限循环之外,所以它永远不会被调用。

    1. 一般来说,您不应该在 GUI 中调用 sleep。它正如它所说的那样:它让你的应用程序进入睡眠状态。当它处于睡眠状态时,它不会刷新屏幕,也不会处理鼠标或键盘事件。应用程序真的死了。

虽然我不确切知道您的意图是什么,但您可以重写自己的自定义 mainloop,通过执行以下操作来利用真实的事件循环:

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

您需要设置30 来表示您希望显示更新的速度。该值以毫秒为单位,因此 30 表示 30fps。此外,您需要只调用一次根窗口的mainloop 函数,以便它可以处理事件。

【讨论】:

  • 我只是一个试图提高python和其他语言的孩子,但你的解释对我来说太复杂了。有些部分我理解,但很糟糕,因为我没有大量的编程知识,所以如果你能“开玩笑”你的解释,我会很感激。
  • 顺便说一句,我正在尝试做一个塔防游戏
  • P.S.:我想用 Tkinter 打开的文件是真正的 .gif 文件(双重检查)。
  • @naapperas:我建议您首先尝试在屏幕上画一个小球并让它移动。一旦你明白了这一点,添加多个玩家和游戏逻辑就会更容易。你在尝试学习语言的同时尝试做太多事情。
  • 我只是想像 Jason Briggs 在他的“儿童 Python”一书中所做的那样。
【解决方案2】:

也许是这个!一些图像软件可以并且有时会将扩展名结尾更改为图像文件。他们可以根据需要利用扩展。例如 .gif 到 .GIF 或 jpeg 到 JPEG 等。在您将文件上传到网站之前,您不会意识到这一点,然后您会看到大写的扩展名。谷歌臭名昭著的 Picaso 下载对我的电脑做了这个,我不得不重新安装系统来修复它。不相关,但 Windows 在某些较旧的 XP 版本中也会秘密更改 jpeg 格式。让别人在另一台机器上测试你的代码。

【讨论】:

    猜你喜欢
    • 2013-11-01
    • 2012-11-09
    • 1970-01-01
    • 2018-03-05
    • 2015-12-31
    • 1970-01-01
    • 2014-09-03
    • 2012-09-15
    • 2014-08-08
    相关资源
    最近更新 更多