How to create X menuItems in submenu? Python pystray - python

so i want to have a menu and in this manu a submenu with X Menu items. The X may differ.
i tried:
import pystray
from PIL import Image
def action():
pass
image = Image.open("sej.png")
menu1 = []
for i in range(0,5):
menu1.append(pystray.MenuItem("das", action))
icon = pystray.Icon("name", image, "title",menu=pystray.Menu(
pystray.MenuItem("das",action),
pystray.MenuItem("das2",action),
pystray.Menu(menu1)
))
icon.run()
and got AttributeError: 'list' object has no attribute 'visible'
i noticed that it works when you pass like that
icon = pystray.Icon("name", image, "title",menu=menu1)
but i want it in a submenu
pls help me ;_;

Related

How to get rid of the resize attribute error?

I'd like to know if I did something wrong in my code or if I have to update something cause every single time I try to resize an image I have this: Attribute Error 'PhotoImage' object has no attribute 'resize'.
import tkinter as tk
from PIL import Image, ImageTk
image1 = Image.open("enseigne.JPEG")
image1= ImageTk.PhotoImage(image1)
imageresize = image1.thumbnail((500,500), Image.ANTIALIAS)
imageresize = ImageTk.PhotoImage(imageresize)
limage = tk.Label(app, image=imageresize)
The error means what it says, PhotoImage object does not have resize attribute, then what has? It is the Image object that has resize. You can remove your first PhotoImage(because it uses resize), as its no use:
image1 = Image.open("enseigne.JPEG")
imageresize = image1.thumbnail((500,500), Image.ANTIALIAS)
imageresize = ImageTk.PhotoImage(imageresize)
limage = tk.Label(app, image=imageresize)
If you want shorter code:
image1 = ImageTk.PhotoImage(Image.open("enseigne.JPEG").thumbnail((500,500), Image.ANTIALIAS))
limage = tk.Label(app, image=image1)
Obvious question: You are not calling resize but why are you getting such error? It is because thumbnail uses resize implicitly(based on conditions).

How to make an image clickable in Tkinter?

Currently, the code chooses images from a folder and displays it on the tkinter window. I can click 'Next image' to see the next image from the folder. I would like to make the images clickable, so that it take would take me to a specified link. I can make it clickable but not sure how to bind the different links to each image. It will get confusing if I were to randomize the images(planning to do this later)
import tkinter as tk
from tkinter.filedialog import askdirectory
import os
img_list = []
def save_to_list(event):
click_loc = [event.x, event.y]
print ("you clicked on", click_loc)
img_list.append(click_loc)
def next_img():
img_label.img = tk.PhotoImage(file=next(imgs))
img_label.config(image=img_label.img)
root = tk.Tk()
root.geometry('500x500')
# Choose multiple images
img_dir = askdirectory(parent=root, initialdir="./yoga_Images/", title='Choose folder')
os.chdir(img_dir)
imgs = iter(os.listdir(img_dir))
img_label = tk.Label(root)
img_label.pack()
img_label.bind("<Button-1>",save_to_list)
btn = tk.Button(root, text='Next image', command=next_img)
btn.pack()
next_img()
root.mainloop()
You can simply specify a image object when creating a button.
from PIL import Image, ImageTk
import tkinter as tk
def example():
print("Clickable Image!")
root = tk.Tk()
image = Image.open("image.png")
btnPhoto= ImageTk.PhotoImage(image)
imgBtn = tk.Button(root, image=btnPhoto, command=example)
imgBtn.pack()
root.mainloop()
Here is some code if you want to make multiple clickable images, don't forget to specify your image directory (Apologies for using list comprehensions, I know they are somewhat confusing).
from PIL import Image, ImageTk
import tkinter as tk
import os
def example():
print("Clickable Image!")
root = tk.Tk()
imgDir = "imgs"
images = [ImageTk.PhotoImage(Image.open(os.path.join(imgDir, imgName))) for imgName in os.listdir(imgDir)]
for img in images:
imgBtn = tk.Button(root, image=img, command=example)
imgBtn.pack()
root.mainloop()

How can i resize images in Tkinter using PIL module

