Python tkinter帧中的背景图像

Python tkinter帧中的背景图像,python,tkinter,Python,Tkinter,我想在一个框架中放置一个背景图像,这是我试图运行但没有成功的代码 import tkinter as tk from tkinter import * root = tk.Tk() F1 = Frame(root) F1.grid(row=0) photo = PhotoImage(file="sfondo.png") label = Label(F1, image=photo) label.image = photo label.place(x=0, y=0) b = tk.Butto

我想在一个框架中放置一个背景图像,这是我试图运行但没有成功的代码

import tkinter as tk
from tkinter import *

root = tk.Tk()

F1 = Frame(root)
F1.grid(row=0)

photo = PhotoImage(file="sfondo.png")
label = Label(F1, image=photo)
label.image = photo
label.place(x=0, y=0)

b = tk.Button(label, text="Start")
b.grid(row=8, column=8)

root.mainloop()
如果按此方式运行代码,则只会显示左上角的一个小点(框架中没有任何内容,即使我将标签放在其中)。如果我将标签父项替换为
,它将显示带有一小部分图像的按钮作为backgound(只有按钮的周长有几个像素的颜色)。然而,我想要的是一个完整的背景图像在框架中,我可以把我想要的小部件

我尝试使用place方法和PIL模块

import tkinter as tk
from tkinter import *
from PIL import Image, ImageTk

root = tk.Tk()

F1 = Frame(root)
F1.grid(row=0)
image = Image.open("sfondo.png")

render = ImageTk.PhotoImage(image)
img = tk.Label(F1, image=render)
img.image = render
img.place(x=0, y=40)

b = tk.Button(img, text="Start")
b.grid(row=8, column=8)

root.mainloop()
这里或多或少我也遇到了同样的问题,如果我将标签的父项设置为
,则按钮显示时周长是彩色的。 如果我将父对象设置为
F1
什么也不发生,并且在这两种情况下,如果我将父对象设置为
root
并删除按钮,图像将完全显示。
但我想要的是,图像完全显示在框架中,然后在背景图像上显示小部件。

您可以将图像放置在
画布上,然后通过将其放置在可以容纳任何Tkinter小部件的

可以以类似的方式添加其他小部件,每个小部件都位于其自己的
画布
窗口对象中(因为每个小部件只能容纳一个小部件)。您可以通过将
框架
小部件放置在
画布
窗口中,然后将其他小部件放置在其中,来解决该限制

下面的示例显示了如何显示单个
按钮

from PIL import Image, ImageTk
import tkinter as tk

IMAGE_PATH = 'sfondo.png'
WIDTH, HEIGTH = 200, 200

root = tk.Tk()
root.geometry('{}x{}'.format(WIDTH, HEIGHT))

canvas = tk.Canvas(root, width=WIDTH, height=HEIGTH)
canvas.pack()

img = ImageTk.PhotoImage(Image.open(IMAGE_PATH).resize((WIDTH, HEIGTH), Image.ANTIALIAS))
canvas.background = img  # Keep a reference in case this code is put in a function.
bg = canvas.create_image(0, 0, anchor=tk.NW, image=img)

# Put a tkinter widget on the canvas.
button = tk.Button(root, text="Start")
button_window = canvas.create_window(10, 10, anchor=tk.NW, window=button)

root.mainloop()
截图:

编辑 虽然我不知道如何在
Frame
中而不是在
Canvas
中执行此操作,但您可以派生自己的
Frame
子类,以便更轻松地添加多个小部件。我的意思是:

from PIL import Image, ImageTk
import tkinter as tk


class BkgrFrame(tk.Frame):
    def __init__(self, parent, file_path, width, height):
        super(BkgrFrame, self).__init__(parent, borderwidth=0, highlightthickness=0)

        self.canvas = tk.Canvas(self, width=width, height=height)
        self.canvas.pack()

        pil_img = Image.open(file_path)
        self.img = ImageTk.PhotoImage(pil_img.resize((width, height), Image.ANTIALIAS))
        self.bg = self.canvas.create_image(0, 0, anchor=tk.NW, image=self.img)

    def add(self, widget, x, y):
        canvas_window = self.canvas.create_window(x, y, anchor=tk.NW, window=widget)
        return widget


