tkinter button not showing image - image

Hi i am trying to put an image as the background on one of my buttons, i have already done this on lots of other buttons in my main window but this particular button sits inside a top level window and the image doesn't load like it should, does anyone know why? (i have also tried defining the width and height of the button but that still doesn't show the image)
def rec_window():
recw = Toplevel(width=500,height=500)
recw.title('Record To.....')
img1 = PhotoImage(file="C:/Users/Josh Bailey/Desktop/pi_dmx/Gif/mainmenu.gif")
Button(recw, image=img1, command=rec_preset_1).grid(row=1, column=1)
Button(recw, text="Preset 2", bg = 'grey70',width=40, height=12,command=rec_preset_2).grid(row=1, column=2)
Button(recw, text="Preset 3", bg = 'grey70',width=40, height=12,command=rec_preset_3).grid(row=2, column=1)
Button(recw, text="Preset 4", bg = 'grey70',width=40, height=12,command=rec_preset_4).grid(row=2, column=2)
Button(recw, text="Cancel", bg='grey70', width=20, height=6, command=recw.destroy). grid(row=3,column=1,columnspan=2, pady=30)

Depending on how the rest of your program is structured, your image might be getting cleared by garbage-collection:
From http://effbot.org/tkinterbook/photoimage.htm
Note: When a PhotoImage object is garbage-collected by Python (e.g.
when you return from a function which stored an image in a local
variable), the image is cleared even if it’s being displayed by a
Tkinter widget.
To avoid this, the program must keep an extra reference to the image
object. A simple way to do this is to assign the image to a widget
attribute, like this:
label = Label(image=photo)
label.image = photo # keep a reference!
label.pack()
In your case, you can start your function by declaring img1 as a global variable to retain a reference:
global img1
or, if you already have img1 elsewhere in your program:
img1 = PhotoImage(file="C:/Users/Josh Bailey/Desktop/pi_dmx/Gif/mainmenu.gif")
img1Btn = Button(recw, image=img1, command=rec_preset_1)
img1Btn.image = img1
img1Btn.grid(row=1, column=1)

Related

Python: update plot with image with slider weight

