使用按钮事件 tkinter 在画布中创建图像

2024-02-07

我需要向 Tkinter gui 中的按钮添加一个事件,该事件将在画布中创建图像。我该怎么做?

谢谢大家

它有效,但我需要获取同一图像文件的动态数字图像,但每次我创建新图像时,旧图像都会被垃圾收集。我想不出该怎么办。我想在画布上有同一图像的多个实例。请,很高兴提供一些建议

my code

from Tkinter import *
import tkMessageBox


def callback():
        if tkMessageBox.askokcancel("Quit", "Do you really wish to quit?"):
            root.destroy()

class AppUI(Frame):
        def __init__(self, master):

            Frame.__init__(self, master, background="white", relief=FLAT, bd=2, height=768, width=1024)

            self.menubar = Menu(self)

            menu = Menu(self.menubar)
            self.menubar.add_cascade(label="File", menu=menu)
            menu.add_command(label="New")
            menu.add_command(label="Open")
            menu.add_command(label="Save As")
            menu.add_command(label="Save Copy of")
            menu.add_separator()
            menu.add_command(label="exit")

            menu = Menu(self.menubar)
            self.menubar.add_cascade(label="Edit", menu=menu)
            menu.add_command(label="Cut")
            menu.add_command(label="Copy")
            menu.add_command(label="Paste")

            menu = Menu(self.menubar)
            self.menubar.add_cascade(label="Debug", menu=menu)
            menu.add_command(label="Open Debugger")
            menu.add_command(label="Auto-debug")
            menu.add_command(label="Revert")

            menu = Menu(self.menubar)
            self.menubar.add_cascade(label="Run", menu=menu)
            menu.add_command(label="Stimulation")
            menu.add_command(label="Check")
            menu.add_command(label="Scan Module")

            menu = Menu(self.menubar)
            self.menubar.add_cascade(label="Help", menu=menu)
            menu.add_command(label="Help files")
            menu.add_command(label="FTA site")
            menu.add_separator()
            menu.add_command(label="Credits")

            self.master.config(menu=self.menubar)      

            f0 = Frame(root, background="white")

            b1 = Button(f0, bd=2, padx=15, pady=15, justify = LEFT)
            photo1 = PhotoImage(file="Images/p1.gif")
            b1.config(image = photo1,width="50",height="50", command=self.create_image1)
            b1.image = photo1
            b1.pack(side=LEFT)

            b2 = Button(f0, bd=2, padx=15, pady=15, justify = LEFT)
            photo2 = PhotoImage(file="Images/p4.gif")
            b2.config(image=photo2, width="50",height="50", command = self.create_image2)
            b2.image = photo2
            b2.pack(side=LEFT)

            b3 = Button(f0,padx=15, bd=2, pady=15, justify = LEFT)
            photo3 = PhotoImage(file="Images/p8.gif")
            b3.config(image=photo3, width="50",height="50", command = self.create_image3)
            b3.image = photo3
            b3.pack(side=LEFT)

            b4 = Button(f0,padx=15, bd=2, pady=15, justify = LEFT)
            photo4 = PhotoImage(file="Images/p7.gif")
            b4.config(image=photo4, width="50",height="50", command = self.create_image4)
            b4.image = photo4
            b4.pack(side=LEFT)

            b5 = Button(f0,padx=15, bd=2, pady=15, justify = LEFT)
            photo5 = PhotoImage(file="Images/p5.gif")
            b5.config(image=photo5, width="50",height="50", command=self.create_image5)
            b5.image = photo5
            b5.pack(side=LEFT)

            f0.pack(anchor=NW, side=TOP)

            self.canvas = Canvas(self, height=750, width=1500, bg="white")
            self.canvas.pack(side=LEFT)

    def create_image1(self):
            photos1 = PhotoImage(file="Images/p1.gif")
            self.photos1=photos1
            self.img1=self.canvas.create_image(60, 60, image=photos1)
            self.canvas.bind("<B1-Motion>", self.move_image1)

    def create_image2(self):
            photos2 = PhotoImage(file="Images/p4.gif")
            self.photos2=photos2
            self.img2=self.canvas.create_image(60, 60, image=photos2)
            self.canvas.bind("<B1-Motion>", self.move_image2)

    def create_image3(self):
            photos3 = PhotoImage(file="Images/p8.gif")
            self.photos3=photos3
            self.img3=self.canvas.create_image(60, 60, image=photos3)
            self.canvas.bind("<B1-Motion>", self.move_image3)

    def create_image4(self):
            photos4 = PhotoImage(file="Images/p7.gif")
            self.photos4=photos4
            self.img4=self.canvas.create_image(60, 60, image=photos4)
            self.canvas.bind("<B1-Motion>", self.move_image4)

    def create_image5(self):
            photos5 = PhotoImage(file="Images/p5.gif")
            self.photos5=photos5
            self.img5=self.canvas.create_image(60, 60, image=photos5)        
            self.canvas.bind("<B1-Motion>", self.move_image5)

    def move_image1(self, event):
            self.canvas.delete(self.img1)
            x = event.x
            y = event.y
            self.img1 = self.canvas.create_image(x, y, image=self.photos1, anchor='nw')
            self.canvas.update()
    def move_image2(self, event):
            self.canvas.delete(self.img2)
            x = event.x
            y = event.y
            self.img2 = self.canvas.create_image(x, y, image=self.photos2, anchor='nw')
            self.canvas.update()
    def move_image3(self, event):
            self.canvas.delete(self.img3)
            x = event.x
            y = event.y
            self.img3 = self.canvas.create_image(x, y, image=self.photos3, anchor='nw')
            self.canvas.update()
    def move_image4(self, event):
            self.canvas.delete(self.img4)
            x = event.x
            y = event.y
            self.img4 = self.canvas.create_image(x, y, image=self.photos4, anchor='nw')
            self.canvas.update()
    def move_image5(self, event):
            self.canvas.delete(self.img5)
            x = event.x
            y = event.y
            self.img5 = self.canvas.create_image(x, y, image=self.photos5, anchor='nw')
            self.canvas.update()        


