Python 2.7, Tkinter and PIL, grab the screen and show the Image I grabbed when I click a button - python-2.7

I've been trying all day to get my program to grab the screen when I click a button then display the image in a label on the screen. For some ridiculous reason or whatever the program works fine before I put the code into a function and run it with the button.
this does not work
import Tkinter, ImageTk, ImageGrab
def takePic():
img = ImageGrab.grab()
dispImg = ImageTk.PhotoImage(img)
label1 = Tkinter.Label(imgFrame, image = dispImg)
label1.pack()
root = Tkinter.Tk()
btn1 = Tkinter.Button(root, text = "Click", command = takePic)
btn1.pack(side = "top")
imgFrame = Tkinter.Frame(root)
imgFrame.pack()
root.mainloop()
this work:
import Tkinter, ImageTk, ImageGrab
root = Tkinter.Tk()
imgFrame = Tkinter.Frame(root)
imgFrame.pack()
img = ImageGrab.grab()
dispImg = ImageTk.PhotoImage(img)
label1 = Tkinter.Label(imgFrame, image = dispImg)
label1.pack()
root.mainloop()
Any1 know why or how to do it damn

Related

Radio Buttons won't select jpg

Shortened the code to minimum for the question. I want to toggle between images to apply on the canvas using radiobuttons. The code will only apply the images if I enter the image name, (ex. tkimg2) into the 'stamp' event. The radiobuttons are not selecting the images, nor does the link work if I enter the image name in picture=[]. Do you know why the image name is sufficient in one location and not the other and why the radiobuttons don't work? Thank you for any help
from Tkinter import *
import PIL
from PIL import ImageTk, Image
import random
import os.path
root = Tk()
shapes = []
#load 2 images for stamping
__dir__ = os.path.dirname(os.path.abspath(__file__))
filename = os.path.join(__dir__, 'balloon.jpg')
img = PIL.Image.open(filename)
tkimg=PIL.ImageTk.PhotoImage(img)
filename2 = os.path.join(__dir__, 'bird1.jpg')
img2 = PIL.Image.open(filename2)
tkimg2=PIL.ImageTk.PhotoImage(img2)
picture =[]
image=picture
# A Radiobutton to toggle between images
radio = [0]*2
v = IntVar()
def call():
if int(float(str(v.get())))==1:
picture=tkimg
else:
picture=tkimg2
Label(root, text ="Select an image to place.").grid(row=1, column=0,
columnspan=5, sticky=S)
R1=Radiobutton(root, text="Bird 1", variable=v, value=1, command=call)
R1.grid(row=2, column=0, sticky=N+E)
R1.select()
R2=Radiobutton(root, text="Bird 2", variable=v, value=2, command=call)
R2.grid(row=2, column=1, sticky=N+E)
# A canvas for mouse events and image drawing
canvas = Canvas(root, height=1000, width=1000, bg='#2EEAFF')
canvas.grid(column=5, row=0, rowspan=4, sticky=W)
# Bind a function to the left mouse button down event.
def stamp(event):
canvas.create_image(event.x,event.y,image)
canvas.bind('<ButtonPress-1>', stamp)
# Enter event loop
root.mainloop()
I removed most of the code not relevant to the question and changed the images to ordinary PhotoImages for simplicity. Also I changed the first positioning of the image on the canvas.
If you want to assign a value to a variable inside a function you'll have to make it global or it will not work. The variable will be defined in the local function scope and will be garbage collected when the function ends.
I don't think you can change an image on a canvas by updating the variable you used to create it. That's how a StringVar functions.
As the image is the only widget on the canvas I delete ALL items and then create a new image when I toggle images.
Also: I use Python 3.6 so I spell tkinter without the capital T.
from tkinter import *
root = Tk()
#load 2 images for stamping
tkimg = PhotoImage(file='test.gif') # Test image
tkimg2 = PhotoImage(file='tesu.gif') # Test image
# A Radiobutton to toggle between images
v = IntVar()
def call():
canvas.delete(ALL)
if v.get() == 1:
canvas.create_image((2, 2), image=tkimg, anchor=NW)
else:
canvas.create_image((2, 2), image=tkimg2, anchor=NW)
Label(root, text ="Select an image to place.").grid(row=1, column=0, columnspan=5, sticky=S)
R1=Radiobutton(root, text="Bird 1", variable=v, value=1, command=call)
R1.grid(row=2, column=0, sticky=N+E)
R1.select()
R2=Radiobutton(root, text="Bird 2", variable=v, value=2, command=call)
R2.grid(row=2, column=1, sticky=N+E)
# A canvas for mouse events and image drawing
canvas = Canvas(root, height=200, width=200, bg='#2EEAFF')
canvas.grid(column=5, row=0, rowspan=4, sticky=W)
canvas.create_image((2, 2), image=tkimg, anchor=NW)
# Enter event loop
root.mainloop()

New window opens on click but does not show anything[Tkinter]

