Imported libaries causing overlap - python

I'm trying to make an interface using tkxui and tkinter for the modules it doesn't cover (Label, anchors etc)
from urllib.request import urlopen
from PIL import Image, ImageTk
from io import BytesIO
from tkinter import *
import tkxui
win = tkxui.Tk(display=tkxui.FRAMELESS, defaultBorder=True)
win.geometry("700x400")
win.title("Window Title")
win.minsize(700, 400)
win.center()
URL = "http://www.universeofsymbolism.com/images/ram-spirit-animal.jpg"
u = urlopen(URL)
raw_data = u.read()
u.close()
im = Image.open(BytesIO(raw_data))
photo = ImageTk.PhotoImage(im)
When running this code I get AttributeError: type object 'Image' has no attribute 'open'(line 18) as Traceback. It seems like tkinter and PIL are overlapping with the open function.
How can I avoid this?

Solved by importing the needed tkinter modules like this:
from tkinter.constants import *
and
from tkinter import Label

Related

Error 'Image' has no attribute 'open' but it should

Im using PIL and TKinter to open an image. I do not understand why I'm getting this error
import os
import random
from PIL import Image
import time
from tkinter import *
root = Tk()
def timer(mins):
time.sleep(mins * 60)
def anmuViewer():
random_pic = (random.choice(os.listdir("D:/de_clutter/memez/anmu")))
openPic = Image.open('D:/de_clutter/memez/anmu/' + random_pic)
openPic.show()
timer(3)
start_btn = Button(root, text = "Start", command = anmuViewer)
start_btn.pack()
root.mainloop()
what should happen is a tkinter window should pop up with only a button called "start". When I click that button, a new window with the image should pop up. instead I get this error
line 17, in anmuViewer
openPic = Image.open('D:/de_clutter/memez/anmu/' + random_pic)
AttributeError: type object 'Image' has no attribute 'open'
Like Michael Butscher said,
"tkinter.Image" overwrites "PIL.Image" in your module's namespace. Avoid imports with *
But if you must use a wildcard import, importing tkinter before PIL should solve your problem
from tkinter import *
import os
import random
from PIL import Image
import time

Why does child have to import same modules parent did?

