Why won't tkinter widgets scroll with the canvas? - python

I am creating a gui for my ML project but I am unable to successfully create a vertical scrollbar that actually works. Here's my code
import tkinter as tk
import tkinter.filedialog
from PIL import ImageTk, Image
class App:
def __init__(self, master):
frame = tk.Frame(master,width=500,height=500)
frame.pack()
self.canvas=tk.Canvas(frame,width=500, height=500,borderwidth=0,highlightthickness=0,background='white',scrollregion=(0,0,500,800))
self.canvas.pack()
vbar=tk.Scrollbar(self.canvas,orient="vertical")
vbar.pack(side="right",fill="y")
vbar.config(command=self.canvas.yview)
self.canvas.config(yscrollcommand=vbar.set)
self.canvas.bind("<Configure>",lambda e:self.canvas.configure(scrollregion=self.canvas.bbox('all')))
root.minsize(500,500)
self.button = tk.Button(self.canvas,
text="QUIT", fg="red",
command=frame.quit)
self.button.pack()
self.button2 = tk.Button(self.canvas,
text="Display image",
command=self.Display_image)
self.button2.pack()
def Display_image(self):
f = tkinter.filedialog.askopenfilename(
parent=root, initialdir='D:/Test',
title='Choose file',
filetypes=[('bmp images', '.bmp')]
)
image = ImageTk.PhotoImage(Image.open(f))
l1 = tkinter.Label(self.canvas, image=image)
l1.image = image
l1.pack()
root = tk.Tk()
app = App(root)
root.mainloop()
The code does create a scrollbar but is not functional. However when I include this line of code self.canvas.create_rectangle((0,0,500,800)) in the code the rectangle scrolls.

Related

Tkinter LabelFrames don't show up

When i want to layout my frames the Labels don't show up. I can't seem to solve it. For some reason it does show op the entries that i've made. Can somebody please help me.
import tkinter as tk
from tkinter import *
from tkinter import filedialog
from PIL import ImageTk, Image
class main_screen():
def __init__(self, master):
self.master = master
self.master.title("Roboframe")
self.master.geometry("650x650")
self.create_frames()
self.create_entries()
def create_frames(self):
self.top = Frame(self.master).grid(row=0,column=0)
self.bottom = Frame(self.master).grid(row=0, column=0)
self.set_paths = LabelFrame(self.master, text="Set Path", padx=10, pady=10).grid(row=0,column=0)
self.options = LabelFrame(self.master, text="Options", padx=10, pady=10).grid(row=0,column=0)
def create_entries(self):
python_path = StringVar(self.set_paths, "C:/Python37/python.exe")
robot_path = StringVar(self.set_paths, "C:/ws/cmge.automation/RobotFrameworkCMGE")
self.set_path_python = Entry(self.set_paths, width=60, textvariable=python_path).grid(row=0,column=0)
self.set_path_robot = Entry(self.set_paths, width=60, textvariable=robot_path).grid(row=1, column=0)
root = tk.Tk()
app = main_screen(root)
root.mainloop()
Output of code shown above
The thing i'm rewritting the code for because it is a mess
The second picture i've also made myself. But the code is a giant mess.
You have to make an object of the widget not the grid function of the widget. Grid returns nothing so naturally none of them will show up. I believe this is what you wanted:
import tkinter as tk
from tkinter import *
from tkinter import filedialog
from PIL import ImageTk, Image
class main_screen():
def __init__(self, master):
self.master = master
self.master.title("Roboframe")
self.master.geometry("650x650")
self.create_frames()
self.create_entries()
def create_frames(self):
# you have grided all of your frames and label frames on the same row and column
self.top = Frame(self.master)
self.top.grid(row=0,column=0)
self.bottom = Frame(self.master)
self.bottom.grid(row=0, column=0)
self.set_paths = LabelFrame(self.master, text="Set Path", padx=10, pady=10)
self.set_paths.grid(row=0,column=0)
self.options = LabelFrame(self.master, text="Options", padx=10, pady=10)
self.options.grid(row=0,column=0)
def create_entries(self):
python_path = StringVar(self.set_paths, "C:/Python37/python.exe")
robot_path = StringVar(self.set_paths, "C:/ws/cmge.automation/RobotFrameworkCMGE")
self.set_path_python = Entry(self.set_paths, width=60, textvariable=python_path)
self.set_path_python.grid(row=0,column=0)
self.set_path_robot = Entry(self.set_paths, width=60, textvariable=robot_path)
self.set_path_robot.grid(row=1, column=0)
root = tk.Tk()
app = main_screen(root)
root.mainloop()
Also a couple of things:
You have imported tkinter twice in two different ways, just use one of them
You are griding both of the LabelFrames and frames on the same row and column but since "self.options" does not contain anything it is not going to show up, be careful later on
This will display both LabelFrames, the second with a dummy Entry widget.
import tkinter as tk
from tkinter import *
from tkinter import filedialog
from PIL import ImageTk, Image
class main_screen():
def __init__(self, master):
self.master = master
self.master.title("Roboframe")
self.master.geometry("650x650")
self.create_frames()
self.create_entries()
def create_frames(self):
self.set_paths = LabelFrame(self.master, text="Set Path", padx=10, pady=10)
self.set_paths.grid(row=0,column=0)
self.options = LabelFrame(self.master, text="Options", padx=10, pady=10)
self.options.grid(row=1,column=0)
def create_entries(self):
python_path = StringVar(self.set_paths, "C:/Python37/python.exe")
robot_path = StringVar(self.set_paths, "C:/ws/cmge.automation/RobotFrameworkCMGE")
self.set_path_python = Entry(self.set_paths, width=60, textvariable=python_path)
self.set_path_python.grid(row=0,column=0)
self.set_path_robot = Entry(self.set_paths, width=60, textvariable=robot_path)
self.set_path_robot.grid(row=1, column=0)
self.test = Entry(self.options, width=60)
self.test.grid(row=1, column=1)
root = tk.Tk()
app = main_screen(root)
root.mainloop()