I am using root as the primary window in which when one puts a question, then the answer from either Wikipedia or WolframAlpha is shown in a new window. But, here what happens is that the new window properly opens but does not show anything.
from Tkinter import *
import wolframalpha
import wikipedia
root=Tk()
root1=Tk()
def getinput():
global entry
answer = StringVar()
ques=entry.get()
try:
#wolframalpha
app_id = myappid #value of myappid is there in the original code
client = wolframalpha.Client(app_id)
res = client.query(ques)
answer.set(next(res.results).text)
label=Label(root1, textvariable=answer)
except:
#wikipedia
answer.set(wikipedia.summary(ques).encode('utf-8'))
label=Label(root1, textvariable=answer)
label.pack(side=BOTTOM)
root.geometry("350x80+300+300")
label=Label(root, text="Hi! I am Python Digital Assistant. How can I help you today?")
entry=Entry(root)
submit=Button(root, text="Submit", bg="light green", command=getinput)
exit1=Button(root, text="Exit", bg="red", fg="white", command=root.destroy)
label.pack()
entry.pack(fill=X)
entry.focus_set()
submit.pack(side=LEFT)
exit1.pack(side=LEFT)
root.mainloop()
You don't have to call TK twice you have to use toplevel to achieve that , with that when you provide the question and click on the submit method the answer will pop up in the Toplevel window.
from Tkinter import *
import wolframalpha
import wikipedia
root=Tk()
def getinput():
top = Toplevel()
top.geometry("500x500")
global entry
answer = StringVar()
ques=entry.get()
try:
#wolframalpha
app_id = myappid #value of myappid is there in the original code
client = wolframalpha.Client(app_id)
res = client.query(ques)
answer.set(next(res.results).text)
label=Label(top, textvariable=answer)
except:
#wikipedia
answer.set(wikipedia.summary(ques).encode('utf-8'))
label=Label(top, textvariable=answer)
label.pack(side=TOP)
root.geometry("350x80+300+300")
label=Label(root, text="Hi! I am Python Digital Assistant. How can I help you today?")
entry=Entry(root)
submit=Button(root, text="Submit", bg="light green", command=getinput)
exit1=Button(root, text="Exit", bg="red", fg="white", command=root.destroy)
label.pack()
entry.pack(fill=X)
entry.focus_set()
submit.pack(side=LEFT)
exit1.pack(side=LEFT)
root.mainloop()

Adding notebook tabs in tkinter - how do I do it with a class-based structure? (Python 2)

I want each tab to come from it's own class (classes are in their own files - I am just testing the first one for now).
Here is what I tried:
tab1.py
from Tkinter import *
import Tkinter as tk
class Tab(tk.Frame):
def __init__(self, master):
tk.Frame.__init__(self, master)
fr = Frame(self).pack()
Label(fr, text="one", bg='red', bd=2).pack()
Label(fr, text="two", bg='yellow', bd=2).pack()
if __name__ == '__main__':
root = Tk()
frame = Frame(root).pack()
Tab(frame)
Button(frame, text='only if class', command=root.destroy).pack()
mainloop()
noteBook.py
from Tkinter import *
from ttk import *
from tab1 import Tab
root = Tk()
note = Notebook(root)
main_frame = Frame(note)
button1 = Button(main_frame, text='test').pack()
#tab1 = Tab(note)
tab1 = Frame(note)
tab2 = Frame(note)
tab3 = Frame(note)
Tab(tab1)
Button(tab1, text='Exit', command=root.destroy).pack()
note.add(tab1, text = "Tab One", compound=TOP)
note.add(tab2, text = "Tab Two")
note.add(tab3, text = "Tab Three")
note.pack()
root.mainloop()
exit()
run with:
python2.7 noteBook.py
The problem is that the content of tab1.py does not appear within the first tab, it instead appears within the frame that contains the whole noteBook.
Also when running tab1.py directly with python2.7 noteBook.py I need it to behave properly meaning from what it has now it should show just the tab with an extra button from the if __name___... part.
I have come accros multiple examples but only found one that was what I want but it had no working solution and it was for python3 - I would like python2. python3 question with no working answer Thanks.
The problem is this line of code:
fr = Frame(self).pack()
When you do the above, fr is None because .pack() returns None (because x().y() returns the value of y()). Later, you do this:
Label(fr, text="one", bg='red', bd=2).pack()
Since fr is None, the label is created in the root window.
Unrelated to the problem, here's some advice: you are creating too many frames. You don't need fr inside of Tab, and you don't need tab1, tab2, or tab3
Here's all you need for Tab:
class Tab(tk.Frame):
def __init__(self, master):
tk.Frame.__init__(self, master, background="pink")
Label(self, text="one", bg='red', bd=2).pack()
Label(self, text="two", bg='yellow', bd=2).pack()
To add it to the notebook, you just need two lines:
tab1 = Tab(note)
note.add(tab1, text = "Tab One", compound=TOP)
This works perfectly and just for fun I've illustrated the populating of tabs 2 and 3 althought I just reused the same class for simplicity here. The goal was to be able to run the tabs directly to view them alone during developpement without having to run the whole thing every time.
noteBook.py
from Tkinter import *
from ttk import *
from tab1 import Tab
root = Tk()
note = Notebook(root)
main_frame = Frame(note)
button1 = Button(main_frame, text='test').pack()
tab1 = Frame(note)
tab2 = Frame(note)
tab3 = Frame(note)
Tab(tab1)
Tab(tab2)
Tab(tab3)
Button(tab1, text='Exit', command=root.destroy).pack()
note.add(tab1, text = "Tab One", compound=TOP)
note.add(tab2, text = "Tab Two")
note.add(tab3, text = "Tab Three")
note.pack()
root.mainloop()
exit()
tab1.py
import Tkinter as tk
class Tab(tk.Frame):
def __init__(self, parent_widget):
tk.Frame.__init__(self, parent_widget)
self.fr = tk.Frame(parent_widget, width=200, height=200, bg='pink', bd=2)
tk.Label(self.fr, text="one", bg='red', bd=2).pack()
tk.Label(self.fr, text="two", bg='yellow', bd=2).pack()
self.fr.pack() # this packing must be done after 2 above packings
if __name__ == '__main__':
root = tk.Tk() # the app window
main_frame = tk.Frame(root, height=200, width=200, bg='blue', bd=2) # main frame
Tab(main_frame) # instatiate Tab(), sending main_frame as the parent_widget
tk.Button(main_frame, text='only if class', command=root.destroy).pack()
main_frame.pack() # display main frame on window
tk.mainloop()