My main Python program (script to most) has elaborate import statements I'd rather not repeat in modules I import:
from __future__ import print_function # Must be first import
from __future__ import with_statement # Error handling for file opens
try:
import tkinter as tk
import tkinter.ttk as ttk
import tkinter.font as font
import tkinter.filedialog as filedialog
import tkinter.messagebox as messagebox
PYTHON_VER="3"
except ImportError: # Python 2
import Tkinter as tk
import ttk
import tkFont as font
import tkFileDialog as filedialog
import tkMessageBox as messagebox
PYTHON_VER="2"
# print ("Python version: ", PYTHON_VER)
import subprocess32 as sp
import sys
import os
import time
import datetime
from PIL import Image, ImageTk, ImageDraw, ImageFont
import pickle
from random import shuffle
import getpass # Get user name for file storage
import locale # To set thousands separator as , or .
locale.setlocale(locale.LC_ALL, '') # Use '' for auto
# mserve modules
import location as lc # Home grown module
As my program/script approaches 5,000 lines I've come over to the light side / (Dark side?) and started using imported modules of my own design. The first module is called location.py but!, lo and behold I've had to repeat import statements already imported in the parent program mserve.
EG at header:
from __future__ import print_function # Must be first import
import getpass
import os
import pickle
import time
And just tonight on a new function I'm writing:
import Tkinter as tk
class MsgDisplay:
''' Text Widget with status messages
'''
def __init__(self, title, toplevel, width, height):
self.line_cnt = 0 # Message lines displayed so far
toplevel.update_idletasks() # Get up-to-date window co-ords
x = toplevel.winfo_x()
y = toplevel.winfo_y()
w = toplevel.winfo_width()
h = toplevel.winfo_height()
xd = (w/2) - (width/2)
yd = (h/2) - (height/2)
print('x:',x,'y:',y,'w:',w,'h:',h,
'width:',width,'height:',height,'xd:',xd,'yd:',yd)
''' Mount message textbox window at centered in passed toplevel '''
self.msg_top = tk.Toplevel()
self.textbox = tk.Text(self.msg_top, height=height, width=width)
self.msg_top.geometry('%dx%d+%d+%d'%(width, height, x + xd, y + yd))
# self.textbox.columnconfigure(0, weight=1)
# self.textbox.rowconfigure(0, weight=1)
self.textbox.pack()
self.textbox.insert(tk.END, "Just a text Widget\nin two lines\n")
def Update(self, msg_list):
self.textbox.insert(tk.END, "Just a text Widget\nin two lines\n")
time.sleep(.1)
def Close(self):
self.msg_top.destroy()
The new import I just added:
import Tkinter as tk
Is a shortcut / fudge because production version would need to be:
try:
import tkinter as tk
except ImportError: # Python 2
import Tkinter as tk
Before preaching python 2.7.12 is obsolete please note I'm using Ubuntu 16.04 whose EOL is 2021. Also note we use Windows 2008 Server at work and legacy systems written in COBOL are common so who cares?
I must be doing something wrong because a module that is imported should not have to import what parent already did? In a normal environment the child should know / inherent what the parent already knows.
As an aside, tonight's new class "MsgDisplay" should be in parent and not in child. It was simpler to put the class in the child rather than figuring out how a child could call a parent class.
I must be doing something wrong because a module that is imported should not have > to import what parent already did? In a normal environment the child should know > inherent what the parent already knows.
You are describing a cpp-like include system where declarations are just placed in order in a single translation unit. That doesn't apply to python. Importing the same module everywhere you use it is necessary. Think about importing as binding the modules contents to the local namespace. If you use module A contents in module B you need to import it in B even if module C already imports A and later B. Don't worry too much about performance. Once a module is loaded by python interpreter remaining imports are not very expensive.

Unable to Load an Image from an URL at TKinter

My goal is to display an JPG image from an URL using tkinter python.
This is the stackoverflow link that I used as a reference. But when I try to run the code, I have received a bunch of error such as:
KeyError: b'R0l.......
AttributeError: 'PhotoImage' object has no attribute '_PhotoImage__photo'
Does anyone have the solution to this?
This is the code:
import tkinter as tk
from PIL import Image, ImageTk
from urllib.request import urlopen
import base64
root = tk.Tk()
URL = "http://www.universeofsymbolism.com/images/ram-spirit-animal.jpg"
u = urlopen(URL)
raw_data = u.read()
u.close()
b64_data = base64.encodestring(raw_data)
photo = ImageTk.PhotoImage(b64_data)
label = tk.Label(image=photo)
label.image = photo
label.pack()
root.mainloop()
The first error is not specifying the data parameter within ImageTk.PhotoImage(data=b64_data). However, I'm unsure why PhotoImage is unable to read base64 data.
A workaround would be to use BytesIO from the io module. You can pass in the raw data you read from the image into a BytesIO, open it in Image and then pass that into PhotoImage.
I found the code for opening the image from here.
import tkinter as tk
from PIL import Image, ImageTk
from urllib2 import urlopen
from io import BytesIO
root = tk.Tk()
URL = "http://www.universeofsymbolism.com/images/ram-spirit-animal.jpg"
u = urlopen(URL)
raw_data = u.read()
u.close()
im = Image.open(BytesIO(raw_data))
photo = ImageTk.PhotoImage(im)
label = tk.Label(image=photo)
label.image = photo
label.pack()
root.mainloop()
If anybody has a better answer as to why the encoding fails, it would be a more appropriate answer to this question.
Very similar but easier than Hobbes' answer, you can directly use the data parameter in the ImageTk.PhotoImage constructor:
import tkinter as tk
from PIL import Image, ImageTk
from urllib.request import urlopen
root = tk.Tk()
URL = "http://www.universeofsymbolism.com/images/ram-spirit-animal.jpg"
u = urlopen(URL)
raw_data = u.read()
u.close()
photo = ImageTk.PhotoImage(data=raw_data) # <-----
label = tk.Label(image=photo)
label.image = photo
label.pack()
root.mainloop()

