How to arrange things (coordinate) in Tkinter? - python

I want to create a Tkinter window where on the right there is an image as below.
In the left of the image, there will be an Entry box with written answers.
Users can check whether the information is correct (if the answer question 30 is 1 the Entry box should be 1, in case if it is not 1, users could fix it)
My so far code:
b,g,r = cv2.split(image)
img = cv2.merge((r,g,b))
root = tk.Tk()
im = Image.fromarray(img)
imgtk= ImageTk.PhotoImage(image=im)
image = tk.Label(root, image=imgtk).pack()
entry1 = tk.Entry(root)
entry1.insert(tk.END, 'the answer').pack()
canvas1.create_window(50,50, window = entry1)
canvas1.create_window(50,100, window = image) #I thought this would make it stood next to each other
root.mainloop()
Sorry, first time working with Tkinter, so my code may stupid
P/s: I know the shape of the image and the Y axis of every question to place the Entry box right next to it.

Related

GUI to select pixel range in a new pop up window

I am trying to improve my code to make it more userfriendly using GUI. I have a simple code to select set of images and crop it. I have a code to that selects the folder directory containing images, now I want something similar using tkinter to select pixel range to crop images in the following code.
#Read images
root= tk.Tk()
var = tk.StringVar()
label = tk.Label( root, textvariable=var,relief = tk.RAISED,fg='peru',bg='white',font=('Helvetica',18,'bold'))
var.set("Choose image location")
label.pack()
img_list =[i for i in glob.glob(filedialog.askdirectory() +'/*.tif')] # choose the folder containing image list
images_read = np.array([(plt.imread(fname)) for fname in img_list]).astype(np.int32)
#crop_size=input()
images_crp =np.array([i[524:1024,275:775] for i in images_flp]) #crop the images to requried shape (or Pixel_row X pixel_column)
Here, I have manually selected pixel range, but I would love to have a pop up window asking me to enter the pixel range using GUI. Help in this regard is appreciated.
Thanks

Changing a displayed image inside mainloop on Tkinter?

I'm trying to make a program to display a single color, fullscreen. The idea is to use it on a large screen to create environment in the room, the screen changing from color to color after certain time.
Displaying the color fullscreen is not a problem but how can I change said color smoothly?
For the fullscreen display I've used a Tkinter window with the same size as the screen: imagesprite = canvas.create_image(w/2, h/2, image=image) where image is a certain color. But to change the color I need to destroy the window using root.after(2000, root.destroy) and then create a new one. This is not smooth as the desktop can be seen for a brief moment.
How can I change the image displayed inside a Tkinter window on the go, or, how can I close one window and open another one smoothly?
An option you have is instead of using an image is to have a background for the Canvas object. Here is the minimum code to have a single colour background.
from tkinter import Tk, Canvas
root = Tk()
root.attributes("-fullscreen",True)#Makes the window fullscreen
canvas = Canvas(root, width=root.winfo_width(),height=root.winfo_height(), background="red") #Makes a canvas with a red coloured background
#The width and height of the Canvas are taken from the root object
canvas.pack()
root.mainloop()
From here, instead of deleting the window constantly, it is possible to just change the attributes of Tkinter widgets. This is done using the config method.
canvas.config(background="green")
A great thing about tkinter is that you can give it a hex code for the colour and it will draw use that. It needs to be in a string formatted like this:
"#RRGGBB" where each group is a hexadecimal number from 0 to FF.
With this in mind, you can increase the hexadecimal number each frame or however many frames you want between two colours. To have a good transition, you may want to use Hue,Saturation,Value (HSV) colours, and only change the Hue value.
You can store the HSV in a list:
hsv = [0,0.7,0.7]
To convert, you first want to convert to 0 to 255 RGB and then to Hexadecimal.
import colorsys
rgb = colorsys.hsv_to_rgb(*hsv) #Uses list unpacking to give it as arguments
Next, you use the rgb and turn it into Hexcode form.
def getHexCode(rgb):
r = hex(int(rgb[0]*255))[2:] #converts to hexadecimal
#With the hex() function, it returns a number in "0xFE" format (0x representing hex).
#To ignore this, we can take the substring using [2:]
if len(r) < 2: #If the value is a 1-digit number, then we want to add a zero at the front for hexcode form
r = "0"+r
g = hex(int(rgb[1]*255))[2:]
if len(g) < 2:
g = "0"+g
b = hex(int(rgb[2]*255))[2:]
if len(b) < 2:
b = "0"+b
return "#" + r + g + b
Finally, we actually call the change method.
changeSpeed = 200
def changeColor():
rgb = colorsys.hsv_to_rgb(*hsv)
hexCode = getHexCode(rgb)
canvas.config(background = hexCode)
hsv[0]+=0.01
root.after(changeSpeed,changeColor)
root.after(changeSpeed, changeColor)
(EDITED)
Two things that were previously a problem were the root.winfo_width() and root.winfo_height(), as well as the fullscreen giving a border.
To solve the first problem, we have to somehow update the root object, since by default it's 1x1. What we can do for that is make the Canvas object and then update it. It looks like this:
canvas = Canvas(root, width=100,height=100, background="white",highlightthickness=0) #Makes a canvas with a white coloured background
canvas.pack()
canvas.update()
canvas.config(width = root.winfo_width(), height = root.winfo_height())
The second problem is also solved by making the canvas object with a specific attribute, highlightthickness=0. If you notice, the canvas object initialization is now:
canvas = Canvas(root, width=100,height=100, background="white",highlightthickness=0)
Another thing that I thought was useful is if a button closes the program. I bound the "Escape" key to the closing using the following:
def quit(event):
root.destroy()
root.bind("<Escape>", quit)
As a full program, it looks like this:
import colorsys
from tkinter import Tk, Canvas
hsv = [0,1,0.8]
changeSpeed = 200
root = Tk()
root.attributes("-fullscreen",True)
canvas = Canvas(root, width=100,height=100, background="white",highlightthickness=0) #Makes a canvas with a white coloured background
canvas.pack()
canvas.update()
canvas.config(width = root.winfo_width(), height = root.winfo_height())
def getHexCode(rgb):
r = hex(int(rgb[0]*255))[2:]
if len(r) < 2:
r = "0"+r
g = hex(int(rgb[1]*255))[2:]
if len(g) < 2:
g = "0"+g
b = hex(int(rgb[2]*255))[2:]
if len(b) < 2:
b = "0"+b
return "#" + r + g + b
def changeColor():
rgb = colorsys.hsv_to_rgb(*hsv)
hexCode = getHexCode(rgb)
canvas.config(background = hexCode)
hsv[0]+=0.01
root.after(changeSpeed,changeColor)
def quit(event):
root.destroy()
root.after(changeSpeed, changeColor)
root.bind("<Escape>", quit)
root.mainloop()
Some variables you can change in this is the changeSpeed, the original hsv list, and the 0.01 that is added to the hue each increase