How can i display a resized image in python tkinter

I'm developing a GUI in Python using Tkinter to learn image processing. GUI's process flow would be as
Load image (jpg|png|...) => Resize/ thumbnail image (240 * 240) => Preview image
from Tkinter import *
import PIL
class Window:
def __init__(self, master):
master.title("Image Processing test")
master.minsize(800, 400)
from PIL import Image
im = Image.open("IMG_0562.png")
size = 240, 240
im.thumbnail(size)
p = im.tobytes()
# photo = PhotoImage(file="IMG_0562.gif")
# photo = BitmapImage(data=p)
w = Label(root, image=photo, width=240, height=240).grid(row=20, column=2)
self.photo = photo
root = Tk()
window = Window(root)
root.mainloop()
My problem is I couldn't get the image in a proper format to use it in Label. As Label only accepts PhotoImage and BitmapImage. PhotoImage doesn't support png or jpg file. So I used Image from PIL to load and resize my colored image. I've tried Image.tobitmap() and Image.tobytes() too but not useful in this case.
Solved the problem by saving the image in memory using io.BytesIO()
from Tkinter import *
from PIL import Image
import io
class Window:
def __init__(self, master):
master.title("Image Processing test")
master.minsize(800, 400)
im = Image.open("IMG_0562.png")
size = 240, 240
im.thumbnail(size)
b = io.BytesIO()
im.save(b, 'gif')
p = b.getvalue()
photo = BitmapImage(data=p)
w = Label(root, image=photo, width=240, height=240).grid(row=20, column=2)
self.photo = photo
root = Tk()
window = Window(root)
root.mainloop()

how to display a form within a frame using python and tkinter

I have created a notebook(file1.py) using python and tkinter. This notebook has three tabs A,B,C. I have another python file(file2.py) which contains few text fields. Now I am looking for a way to display the contents of the other file2.py within the tab A which is in file1.py.The following is the code I used in file1.py
import tkinter as tk
import tkinter.ttk as ttk
root = tk.Tk()
# use width x height + x_offset + y_offset (no spaces!)
root.geometry("%dx%d+%d+%d" % (300, 200, 100, 50))
root.title('test the ttk.Notebook')
nb = ttk.Notebook(root)
nb.pack(fill='both', expand='yes')
# create a child frame for each page
f1 = tk.Frame(bg='red')
f2 = tk.Frame(bg='blue')
f3 = tk.Frame(bg='green')
# create the pages
nb.add(f1, text='A')
nb.add(f2, text='B')
nb.add(f3, text='C')
# put a button widget on child frame f1 on page1
btn1 = tk.Button(f1, text='button1')
btn1.pack(side='left', anchor='nw', padx=3, pady=5)
root.mainloop()
File2.py
import sys
from PyQt4 import Qt
from taurus.qt.qtgui.application import TaurusApplication
app = TaurusApplication(sys.argv)
panel = Qt.QWidget()
layout = Qt.QHBoxLayout()
panel.setLayout(layout)
from taurus.qt.qtgui.panel import TaurusForm
panel = TaurusForm()
model = [ 'test/i1/1/%s' % p for p in props ]
panel.setModel(model)
panel.show()
sys.exit(app.exec_())
I am new to using tkinter and python so could you let me know how I could achieve it. Also in the other file(file2.py) I have few import statements like 'import sys" etc.Thanks.
You cannot mix those two files. One uses Tkinter, one uses PyQT. Those two libraries are incompatible with each other.