if __name__ == '__main__':

    IMAGE_PATH = 'sfondo.png'
    WIDTH, HEIGTH = 350, 200

    root = tk.Tk()
    root.geometry('{}x{}'.format(WIDTH, HEIGTH))

    bkrgframe = BkgrFrame(root, IMAGE_PATH, WIDTH, HEIGTH)
    bkrgframe.pack()

    # Put some tkinter widgets in the BkgrFrame.
    button1 = bkrgframe.add(tk.Button(root, text="Start"), 10, 10)
    button2 = bkrgframe.add(tk.Button(root, text="Continue"), 50, 10)

    root.mainloop()
结果:

更新 我最近才意识到,实际上有一种比创建自定义的
框架
子类更简单的方法,如我前面的编辑所示。诀窍是
place()
一个
标签
,其上的图像位于父
框架的中心
——然后您可以像通常一样自由使用其他几何体管理器,如
pack()
grid()
——如下面的示例代码所示。与需要调用非标准方法(如
add()
)相比,它不仅不那么复杂,而且是一种更“自然”的添加小部件的方法

结果#2


p.S.您可以从下载
sfondo.png
背景图像的副本。

您可以将图像放置在
画布上
,然后将
按钮
放在可容纳任何Tkinter小部件的窗口中

可以以类似的方式添加其他小部件,每个小部件都位于其自己的
画布
窗口对象中(因为每个小部件只能容纳一个小部件)。您可以通过将
框架
小部件放置在
画布
窗口中,然后将其他小部件放置在其中,来解决该限制

下面的示例显示了如何显示单个
按钮

from PIL import Image, ImageTk
import tkinter as tk

IMAGE_PATH = 'sfondo.png'
WIDTH, HEIGTH = 200, 200

root = tk.Tk()
root.geometry('{}x{}'.format(WIDTH, HEIGHT))

canvas = tk.Canvas(root, width=WIDTH, height=HEIGTH)
canvas.pack()

img = ImageTk.PhotoImage(Image.open(IMAGE_PATH).resize((WIDTH, HEIGTH), Image.ANTIALIAS))
canvas.background = img  # Keep a reference in case this code is put in a function.
bg = canvas.create_image(0, 0, anchor=tk.NW, image=img)

# Put a tkinter widget on the canvas.
button = tk.Button(root, text="Start")
button_window = canvas.create_window(10, 10, anchor=tk.NW, window=button)

root.mainloop()
截图:

编辑 虽然我不知道如何在
Frame
中而不是在
Canvas
中执行此操作,但您可以派生自己的
Frame
子类,以便更轻松地添加多个小部件。我的意思是:

from PIL import Image, ImageTk
import tkinter as tk


class BkgrFrame(tk.Frame):
    def __init__(self, parent, file_path, width, height):
        super(BkgrFrame, self).__init__(parent, borderwidth=0, highlightthickness=0)

        self.canvas = tk.Canvas(self, width=width, height=height)
        self.canvas.pack()

        pil_img = Image.open(file_path)
        self.img = ImageTk.PhotoImage(pil_img.resize((width, height), Image.ANTIALIAS))
        self.bg = self.canvas.create_image(0, 0, anchor=tk.NW, image=self.img)

    def add(self, widget, x, y):
        canvas_window = self.canvas.create_window(x, y, anchor=tk.NW, window=widget)
        return widget


if __name__ == '__main__':

    IMAGE_PATH = 'sfondo.png'
    WIDTH, HEIGTH = 350, 200

    root = tk.Tk()
    root.geometry('{}x{}'.format(WIDTH, HEIGTH))

    bkrgframe = BkgrFrame(root, IMAGE_PATH, WIDTH, HEIGTH)
    bkrgframe.pack()

    # Put some tkinter widgets in the BkgrFrame.
    button1 = bkrgframe.add(tk.Button(root, text="Start"), 10, 10)
    button2 = bkrgframe.add(tk.Button(root, text="Continue"), 50, 10)

    root.mainloop()
结果:

更新 我最近才意识到,实际上有一种比创建自定义的
框架
子类更简单的方法,如我前面的编辑所示。诀窍是
place()
一个
标签
,其上的图像位于父
框架的中心
——然后您可以像通常一样自由使用其他几何体管理器,如
pack()
grid()
——如下面的示例代码所示。与需要调用非标准方法(如
add()
)相比,它不仅不那么复杂,而且是一种更“自然”的添加小部件的方法

结果#2


p.S.您可以从下载
sfondo.png
背景图像的副本。

有一种方法可以在
框架中而不是
画布中进行此操作?@user9994167:我不这么认为-请参见我答案中的编辑。有一种方法可以在
框架中而不是
画布中进行此操作?@user9994167:我不这么认为-请参阅我答案中的编辑。