1

I'm writing a simple Python 3 program using tkinter. it should display a background picture and a button.

Here is the code:

import tkinter
from PIL import Image
from PIL import ImageTk

window = tkinter.Tk()
file = Image.open('/Users/dariushmazlumi/Desktop/p.jpg')
img = ImageTk.PhotoImage(file)
background = tkinter.Label(window, image=img)
background.image = img
background.pack()
window.minsize(height=window.winfo_height(), width=window.winfo_width())
number = 0
def buttonclicked():
    global number
    number = number+1
    button.configure(text=number)
button = tkinter.Button(window, text=0, command=buttonclicked)
button.grid(column=1, row=1)
window.mainloop()

Prior to this, I tried using button.pack(), but it shows button under the image, not on it(maybe the image is not background).

Next, I tried using button.grid(). It runs on the terminal with no error, but no visible output! It just runs. I don't know why.

I want my program to display an image and buttons on it (like a desktop for example).

martineau
  • 119,623
  • 25
  • 170
  • 301
  • You can't put tkinter widgets on top of one another with the exception of a `Canvas`, which can contain them (as well as pure graphics), but still not on top of each other. In other words, you can't put a `Button` on top of a `Label`. – martineau Aug 23 '17 at 15:51
  • Possible duplicate of [how to put a image as a background in tkinter in python](https://stackoverflow.com/questions/10158552/how-to-put-a-image-as-a-background-in-tkinter-in-python) – Aran-Fey Aug 23 '17 at 15:54
  • If you run this code, you may notice an error message like `_tkinter.TclError: cannot use geometry manager grid inside . which already has slaves managed by pack`. I think that explains why the code doesn't work clearly enough. – Aran-Fey Aug 23 '17 at 15:55
  • @martineau: you _can_ put tkinter widgets on top of one another, including putting a button on top of a label. It may not be pretty, but there''s nothing to prevent you from doing it. – Bryan Oakley Aug 23 '17 at 16:04
  • @Rawing run the second code. same error? –  Aug 23 '17 at 16:08
  • When I run the code I get the (expected) error "cannot use geometry manager grid inside .". It's expected because, like the complete error says, you're already using `pack`. – Bryan Oakley Aug 23 '17 at 16:09
  • Same mistake, same error. – Aran-Fey Aug 23 '17 at 16:09
  • @martineau I didn't get it. can you write that code? –  Aug 23 '17 at 16:10
  • @Rawing weird! let me re-run my code again. –  Aug 23 '17 at 16:11
  • 1
    The question you are asking is unclear. Are you asking how to put a button on top of a label? Or, are you asking the more general question of how do you use an image as a background for an entire GUI window? – Bryan Oakley Aug 23 '17 at 16:12
  • @Rawing I think you don't have an image in location '/Users/dariushmazlumi/Desktop/p.jpg' ! –  Aug 23 '17 at 16:12
  • @BryanOakley I (think) I know how to use an image as background. I wanted to add button, and now I have trouble with it! –  Aug 23 '17 at 16:16
  • @martineau this is also my question that why my code is not working and how to fix it. –  Aug 23 '17 at 16:19
  • dariushmazlumi: OK, but you need to clarify a little more exactly what you're trying to do: How it should look and how it should work. – martineau Aug 23 '17 at 16:29
  • thank's @martineau . I want to display an image, and buttons on it. –  Aug 23 '17 at 16:31
  • @martineau you mean buttons that have image?nice! but how can I add a number on it? –  Aug 23 '17 at 17:08

1 Answers1

1

I found a simple way to do what you want which is much less complex that what I was suggesting in my comments. The essential steps are: Create a tkinter.Canvas, display the image on it with Canvas.create_image(), next create a Canvas.create_window() and finally put the tkinter.Button in that. Note that each Canvas "window" can only hold one widget, so you'll have to repeat the last two steps if you want to put more than one button on the image.

It may be simpler to understand by checking out the code below:

import tkinter as tk
from PIL import ImageTk, Image

class CanvasButton:
    def __init__(self, canvas):
        self.canvas = canvas
        self.number = tk.IntVar()
        self.button = tk.Button(canvas, textvariable=self.number,
                                command=self.buttonclicked)
        self.id = canvas.create_window(50, 100, width=25, height=25,
                                       window=self.button)
    def buttonclicked(self):
        self.number.set(self.number.get()+1)  # auto updates Button

root = tk.Tk()
root.resizable(width=False, height=False)
root.wm_attributes("-topmost", 1)

imgpath = 'archipelago_big.gif'
img = Image.open(imgpath)
photo = ImageTk.PhotoImage(img)

canvas = tk.Canvas(root, bd=0, highlightthickness=0)
canvas.pack()
canvas.create_image(0, 0, image=photo)

CanvasButton(canvas)  # create a clickable button on the canvas

root.mainloop()

Here's what it looks like after clicking on the button a few times:

screenshot of image displayed by script

martineau
  • 119,623
  • 25
  • 170
  • 301