root = Tk()
root.protocol("WM_DELETE_WINDOW", callback)

app = AppUI(root)
app.pack()

root.mainloop()

此外,只能拖放最后绘制的图像,所有先前绘制的图像都无法交互。而且,正如我所说,我似乎无法创建多个克隆图像。我知道我应该锚定所有图像,这样它们就不会被垃圾收集,但我似乎无法找到一种方法来做到这一点。我尝试将函数 create_image 的图像实例返回到数组。但没有成功。提前致谢


您具体遇到什么问题?这没有什么棘手的:

def __init__(...):
    ...
    self.canvas = tk.Canvas(...)
    b = tk.Button(..., command=self.create_image)
    ...
def create_image(self):
    self.canvas.create_image(...)

要记住的重要一点是,除非您保留对图像的引用,否则图像将被垃圾收集。由于您要创建多个图像,因此一种简单的方法是创建一个列表,您可以在其中附加对图像的引用:

def __init__(...):
    ...
    self.images = []
    ...
    photo1 = PhotoImage(file="Images/p1.gif")
    self.images.append(photo1)
    ...

您的代码还存在一些其他问题。其一,您无需在移动图像时删除然后重新创建图像。画布上有一个move专门用于移动现有项目的方法。此外,还调用self.canvas.update()完全没用。

最后,如果您只有一个“移动”方法,而不是每个图像一个,那么您的代码将更容易维护。这不是这个特定问题的主题,但您可能想搜索lambda and functools.partial作为能够通过绑定传递参数的解决方案。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用按钮事件 tkinter 在画布中创建图像 的相关文章