Displaying an image on a label by selecting the image via button

When the button is clicked, browse window should pop up asking for the image file to select and that image needs to be displayed on a label. Unable to define the function clicked() to do so.
from tkinter import *
from PIL import Image, ImageTk
from tkinter import filedialog
from tkinter.filedialog import askopenfilename
root = Tk()
#def clicked():
# path=filedialog.askopenfilename(filetypes=[("Image File",'.jpg')])
label = Label(root, image = logo)
label.pack()
button = Button(root, text = "Load Image", command = clicked)
button.pack()
root.mainloop()
This May Help You
from tkinter import *
from tkinter import filedialog
from PIL import Image,ImageTk
class GUI(Frame):
def __init__(self, master=None):
Frame.__init__(self, master)
w,h = 650, 650
master.minsize(width=w, height=h)
master.maxsize(width=w, height=h)
self.pack()
self.file = Button(self, text='Browse', command=self.choose)
self.choose = Label(self, text="Choose file").pack()
#Replace with your image
self.image = PhotoImage(file='test.png')
self.label = Label(image=self.image)
self.file.pack()
self.label.pack()
def choose(self):
ifile = filedialog.askopenfile(parent=self,mode='rb',title='Choose a file')
path = Image.open(ifile)
self.image2 = ImageTk.PhotoImage(path)
self.label.configure(image=self.image2)
self.label.image=self.image2
root = Tk()
app = GUI(master=root)
app.mainloop()
root.destroy()

How do I create an image button - Python [duplicate]

This question already has an answer here:
Create image in button
(1 answer)
Closed 3 years ago.
For the buttons, I want to change the "text" to be "images"
e.g picture of a eraser instead of text saying eraser.
Here is the Section of Code:
def __init__(self):
self.root = Tk()
self.choose_size_button = Scale(self.root, from_=1, to=15, orient=HORIZONTAL)
self.choose_size_button.grid(row=0, column=1)
self.draw_button = Button(self.root, text='Draw', command=self.use_draw)
self.draw_button.grid(row=0, column=2)
self.color_button = Button(self.root, text='Colour', command=self.choose_color)
self.color_button.grid(row=0, column=3)
self.eraser_button = Button(self.root, text='Eraser', command=self.use_eraser)
self.eraser_button.grid(row=0, column=4)
self.c = Canvas(self.root, bg='white', width=650, height=600)
self.c.grid(row=1, columnspan=5)
self.setup()
self.root.mainloop()
You should use the tinkter to perform your task. You can pass image argument to the button.
For example:
import Tkinter as tk
class View(tk.Frame):
def __init__(self, *args, **kwargs):
tk.Frame.__init__(self, *args, **kwargs)
self.image = tk.PhotoImage(file="anyfile.gif")
b = tk.Button(self, text=" ", image=self.image)
b.pack(side="top")
if __name__ == "__main__":
root = tk.Tk()
view = View(root)
view.pack(side="top", fill="both", expand=True)
root.mainloop()
You can use image argument of Button in tkinter.
For example; see this snippet:-
from tkinter import *
from PIL import ImageTk, Image
root = Tk()
img = ImageTk.PhotoImage(Image.open('your_image_path'))
b = Button(root, command = print('hello'), image = img)
b.pack()
b.place()