Place widgets into Frames?

I was trying out something new on Tkinter (I am still a newbie), but it keeps failing...maybe someone could help out?
I wanted to create a window with several Frames, so that I can open and close them and show that way different content. However I am already stuck with not being able to "place" the, in this case a button, to the frame. Instead I get a blank frame with nothing inside...
The reason I want to use the place manager is so that I can easily choose the x and y coordinates. I don't want to create empty columns just in order to get a button appear in the middle of the screen.
Here the code:
from Tkinter import *
root = Tk()
root.title("Tkinter window")
root.geometry("800x600")
StartFrame = Frame(root)
StartFrame.pack()
Button1 = Button(StartFrame, command = StartTkinter, text = "Start", bg = "white", fg = "black", height = 2, width = 15)
Button1.place(x=0, y=50)
root.mainloop()
The problem is that you forgot to specify the dimensions of the frame. So, by default, it is created to be just 1 pixel high and 1 pixel wide. This means that its contents will not be visible on the window.
To fix the problem, you can either set exact values for these dimensions when you create the frame:
StartFrame = Frame(root, height=600, width=800)
or you can do:
StartFrame.pack(expand=True, fill="both")
to have the frame fill all available space.

Python: Whole image not showing

Today I was trying to learn how the PhotoImage works but I run into errors and problems non stop. After lots of research I finally get an image to show up BUT its not the whole image, just a piece of it.
Heres my code:
from tkinter import*
root = Tk()
canvas = Canvas( root , width=720 , height=480 )
originallogo = PhotoImage( file="Picture1.gif" )
canvas.create_image( 0, 0, image=originallogo )
canvas.grid()
root.mainloop()
I would post a screenshot of the outcome but I am not level 10 yet. Heres a link of it instead: https://www.dropbox.com/s/iiwsdmgvlhyhlef/Screen%20shot%202014-11-24%20at%208.34.51%20PM.png?dl=0
By default the center of the image will be placed at the given coordinates. If you want the upper left corner of the image to be at 0,0, add anchor="nw"
canvas.create_image(..., anchor="nw", ...)
There is a very simple solution to this. Change the position of the drawing of the image from 0,0 to different numbers until you get it into the right position that you desire.

Draw and move a point over an image in python

Hi all I have to do a little script in Python.
In this script I have a variable (that represents a coordinate) that is continuously updated to a new value.
So I have to draw a red point over a image and update the point position every time the variable that contains the coordinate is updated.
I tried to explain what I need doing something like this but obviously it doesn't works:
import Tkinter, Image, ImageDraw, ImageTk
i=0
root = Tkinter.Tk()
im = Image.open("img.jpg")
root.geometry("%dx%d" % (im.size[0], im.size[1]))
while True:
draw = ImageDraw.Draw(im)
draw.ellipse((i, 0, 10, 10), fill=(255, 0, 0))
pi = ImageTk.PhotoImage(im)
label = Tkinter.Label(root, image=pi)
label.place(x=0, y=0, width=im.size[0], height=im.size[1])
i+=1
del draw
someone may help me please? thanks very much!
Your on the right track using a PhotoImage in a Label but instead of creating a new Label each loop, just create the label once and update its position in the loop.

Categories

Resources