I loaded a .nii file in my application.
def show(self):
image = SimpleITK.ReadImage(file_name)
t1 = SimpleITK.GetArrayFromImage(image)
t2 = color.rgb2gray(t1[w.get()])
print(w.get())
print(t2.shape)
plt.ion()
fig = plt.figure()
ax = fig.add_subplot(111)
line1 = ax.imshow(t2, cmap='gray')
This function it is called when I move the slider and show me in a new figure the slice of brain.(the screenshot of application is attach here: [1]: https://i.stack.imgur.com/vzDJt.png)
I need to update the same figure/plot, it is possible?
That should work, but I would not be calling ReadImage and GetArrayFromImage every time show gets called. You don't want to be re-loading and converting the image each time your widget changes. Do those thing once, when the application starts.
If you look at the SimpleITK-Notebooks that's pretty much how images are displayed in Jupyter notebooks.
http://insightsoftwareconsortium.github.io/SimpleITK-Notebooks/Python_html/04_Image_Display.html
The section 'Inline display with matplotlib' uses imshow to display images.

Retrieve image from TinyDB via a Python function

I know TinyDB can't store images but you can store the image file path. I have done that and I want to make my application display an image when a button is clicked. I have successfully added the file path to the database and I have tested the output using print and the file path displays (so it is working to that extent). Also no error message come up. The function is as follows:
def showcar():
getcar = cardb.get(where("img_id") == "1")
img = Image.open("{car_img}".format(**getcar))
pic = ImageTk.PhotoImage(img)
lblimage.configure(image=pic)
When I click the button the function is assigned to, nothing happens. But when I use the exact same code out of the function like so:
getcar = cardb.get(where("img_id") == "1")
img = Image.open("{car_img}".format(**getcar))
pic = ImageTk.PhotoImage(img)
btnshow = Button(root, text="Show All", command=lambda: lblimage.configure(image=pic))
Then the image displays when the button is clicked. How can I make the application call the image path from TinyDB in a function?

How do I add an image in the QToolbar using PyQt?

I'm creating a tool bar in PyQt. How it looks now is:
(HomeButton).............................................(ExitButton)..|
I want to use the space in the middle to put in an image/logo -- with no function so it looks like:
(homebutton)......[IMAGE/LOGO_HERE]......(exitbutton)..|
I've tried to do this by adding a widget with an image but it's not showing up. My code is:
logo = QWidget()
logolabel = QLabel(p3logo)
logopixmap = QPixmap(self.LOGO)
logolabel.setPixmap(QPixmap(self.LOGO))
logolabel.setPixmap(logopixmap)
logo.resize(logopixmap.width(),logopixmap.height())
###logoAction = QAction(QIcon('logo.png'), 'Logo', self)
spacer = QWidget()
spacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
exitAction = QAction(QIcon('exit.png'), 'Exit', self)
exitAction.setShortcut('Ctrl+X')
exitAction.triggered.connect(self.exitClicked)
homeAction = QAction(QIcon('home.png'), 'Home', self)
homeAction.setShortcut('Ctrl+H')
homeAction.triggered.connect(self.homeClicked)
self.toolbar = self.addToolBar('Toolbar')
self.toolbar.addAction(homeAction)
self.toolbar.addWidget(logo)
###self.toolbar.addAction(logoAction)
self.toolbar.addWidget(spacer)
self.toolbar.addAction(exitAction)
self.toolbar.addSeparator()
I also tried to add it in as an 'icon' but it was resized to the same size as the home/exit buttons making it hardly visible.
Your code example is effectively just adding an empty widget to the toolbar, because the label has not been put inside a layout. It looks like it can be fixed by getting rid of the container widget and simply adding the label directly:
self.toolbar.addWidget(logolabel)

images wont unload - please assist

I have some code here that when an image (which is my button) is clicked, a new image randomly appears. This is due to a table I created with some images inside.
local animalPic
local button = display.newImageRect ("images/animalBtn.jpg", 200, 200)
button.x = 250
button.y = 50
local myPics = {"images/animal1.png", "images/animal2.png"}
function button:tap (event)
local idx = math.random(#myPics)
local img = myPics[idx]
local animalPic = display.newImage(img)
animalPic.x = contentCenterX
animalPic.y = contentCenterY
end
button:addEventListener ("tap", button)
The problem with it is the graphics just keep piling up when I click the button. The correct behavior should be -
Button is clicked and an image is shown while removing the previous image. How do I incorporate this behavior? I already tried the removeSelf command and it doesnt work......Any help appreciated.
You declare animalPic each time you enter function. You should declare it once and then remove it and replace it by another.
It should be:
local animalPic
function button:tap (event)
local idx = math.random(#myPics)
local img = myPics[idx]
animalPic:removeSelf()
animalPic = nil
animalPic = display.newImage(img)
animalPic.x = contentCenterX
animalPic.y = contentCenterY
end
When you call display.newImage(), you are adding a new image. The problem is that you need to remove/hide the original one. Perhaps you really need two objects - one for the current image and one for the tap event. When the tap event occurs, hide the old image and display the new one. An alternative would be to load all the images in their own imageRects and then toggle them on and off.

Add an image button to top level window Tkinter

I'm building a small GUI application, that once a button is clicked a new top level window will open and it should display images for buttons.
I can get the image button to work on the root window, but not on the top level window. Only a blackbox appears.
I have a generic button on both windows and they do work.
I'm new to Python.
import Tkinter
from Tkinter import *
from PIL import ImageTk, Image
root = Tkinter.Tk()
root.title("First Window")
root.configure(background = "black")
def new_window():
win2 = Toplevel(root)
win2.geometry("650x350+50+40")
win2.title("Second Window!")
win2.configure(background = "white")
def close1():
win2.destroy()
img1 = ImageTk.PhotoImage(Image.open("./images/close.gif"))
c1 = Button(win2, image = img1, bg ="black", command = close1)
c1.grid(row = 1)
c2= Tkinter.Button(win2, text='close', command = close1)
c2.grid(row = 2)
nw = Tkinter.Button(root, text = 'New Window' , command = new_window)
nw.grid(row = 1)
def close3():
root.destroy()
img3 = ImageTk.PhotoImage(Image.open("./images/close.gif"))
c3 = Button(root, image = img3, bg ="black", command = close3)
c3.grid(row = 2)
root.mainloop()
When you create the new toplevel, you are using a local variable to refer to the image. Because of this, when the method exits, the garbage collector will delete the image. You need to save a reference in a global variable, or some other way to protect it from the garbage collector
A common way to save a reference is to make it an attribute of the button:
img1 = ImageTk.PhotoImage(...)
c1 = Button(...)
c1.image = img1

Resources