框架

时间:2019-01-18 08:53:26

标签: 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.Button(label, text="Start")
b.grid(row=8, column=8)

root.mainloop()

如果以这种方式运行代码,则只会在左上角显示一点(即使没有将标签放在其中的框架,也没有任何内容)。如果我将标签parent替换为root,它会将按钮的图像的一小部分显示为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()

或多或少,我遇到了同样的问题,如果我将标签的父级设置为root,则会显示带有彩色边框的按钮。 如果将父级设置为F1,则什么也不会发生;在两种情况下,如果将父级设置为root并移除按钮,则图像将完全显示。 但是我想要的是图像完全显示在框架中,并且在背景图像上显示小部件之后。

1 个答案:

答案 0 :(得分:1)

您可以将图像放置在Canvas上,然后将其放置在Canvas window object上,该图像可以容纳任何Tkinter小部件,然后将其放置在Button上。

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

下面是显示如何显示单个Button的示例:

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, HEIGTH))

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()

屏幕截图:

screenshot of sample code running

修改

虽然我不知道用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()

结果:

screenshot showing two widget displayed on a frame with a background