I am trying to learn Tkinter and python. How can I open multiple images and save it on multiple canvas in Python 3? I also want the image to fit just perfect on to the size of the canvas.
Could someone show me to do this using simple code.
import tkinter
from tkinter import filedialog
import os
#from PIL import ImageTk, Image
from tkinter import *
import PIL.Image
from tkinter.filedialog import askopenfilename
import py_compile
mainWindow =tkinter.Tk()
mainWindow.title("Image")
mainWindow.geometry('640x480+800+200')
mainWindow.columnconfigure(0, weight=3)
mainWindow.columnconfigure(1, weight=1)
mainWindow.columnconfigure(2, weight=1)
mainWindow.rowconfigure(0, weight=3)
mainWindow.rowconfigure(1, weight=3)
mainWindow.rowconfigure(2, weight=5)
mainWindow.rowconfigure(3, weight=3)
leftFrame = tkinter.LabelFrame(mainWindow, text='PICTURE')
leftFrame.grid()
canvas = tkinter.Canvas(leftFrame, relief='sunken', borderwidth=5, bg= 'white', width=100, height=100)
canvas.grid(row=1, column=0)
canvas2 = tkinter.Canvas(leftFrame, relief='sunken', borderwidth=5, bg= 'white', width=100, height=100)
canvas2.grid(row=2, column=0)
canvas3 = tkinter.Canvas(leftFrame, relief='sunken', borderwidth=5, bg= 'white', width=100, height=100)
canvas3.grid(row=1, column=1)
canvas4 = tkinter.Canvas(leftFrame, relief='sunken', borderwidth=5, bg= 'white', width=100, height=100)
canvas4.grid(row=2, column=1)
def clicked():
print('hello')
open_img()
def open_img():
global photo
filename = filedialog.askopenfilename(initialdir = "E:/Images", filetypes = ())
photo = tkinter.PhotoImage(file=filename)
photo = photo.subsample(3,3)
canvas.create_image(0,0, anchor=CENTER, image=photo)
rightFrame = tkinter.LabelFrame(mainWindow, text='MENU')
rightFrame.grid()
button1 = tkinter.Button(rightFrame , text="Open", command=clicked)
button1.grid(row=1, column=2)
mainWindow.mainloop()
You would use one class with each image creating an instance of that class, but since you have not used a class and so are probably not familiar with the class structure, the following code combines everything into one class. Since I don't have the images, this opens a new Toplevel with a related "close" button instead of an image, each time the "open" button is clicked.
try:
import Tkinter as tk ## Python 2.x
except ImportError:
import tkinter as tk ## Python 3.x
from functools import partial
class OpenToplevels():
""" open and close additional Toplevels with a button
"""
def __init__(self):
self.root = tk.Tk()
self.button_ctr=0
but=tk.Button(self.root, text="Open a Toplevel",
command=self.open_another)
but.grid(row=0, column=0)
tk.Button(self.root, text="Exit Tkinter", bg="red",
command=self.root.quit).grid(row=1, column=0, sticky="we")
self.root.mainloop()
def close_it(self, id):
id.destroy()
def open_another(self):
self.button_ctr += 1
id = tk.Toplevel(self.root)
id.title("Toplevel #%d" % (self.button_ctr))
tk.Button(id, text="Close Toplevel #%d" % (self.button_ctr),
command=partial(self.close_it, id),
bg="orange", width=20).grid(row=1, column=0)
Ot=OpenToplevels()
Related
I am making a text base game and would like to get a new root window on the click of a button while simultaneously closing the original one?
#Packages
import tkinter as tk
from tkinter import ttk, BOTTOM
from PIL import ImageTk, Image
#Create Window
root = tk.Tk()
root.geometry("360x740")
root.resizable(True, True)
root.title("Box")
root.configure(bg="black")
#Load Image
canvas = tk.Canvas(root, width=360, height=360, bg="black")
tk.Canvas(bg="black")
canvas.pack()
img = ImageTk.PhotoImage(Image.open("sample_image.jpg"))
canvas.create_image(180, 200, image=img)
#Create Text Widget
T = tk.Text(root, height=10, width=52, bg="black", fg="white")
l = tk.Label(root, text="Hard Living by Amsha", fg="white", bg="black")
l.config(font=(None, 14,))
story = """
"""
l.pack()
T.pack()
#Continue Button
yes_button = ttk.Button(root, text="Continue", command=lambda: next_window())
yes_button.pack(pady=75, side=BOTTOM)
T.insert(tk.END, story)
root.mainloop()
def next_window():
root.quit()
root = tk.Tk()
root.geometry("360x740")
root.resizable(True, True)
root.title("Hard Living")
root.configure(bg="black")
root.mainloop()
Here's the code I am using (one example):
import os
import win32api
from tkinter import *
from tkinter import ttk
from tkinter import filedialog
from PIL import ImageTk, Image
#...
def mainloop():
root = Tk()
mainframe = ttk.Frame(root)
mainframe.grid(column=0, row=0, sticky=(N,W,E,S))
root.columnconfigure(0, weight=1)
root.rowconfigure(0,weight=1)
#...
pillarImg = ImageTk.PhotoImage(Image.open("pillars.png"))
pillars_label = ttk.Label(root)
pillars_label['image'] = pillarImg
#...
rldir_entry = ttk.Entry(mainframe, width=40, textvariable=rldir)
pillars_entry = ttk.Entry(mainframe, width=10, textvariable=Pillars)
#...
rldir_entry.grid(column=0, row=0, columnspan=5, sticky=(W,E))
pillars_label.grid(column=0, row=1, columnspan=2, sticky=(N,W,E,S))
pillars_entry.grid(column=0, row=2, sticky=(W,E))
#...
root.mainloop()
mainloop()
This code results in the two entry boxes being above the image, even though I set the grid to have the image between the two entry boxes...?
Here's a pic of what I mean:
Ahh I just figured it out.
here:
pillars_label = ttk.Label(root)
I added the label to root.
While here:
rldir_entry = ttk.Entry(mainframe, width=40, textvariable=rldir)
the entry boxes are in the mainframe. lol.
I need to center two buttons, and I may need to center more buttons, but I can't center more than one button, so I need help...
Here's the code:
from tkinter import *
from tkinter.ttk import *
import os
root = Tk()
root.geometry("325x100")
def click():
pass
def click2():
pass
button = Button(root, text="Button 1", command=click, width=25)
button.grid(row=0, column=0)
button2 = Button(root, text="Button 2", command=click2, width=25)
button2.grid(row=1, column=0)
root.grid_rowconfigure(0, weight=1)
root.grid_columnconfigure(0, weight=1)
root.mainloop()
I did a bit of testing and here is what i have come up with. I have used the .pack() method instead of the .grid() method and i have also used a frame. I am kind of new to Python, but here it is :)
from tkinter import *
from tkinter.ttk import *
import os
root = Tk()
root.geometry("325x100")
def click():
pass
def click2():
pass
frame = Frame(root)
frame.pack(padx = 20, pady = 12)
button = Button(root, text="Button 1", command=click, width=25)
button.pack()
button2 = Button(root, text="Button 2", command=click2, width=25)
button2.pack()
root.mainloop()
Here is what it looks like:
Don't add weight to the first row. It is forcing it to expand. You may want to consider something else, though. You may eventually put something else on that row, and you may need that thing to expand the row. In it's current state this will cause a "catch 22" for you. You may want to consider creating a frame to hold all of the buttons, and put that entire frame on the root.
immediate fix:
from tkinter import *
from tkinter.ttk import *
import os
root = Tk()
root.geometry("325x100")
def click():
pass
def click2():
pass
button = Button(root, text="Button 1", command=click, width=25)
button.grid(row=0, column=0)
button2 = Button(root, text="Button 2", command=click2, width=25)
button2.grid(row=1, column=0)
#this is forcing the top row to expand
#root.grid_rowconfigure(0, weight=1)
root.grid_columnconfigure(0, weight=1)
root.mainloop()
possibly a better way:
from tkinter import *
from tkinter.ttk import *
import os
root = Tk()
root.geometry("325x100")
def click():
pass
def click2():
pass
#by not defining row and column in grid()
#~ row will be the next available one and column will be 0
button_frame = Frame(root)
button_frame.grid(sticky='nswe')
button_frame.grid_columnconfigure(0, weight=1)
#you only need to store a reference if you intend to change/reference/destroy/forget these
#if they are going to always be a button, as initially defined, a reference is dead weight
Button(button_frame, text="Button 1", command=click, width=25).grid()
Button(button_frame, text="Button 2", command=click2, width=25).grid()
#now you can use grid_rowconfigure without it destroying your button layout
root.grid_rowconfigure(0, weight=1)
root.grid_columnconfigure(0, weight=1)
root.mainloop()
On create window, tkinter.scrolledtext look up for SearchIP() to insert but never update layout. When I have different input for SearchIP() method never show up. It only shows the initial value.
Note: I added a couple of print statements to watch if SearchIP() returns the right thing, which is the case, for example for 'www.google.com' it prints '216.58.192.4', but this value never shows up in ScrolledText.
import socket
try:
# for Python2
import Tkinter as tk
import ScrolledText as tkst
except ImportError:
# for Python3
import tkinter as tk
import tkinter.scrolledtext as tkst
global Filename
root = tk.Tk()
frame = tk.Frame(root,width=100)
label = Label(root,text="http://")
label.grid(row=0,column=0)
entryVar = tk.StringVar()
entry = Entry(root,width=50,textvariable=entryVar)
entry.grid(row='0',column='1',columnspan=8)
def SearchIP():
print(entryVar.get())
add = str(entryVar.get())
ip_a = socket.gethostbyname(add)
print(str(ip_a))
return str(ip_a);
button1 = Button(root, text="Search IP", command=SearchIP)
button1.grid(row=1, column=0)
button2 = Button(root, text="DNS Recon")
button2.grid(row=1, column=1)
button3 = Button(root, text="Port Scanner")
button3.grid(row=1, column=2)
button4 = Button(root, text="Web Crawl")
button4.grid(row=1, column=3)
button5 = Button(root, text="Email Gathering")
button5.grid(row=1, column=4)
frame.grid(row=2, column=0, columnspan=30, rowspan=30)
edit_space = tkst.ScrolledText(
master = frame,
wrap = 'word', # wrap text at full words only
width = 45, # characters
height = 10, # text lines
# background color of edit area
)
# the padx/pady space will form a frame
edit_space.pack(fill='both', expand=True, padx=8, pady=8)
root.title("E-Z Security Audting")
root.resizable(True, True)
edit_space.insert('insert', SearchIP())
root.mainloop()
I also tried to modify the SearchIP() method and remove the return statement, but then I got this error:
File "C:/Users/kero/Desktop/Robert_HodgesKeroles_Hakeem_secproject/secproject/newUser_Interface.py", line 50, in <module>
edit_space.insert('insert', SearchIP())
File "C:\Python27\lib\lib-tk\Tkinter.py", line 2986, in insert
self.tk.call((self._w, 'insert', index, chars) + args)`
SearchIP after modification
def SearchIP():
add = str(entryVar.get())
ip_a= socket.gethostbyname(add)
You have to use insert() inside SearchIP()
import socket
try:
# for Python2
import Tkinter as tk
import ScrolledText as tkst
except ImportError:
# for Python3
import tkinter as tk
import tkinter.scrolledtext as tkst
# --- functions ---
def SearchIP():
add = entryVar.get()
ip_a = socket.gethostbyname(add)
edit_space.insert('insert', ip_a + "\n")
# --- main ---
root = tk.Tk()
root.title("E-Z Security Audting")
root.resizable(True, True)
frame = tk.Frame(root, width=100)
frame.grid(row=2, column=0, columnspan=30, rowspan=30)
label = tk.Label(root, text="http://")
label.grid(row=0, column=0)
entryVar = tk.StringVar()
entry = tk.Entry(root, width=50, textvariable=entryVar)
entry.grid(row=0, column=1, columnspan=8)
button1 = tk.Button(root, text="Search IP", command=SearchIP)
button1.grid(row=1, column=0)
button2 = tk.Button(root, text="DNS Recon")
button2.grid(row=1, column=1)
button3 = tk.Button(root, text="Port Scanner")
button3.grid(row=1, column=2)
button4 = tk.Button(root, text="Web Crawl")
button4.grid(row=1, column=3)
button5 = tk.Button(root, text="Email Gathering")
button5.grid(row=1, column=4)
edit_space = tkst.ScrolledText(
master=frame,
wrap='word', # wrap text at full words only
width=45, # characters
height=10, # text lines
# background color of edit area
)
edit_space.pack(fill='both', expand=True, padx=8, pady=8)
root.mainloop()
Using Tkinter,How can I toggle between images when a button is click. Having this code as reference, I can only load one image but I don't know how to make it behave the way I need.
from Tkinter import *
import ttk
from PIL import ImageTk, Image
def showImage(*args):
lbl['image'] = image_tk
root = Tk()
c = ttk.Frame(root, padding=(5, 5, 12, 0))
c.grid(column=0, row=0, sticky=(N,W,E,S))
root.grid_columnconfigure(0, weight=1)
root.grid_rowconfigure(0,weight=1)
fname = "A.jpg"
fname1 = "B.jpg"
image_tk = ImageTk.PhotoImage(Image.open(fname))
btn = ttk.Button(c, text="load image", command=showImage)
lbl1 = ttk.Label(c)
btn.grid(column=0, row=0, sticky=N, pady=5, padx=5)
lbl.grid(column=1, row=1, sticky=N, pady=5, padx=5)
root.mainloop()
How can I configure my ShowImage function or any other modification needed to be able to switch the image between fname and fname1
To change images on button clicks use the configure() method to the button to change the command argument and create a new ImageTk object to hold a reference of the second image.
from Tkinter import *
import ttk
from PIL import ImageTk, Image
def showImage():
lbl1.configure(image=image_tk)
btn.configure(text = "load image!", command=showImage1)
def showImage1():
lbl1.configure(image=image_tk1)
btn.configure(text = "load image!", command=showImage)
root = Tk()
c = ttk.Frame(root, padding=(5, 5, 12, 0))
c.grid(column=0, row=0, sticky=(N,W,E,S))
root.grid_columnconfigure(0, weight=1)
root.grid_rowconfigure(0,weight=1)
fname = "a.jpg"
image_tk = ImageTk.PhotoImage(Image.open(fname))
fname1 = "b.jpg"
image_tk1 = ImageTk.PhotoImage(Image.open(fname1)) # new image object
btn = ttk.Button(c, text="load image", command=showImage)
lbl1 = ttk.Label(c)
btn.grid(column=0, row=0, sticky=N, pady=5, padx=5)
lbl1.grid(column=1, row=1, sticky=N, pady=5, padx=5)
root.mainloop()