随机推荐

  • 捕获程序的每个异常?

    我有一个在全球范围内运行良好的 WPF 应用程序 但有时 客户告诉我他遇到了一些崩溃 但除了他做了什么 我对发生的事情一无所知 有没有办法放置全局 try catch Exception LOGEXCEPTION throw 某处接收由 G
  • 巨大的性能差异:调试与发布

    我有一个简单的算法 可以将拜耳图像通道 BGGR RGGB GBRG GRBG 转换为RGB 去马赛克但没有邻居 在我的实现中 我有预设的偏移向量 可以帮助我将拜耳通道索引转换为其相应的 RGB 通道索引 唯一的问题是我在 MSVC11 的
  • 错误 LNK2019:无法解析的外部符号“toString(int)”

    环境 Windows XP Visual Studios 2010 语言 C 我遇到了以下链接错误 并且已经没有办法解决此问题 我有一个项目 CnD Device 它链接到我的团队控制的 2 个项目 Messages 和 Carbon 我尝
  • 在 Prolog 中打乱列表

    简单的问题 如何在 Prolog 中打乱列表 以便A1是洗牌后的列表吗 shuffle 1 1 1 2 3 4 A1 我尝试了在网上找到的一些谓词 但似乎都不起作用 还发现this http www cs uni potsdam de wv
  • 如何访问reduce中的第0个元素以计算数组中的重复次数

    在节点学校的突发奇想中 我正在尝试使用reduce计算字符串在数组中重复的次数 var fruits Apple Banana Apple Durian Durian Durian obj fruits reduce function pr
  • CloudKit 中私人存储的数据是否存储在用户的 iCloud 帐户中?

    我的应用程序涉及用户创建数据并将其保存到他们的私人数据库中 这些数据会占用他们的 iCloud 帐户空间 还是会成为我的 CloudKit 存储配额的一部分 谢谢 这包含在为 CloudKit 进行设计 https developer ap
  • VBA 未使用 Now() 返回正确的日期

    我有一个简单的代码 VBA 无法返回正确的日期 Sub Test Date Debug Print Format Month Now mmm Debug Print Month Now Debug Print Now End Sub 返回
  • 在图像上添加动态文本

    我正在为用户创建一个网站 他们可以在其中创建自定义徽标 为此 我需要一种工具来从用户将填写的文本框中添加动态文本 然后文本应出现在所选图像上 有没有什么办法 比如说Javascript 可以通过它来实现上述场景 对于我如何做到这一点的任何建
  • RecyclerView Grid - 定义每行的项目数

    我通常反对在没有代码的情况下发布问题 但我没有代码可以显示 我终于将我的项目从 listviews 和 gridviews 转换为 recyclerView 在一堂课中 我使用一个小型网格视图来放置从服务器拉取的项目 每行的最大项目数为 3
  • 尝试在 Rails 中调用我的服务时出现“未初始化常量”

    我正在使用 Rails 4 2 3 我在控制器中有这一行 service XACTEService new Event 2015 06 01 Zoo 有问题的类在 app services XACTEService rb 中定义 然而 在访
  • XmlSerializer 列表项元素名称

    我有课PersonList XmlRoot Persons PersonList List
  • Web 应用程序的传入请求是否有配额?

    我正在运行一个脚本 该脚本通过 URL 访问更改 Google 表格中的行 部署为 Web 应用程序 例如macroUrl sheet SheetName key KeyName value ValueName 这非常适合我的需要 但我不确
  • 与 TypeScript 混合模式?

    我读过这篇文章 https justinfagnani com 2015 12 21 real mixins with javascript classes https justinfagnani com 2015 12 21 real m
  • 增加 HTML 正文中的光标大小

    有没有什么方法可以在基于浏览器的应用程序中以编程方式增加光标的大小CSS or jQuery 我可以用 CSS 改变光标的类型 就像这样 body cursor crosshair 但我在 CSS 中没有看到增加光标大小的规定 没有关于光标
  • 你能让 ERB 在渲染时正确缩进吗?

    我有几个部分包含在 Rails 中application html erb file 但生成的 HTML 不会保留我的缩进 格式 我被告知第一行以与调用相同的缩进级别呈现 partial html erb 但部分中的所有后续行都会左对齐 这
  • jQuery 图片库非功能性淡入淡出效果

    这是一个简单的图像库脚本 用于淡入和淡出带有背景图像的 div 它很慢而且不能正常工作 看起来所有图像都一起出现和消失 没有任何动画 该画廊应该将每张图像淡出到下一张图像中 function gallery timerp window se
  • Imagemagick 将每个边缘切掉 30px(宽度和高度可变)

    我需要将每边切掉 30px 左上右下 我试过了crop并且 chop 30x30但这似乎只在一方面起作用 convert verbose density 150 trim pdfs test test pdf quality 80 chop
  • 源集 - Groovy -> Kotlin DSL

    sourceSets main java srcDirs src main kotlin src main java res srcDirs src main res layouts activity src main res layout
  • 使用管理器和向量时出现内存错误

    我想创建一个包含多个对象的管理器 并且必须使用它才能实际创建对象 这些对象将其信息保存在智能指针中 这就是我的实现方式 struct Object std shared ptr
  • 使用按钮事件 tkinter 在画布中创建图像

    我需要向 Tkinter gui 中的按钮添加一个事件 该事件将在画布中创建图像 我该怎么做 谢谢大家 它有效 但我需要获取同一图像文件的动态数字图像 但每次我创建新图像时 旧图像都会被垃圾收集 我想不出该怎么办 我想在画布上有同一图像的多