Viewing external images in a list (Tkinter in python)

im trying to learn Python and doing some test apps.
Right now im creating a type of image viewer for viewing external images. But have some problems.
I've successfully worked out on how to view the image. But i need to view it as a function, so the image can be updated.
This is what i use for just viewing the image:
from io import BytesIO
import urllib
import urllib.request
import tkinter as tk
from PIL import Image, ImageTk
imagelinks = []
***** Here is a crawler that provides image urls from a webpage into the above list ***
root = tk.Tk()
listvalue = 1
url = (imagelinks[listvalue])
with urllib.request.urlopen(url) as u:
raw_data = u.read()
im = Image.open(BytesIO(raw_data))
image = ImageTk.PhotoImage(im)
label = tk.Label(image=image)
label.pack()
root.mainloop()
Everything works well, the image 1 from the list shows up properly.
The problem im having is that i want to add a prev and next button which increment the value of listvalue-=1 and +=1 but simply doing that wont work since it wont update the image in the tkinter window.
Also tried with the Tkinter's update() in my buttons function, but didn't help much either.
Anyone got some input on how to get it to work?
Update:
Tried to put it in a function like this. It is resizing the windows to the proper size, but wont show the image.
from io import BytesIO
import urllib
import urllib.request
import tkinter as tk
from PIL import Image, ImageTk
root = tk.Tk()
link='http://img.khelnama.com/sites/default/files/previewimage/features/2013/Aug/IMG- Reliance_logo(1).jpg'
def showimg(currentimg):
url = currentimg
with urllib.request.urlopen(url) as u:
raw_data = u.read()
im = Image.open(BytesIO(raw_data))
image = ImageTk.PhotoImage(im)
label = tk.Label(image=image)
label.pack()
showimg(link)
root.mainloop()
You will need to put your code that retrieves and displays the image in a definition, and pass the list item that it is meant to use as a parameter. That way on a button press, you can increment or decrement the index, and call your own update function you made.
Edit:
Try this then
label = tk.Label()
label.pack()
def showimg(currentimg, label):
url = currentimg
with urllib.request.urlopen(url) as u:
raw_data = u.read()
im = Image.open(BytesIO(raw_data))
image = ImageTk.PhotoImage(im)
label.config(image = image)
showimg(link, label)

How to display a png file from a webpage on a tk label in Python?

I'm new to python and I'm on a windows 7 64 bit with python 3.3. I can display a gif image with the following code. However I can't make it work with png files. How to do that? Thanks.
import urllib
import urllib.request
import tkinter as tk
root = tk.Tk()
url = "http://www.baidu.com/img/bdlogo.gif"
u = urllib.request.urlopen(url)
raw_data = u.read()
u.close()
import base64
b64_data = base64.encodestring(raw_data)
image = tk.PhotoImage(data=b64_data)
label = tk.Label(image=image)
label.pack()
You should use PIL (or pillow). You can find pillow windows binary here.
Try following example after you install pillow:
from io import BytesIO
import urllib
import urllib.request
import tkinter as tk
from PIL import Image, ImageTk
root = tk.Tk()
url = "http://imgs.xkcd.com/comics/python.png"
with urllib.request.urlopen(url) as u:
raw_data = u.read()
im = Image.open(BytesIO(raw_data))
image = ImageTk.PhotoImage(im)
label = tk.Label(image=image)
label.pack()
root.mainloop()

Categories

Resources