How to open the filedialog after pressing the button?

I would like to open the filedialog after pressing a button. Then I could choose an image and display it on a canvas. (My goal is to do a very simple image editor) Unfortunately, the filedialog open up automatically when I start the program. Is there a way for example to do something like this:
press a button to open the filedialog
choose an image
display the image on the canvas
Here is my code that I've done so far
from tkinter import *
from PIL import Image, ImageTk
from tkinter import filedialog
root = Tk()
#function to select my image by using the filedialog
def select_image():
file_path = filedialog.askopenfilename()
return Image.open(file_path)
#button to press to open filedialog
select = Button(root, text="select an image", command=select_image)
select.pack()
#the canvas where the image will be display
canvas = Canvas(root, width= 400, height=400, bg="grey")
canvas.pack()
image_tk = ImageTk.PhotoImage(select_image())
canvas.create_image(200,200, image= image_tk)
root.mainloop()
The filedialog opens because of this line:
image_tk = ImageTk.PhotoImage(select_image())
My Solution is:
from tkinter import Tk, filedialog, Frame, Button, Canvas
from PIL import Image, ImageTk
class Gui:
def __init__(self, master):
self.master = master
self.create_widgets()
def create_widgets(self):
self.select = Button(self.master, text="select an image", command=self.select_image)
self.select.pack()
self.canvas = Canvas(self.master, width= 400, height=400, bg="grey")
self.canvas.pack()
def select_image(self):
file_path = filedialog.askopenfilename()
des = Image.open(file_path)
bg_image = ImageTk.PhotoImage(des)
self.canvas.bg_image = bg_image
self.canvas.create_image(200,200, image=self.canvas.bg_image)
if __name__ == "__main__":
root = Tk()
my_gui = Gui(root)
root.mainloop()

how to set background image to a window using Tkinter python 2.7

I was working on setting the background image and upon that image adding the labels, buttons and all. everything is coming, but not on the background image, its like this:
And my code is:
from Tkinter import Tk, Frame, BOTH
import Tkinter
from PIL import Image, ImageTk
class Example(Frame):
def __init__(self, parent):
Frame.__init__(self, parent)
self.parent = parent
self.initUI()
def initUI(self):
self.parent.title("PISE")
self.pack(fill=BOTH, expand=1)
root = Tk()
root.geometry("1111x675+300+300")
app = Example(root)
im = Image.open('wood.png')
tkimage = ImageTk.PhotoImage(im)
Tkinter.Label(root,image = tkimage).pack()
custName = StringVar(None)
yourName = Entry(app, textvariable=custName)
yourName.pack()
relStatus = StringVar()
relStatus.set(None)
labelText = StringVar()
labelText.set('Accuracy Level')
label1 = Label(app, textvariable=labelText, height=2)
label1.pack()
radio1 = Radiobutton(app, text='100%', value='1', variable = relStatus, command=beenClicked1).pack()
radio2 = Radiobutton(app, text='50%', value='5', variable = relStatus, command=beenClicked5).pack()
root.mainloop()
How to fit the background image properly?
Thanks in advance!
You should use place() for placing the image & then use grid() (personally i prefer grid) or pack() for other widgets.
from Tkinter import Tk, Frame, BOTH
import Tkinter
from PIL import Image, ImageTk
class Example(Frame):
def __init__(self, parent):
Frame.__init__(self, parent)
self.parent = parent
self.initUI()
def initUI(self):
self.parent.title("PISE")
self.pack(fill=BOTH, expand=1)
root = Tk()
root.geometry("1111x675+300+300")
app = Example(root)
im = Image.open('Test1.png')
tkimage = ImageTk.PhotoImage(im)
myvar=Tkinter.Label(root,image = tkimage)
myvar.place(x=0, y=0, relwidth=1, relheight=1)
custName = StringVar(None)
yourName = Entry(root, textvariable=custName)
yourName.pack()
relStatus = StringVar()
relStatus.set(None)
labelText = StringVar()
labelText.set('Accuracy Level')
label1 = Label(root, textvariable=labelText, height=2)
label1.pack()
def beenClicked1():
pass
def beenClicked5():
pass
radio1 = Radiobutton(root, text='100%', value='1', variable = relStatus, command=beenClicked1).pack()
radio2 = Radiobutton(root, text='50%', value='5', variable = relStatus, command=beenClicked5).pack()
root.mainloop()
The reason the widgets were not visible was because you were using two different parents ,i.e, app(its an Instance of class Example,so don't use this) and root.

Categories

Resources