i got this code and i get this error:
AttributeError: 'PhotoImage' object has no attribute 'resize'
I have also tried rgrapg = Image.open("risinggrap.jpg") and i get this error: _tkinter.TclError: image "" doesn't exist
rgraph = ImageTk.PhotoImage(Image.open("risinggrap.jpg"))
rgraph = rgraph.resize((200,250),Image.ANTIALIAS)
photoLabe = Label(x, image=rgraph)```
You need to load the image first, resize it, then cast it into ImageTk.PhotoImage. Here is a working example that goes like so:
import tkinter as tk
from PIL import Image, ImageTk
x = tk.Tk()
# 1. load image
image = Image.open("risinggrap.jpg")
# 2. resize it
image = image.resize((200, 250), Image.ANTIALIAS)
# 3. cast it into ImageTk.PhotoImage
rgraph = ImageTk.PhotoImage(image)
photoLabel = tk.Label(x, image = rgraph)
photoLabel.pack(side = "bottom", fill = "both", expand = "yes")
x.mainloop()

PIL: Jump to next photo after one click event

I am preparing data for deep running. So I have to get certain pixel coordinates for each picture. Only one coordinate per photo is required.
So when I use PIL to input one click, I try to implement coordinates so that I can go to the next picture.
However, when I write the code as below, the coordinates are output in duplicate to only one picture, and the next picture does not appear on the screen.
How can I make sure that only one coordinate is recorded on a single picture?
from PIL import Image, ImageTk
import tkinter
import os
URL = './SavedImage/'
imgList = os.listdir(URL)
print(imgList)
width = 852
height = 480
stepW = 852/4
stepH = 480/5
def callback(event):
print("clicked at: ", event.x, event.y)
window = tkinter.Tk(className='pla')
for file in sorted(imgList):
a=True
image = Image.open(os.path.join(URL, file))
print(image)
canvas = tkinter.Canvas(window, width=image.size[0], height=image.size[1])
canvas.pack()
image_tk = ImageTk.PhotoImage(image)
canvas.create_image(image.size[0]//2, image.size[1]//2, image=image_tk)
canvas.bind("<Button-1>", callback)
tkinter.mainloop()
I am not 100% sure I understand what you need but it looks like to me you are trying to get one set of cord's for each image in a list of images.
I would do this by creating a function and a tracking variable to loop through each image on at a time and on click update a new list with the image and cord's then loop to next image.
Let me know if you have any questions.
Example:
from PIL import Image, ImageTk
import tkinter
import os
URL = './SavedImage/'
imgList = os.listdir(URL)
width = 852
height = 480
stepW = 852/4
stepH = 480/5
tracker = 0
list_images_with_cords = [] # added list for final results
def callback(event):
# Added global's.
global tracker,list_images_with_cords
# Used to append final results to list.
list_images_with_cords.append([imgList[tracker], event.x, event.y])
# This tracker lets us go through each item on the list.
tracker += 1
# After appending list go to next image.
open_next()
window = tkinter.Tk(className='pla')
# Creates just one canvas that we can update later.
canvas = tkinter.Canvas(window)
canvas.pack()
def open_next():
# Adding global's.
global image, canvas, image_tk, tracker
# Clearing canvas before drawing new image.
canvas.delete("all")
# Checking for valid index in list.
if tracker < len(imgList):
image = Image.open(os.path.join(URL, imgList[tracker]))
# use config() to update canvas.
canvas.config(width=image.size[0], height=image.size[1])
image_tk = ImageTk.PhotoImage(image)
canvas.create_image(image.size[0]//2, image.size[1]//2, image=image_tk)
canvas.bind("<Button-1>", callback)
else:
# This else statement is just for when we run out of images.
# It will display all the results in a textbox.
canvas.destroy()
txt = tkinter.Text(window, width=25)
txt.pack()
for item in list_images_with_cords:
txt.insert("end", "{}\n\n".format(item))
open_next()
tkinter.mainloop()

Display an image with Tkinter

I am trying to use Tkinter to display an image in Python 2.7. Below is an example of a code I tried to use, which displays all images in the folder (from
http://code.activestate.com/recipes/521918-pil-and-tkinter-to-display-images/ ):
import os, sys
import Tkinter
import Image, ImageTk
def button_click_exit_mainloop (event):
event.widget.quit() # this will cause mainloop to unblock.
root = Tkinter.Tk()
root.bind("<Button>", button_click_exit_mainloop)
root.geometry('+%d+%d' % (100,100))
dirlist = os.listdir('.')
old_label_image = None
for f in dirlist:
try:
image1 = Image.open(f)
root.geometry('%dx%d' % (image1.size[0],image1.size[1]))
tkpi = ImageTk.PhotoImage(image1)
label_image = Tkinter.Label(root, image=tkpi)
label_image.place(x=0,y=0,width=image1.size[0],height=image1.size[1])
root.title(f)
if old_label_image is not None:
old_label_image.destroy()
old_label_image = label_image
root.mainloop() # wait until user clicks the window
except Exception, e:
# This is used to skip anything not an image.
# Image.open will generate an exception if it cannot open a file.
# Warning, this will hide other errors as well.
pass
For instance, a cross (top) will lead to the following displayed image in the Tkinter window (bottom):
I have tried other codes (including some to display live my webcam), they all lead to the same result: I can see an image, it has the correct dimension, but each column has a constant pixel value (the one of the corresponding column of the first row of the original image).

Categories

Resources