I made a code with multiprocessing and it does not work. Here's the code
from tkinter import *
from PIL import ImageTk , Image
import multiprocessing
root = Tk()
def imgs(img):
img1 = "C:/Users/ASUS/pixel/"+img+".png"
global img2
img2 = ImageTk.PhotoImage(Image.open(img1))
l = Label(image = img2)
l.pack()
q1 = input("what is your favorite color?")
print("wow " + q1 + " , also is mine's!")
imgs("f_i")
p = multiprocessing.Process(target=imgs)
p.start()
#more prints , inputs , etc
An image was supposed to show up but it does not. How can I fix that?
Related
I'm trying to make a memory game for fun and as a learning experience, and I've run into the issue where even with something like time.sleep(.5) I still can't get buttons to update correctly with a delay. In fact the second button seems to update to hidden as it's about to show the proper image. I'm assuming the issue lies somewhere in the buttonClicked() function.
I'm trying to figure out how I can make it show one button, then the second, then wait half a second and hide both. And if someone understands why this is happening or where I could look into the issue and read up on my own, that would be helpful.
Thanks.
from re import A
import time
import tkinter as tk
from tkinter import *
from typing_extensions import Self
from PIL import Image, ImageTk
import glob
import os, os.path
import numpy as np
from sqlalchemy import null
#resize images and button
imgButtonWidth = 100
imgButtonHeight = 100
imgButtonSize = (imgButtonWidth,imgButtonHeight)
#Set the height and width of the game by number of items.
width = 6
height = 6
#buttons = [[Button]*width]*height
#Total number of items 36 (0-35)
count = width*height-1
buttonList = []
#Will be a 2d array of [button, id]
answersList = []
clickedCount = 0
imgs = []
hiddenImg = null
# Create frame, set default size of frame and background color.
root = Tk()
root.title('Memory Game')
root.geometry(str(imgButtonWidth * (width+1)) + "x" + str(imgButtonHeight * (height+1)))
root.config(bg='darkblue')
frame = Frame(root, bg='darkblue')
# Fetch images from location and create a list of Image objects, then return.
def getImages():
imgs = []
path = "/home/paul/Programming/Python/MyMiniProjects/Mid/MemoryGame/"
valid_images = [".jpg",".gif",".png",".tga"]
for f in os.listdir(path):
ext = os.path.splitext(f)[1]
if ext.lower() not in valid_images:
continue
imgs.append([Image.open(os.path.join(path,f)).resize(imgButtonSize), f])
return imgs + imgs
#Shuffle images for the game
imgs = getImages()
random.shuffle(imgs)
#Simple image to cover the tiles
hiddenImg = ImageTk.PhotoImage(Image.new('RGB', (imgButtonWidth, imgButtonHeight), (0,0,105)))
#Disable buttons after a match
def disable():
global clickedCount, answersList
clickedCount = 0
for a in answersList:
a[0]["state"] = "disabled"
a[0]["bg"] = "green"
answersList = []
#Hide buttons again
def hide():
global clickedCount, answersList
clickedCount = 0
for a in answersList:
#a[0].config(image = hiddenImg)
a[0]["image"] = hiddenImg
a[0]["state"] = "normal"
a[0]["bg"] = "white"
answersList = []
def wrong():
for a in answersList:
a[0]["bg"] = "red"
def buttonClicked(picture, id, button):
global clickedCount, answersList
print(clickedCount, len(answersList))
#print(button.image, "1", hiddenImg, picture)
if button.image is hiddenImg and clickedCount < 2:
button["image"] = picture
button["state"] = "disabled"
clickedCount += 1
answersList.append([button, id])
if len(answersList) == 2:
#Check id but make sure it's not the same button pressed twice
if answersList[0][1] is answersList[1][1]:#and answersList[0][0] is not answersList[1][0]:
disable()
else:
wrong()
hide()
#Create the actual buttons with their respective image
for h in range(height): #print(buttons[w][::],"\n")
newList = []
for w in range(width):
tempImage = imgs.pop(count)
picture = ImageTk.PhotoImage(tempImage[0])
id = tempImage[1]
button = Button(frame, image=hiddenImg, state=NORMAL, height=imgButtonHeight, width=imgButtonWidth)
#Need to split this up because of how python handles closures
button["command"] = lambda pic_temp=picture, id_temp=id, button_temp = button: buttonClicked(pic_temp, id_temp, button_temp)
button.image = hiddenImg
#buttons[w][h].name = str(w + h)
#buttons[w][h].grid(row=w, column=h, ipadx=random.randint(0,40), ipady=random.randint(0,40), padx=random.randint(0,5), pady=random.randint(0,5))
button.grid(row=h, column=w, padx=1, pady=1)
#Button(frame, image=picture).grid(row=w, column=h, ipadx=random.randint(0,40), ipady=random.randint(0,40), padx=random.randint(0,5), pady=random.randint(0,5))
count -= 1
# buttonList.append(buttons[h][w])
newList.append(button)
buttonList.append(newList)
# for y in range(height):
# for x in range(width):
# print(ButtonList[y][x])
# print("")
frame.pack(expand=True)
root.mainloop()```
I'm trying to create a GUI that will display an image that is taken every 10 seconds and it's processed counter part. I'm having trouble getting the GUI window to update the two images when they get overridden in the file system.
Here's the code I have so far
import cv2
import threading
from imageai.Detection import ObjectDetection
import os
from tkinter import *
import os
from PIL import ImageTk,Image
root = Tk()
canvas = Canvas(root, width = 2000, height = 2000)
canvas.pack()
execution_path = os.getcwd()
inimg = ImageTk.PhotoImage(Image.open(os.path.join(execution_path , "test.jpg")))
outimg = ImageTk.PhotoImage(Image.open(os.path.join(execution_path , "testnew.jpg")))
def capture():
print("Capturing...")
videoCaptureObject = cv2.VideoCapture(0)
ret,frame = videoCaptureObject.read()
cv2.imwrite("test.jpg",frame)
print("Done capturing.")
print("Finding")
totalPersons = 0
detections = detector.detectObjectsFromImage(input_image=os.path.join(execution_path , "test.jpg"), output_image_path=os.path.join(execution_path , "testnew.jpg"))
for eachObject in detections:
if(eachObject["name"] == "person"):
totalPersons += 1
print("Total persons " + str(totalPersons))
detector = ObjectDetection()
detector.setModelTypeAsRetinaNet()
execution_path = os.getcwd()
detector.setModelPath(os.path.join(execution_path , "resnet50_coco_best_v2.0.1.h5"))
detector.loadModel("fastest")
def run():
threading.Timer(10.0, run).start()
canvas.create_image(20, 20, anchor=NW, image=inimg)
canvas.create_image(750, 500, anchor=SW, image=outimg)
root.mainloop()
capture()
run()
try to use
root.update_idletasks()
to update tkinter GUI window.
I am trying to build a GUI that displays sequence of images as videos. The images are numpy arrays.
The code is working when I try to display one image at a time but it crashes when I try to run them as a sequence.
The code:
from tkinter import *
from scipy.io import loadmat
from PIL import ImageTk, Image
import time
data = loadmat('DepthFrames.mat')['DepthFrames'].squeeze(axis=0)
print(data.shape)
counter = 0
root = Tk()
image = ImageTk.PhotoImage(image = Image.fromarray(data[counter]))
root.title("WUDU VIDEOS LABEL TOOL")
myLabel = Label(root, image = image)
myLabel.grid(row = 0)
def changeImg():
global counter
counter +=1
print(counter)
image = ImageTk.PhotoImage(image = Image.fromarray(data[counter]))
myLabel.configure(image = image)
myLabel.image = image
def playVideo():
for i in range(10):
image = ImageTk.PhotoImage(image = Image.fromarray(data[i]))
myLabel.configure(image = image)
myLabel.image = image
time.sleep(0.03333)
my_Button = Button(text = "Play video",command = playVideo)
my_Button.grid(row = 1)
root.mainloop()
time.sleep blocks the main thread of tkinter. Your code will freeze the GUI until the for loop is completed and the image will be shown as the last image. For more details, see this post.
You need to use the after method. Something like this:
def playVideo(frame=0):
try:
image = ImageTk.PhotoImage(image = Image.fromarray(data[frame]))
except IndexError:
return
myLabel.configure(image = image)
myLabel.image = image
root.after(33, playVideo, frame+1)
That's my code and I get the error message:
... return getattr(self.tk, attr)
AttributeError: temp_pic"...
I need to program two buttons: [zoom in] and [zoom out].
If you have any better ideas for doing that, please, just say it.
I'm going to use this image to develop maps through graphs (structure)
from Tkinter import *
from PIL import Image, ImageTk, ImageDraw, ImageOps, ImageEnhance
bairro = "botafogo.jpg"
class Painel(Tk):
def __init__(self):
Tk.__init__(self) #create ui
self.zoom = Frame(self)
self.zoom.pack()
self.zin = Button(self.zoom, command = self.zoom_in, text = "Zoom In")
self.zin.pack()
self.zout = Button(self.zoom, command = self.zoom_out, text = "Zoom Out")
self.zout.pack()
self.c = Canvas(self, bd=0, highlightthickness=0, width=100, height=100)
self.c.pack(fill='both', expand=1)
self.main_pic = Image.open(bairro) #load image
self.main_pic.thumbnail((800, 600))
self.tkphoto = ImageTk.PhotoImage(self.main_pic)
self.canvasItem = self.c.create_image(0, 0, anchor='nw', image = self.tkphoto)
self.c.config(width = self.main_pic.size[0], height = self.main_pic.size[1])
self.temp = self.main_pic.copy() # 'working' image
def update_painel(self):
self.tkphoto = ImageTk.PhotoImage(self.temp_pic)
self.c.itemconfigure(self.canvasItem, image = self.tkphoto)
def zoom_in(self):
self.temp_pic = self.temp_pic.transform( ( self.temp_pic.size[0]/2,
self.temp_pic.size[0]/2
),
Image.EXTEND,
( 0, 0, self.temp_pic[0], self.temp_pic[1]
)
)
self.update_painel()
def zoom_out(self):
self.temp_pic = self.main_pic
self.update_painel()
app = Painel()
app.mainloop()
a deep-copy instruction shall read
self.temp_pic = self.main_pic.copy() # 'working' image
instead of
self.temp = self.main_pic.copy() # 'working' image**
I'd like to write a program that over a given time period fades the background of a Tkinter window from an initial hex color to a final hex color while displaying some of the colors in between. (Uncommenting line 99, print time, hex_color_t, should clarify what I mean if it isn't clear.)
Here's the code:
from Tkinter import *
from ttk import *
import re
class InvalidColor(Exception):
pass
def color_to_hex(color):
MIN_COLOR = 0
MAX_COLOR = 255
try:
if color >= MIN_COLOR and color <= MAX_COLOR:
try:
hex_str = hex(color)[2:]
except TypeError:
raise InvalidColor
if len(hex_str) < 2:
hex_str = "0" + hex_str
return hex_str
else:
raise InvalidColor
except InvalidColor:
return "00"
def rgb_to_hex((red, green, blue), upper = True):
r = color_to_hex(red)
g = color_to_hex(green)
b = color_to_hex(blue)
hex_str = "#%s%s%s" % (r, g, b)
if upper:
hex_str = hex_str.upper()
return hex_str
def hex_to_rgb(hex_value):
hex_pattern = re.compile(r"^(#)?(?P<r>[a-f0-9]{2})(?P<g>[a-f0-9]{2})(?P<b>[a-f0-9]{2})$", re.IGNORECASE)
match = hex_pattern.match(hex_value)
HEX_PREFIX = "0x"
BASE = 16
if match:
# could be more DRY-ish, but whatever
r = int(HEX_PREFIX + match.group("r"), BASE)
g = int(HEX_PREFIX + match.group("g"), BASE)
b = int(HEX_PREFIX + match.group("b"), BASE)
else:
raise InvalidColor
return (r, g, b)
#print rgb_to_hex((255, 0, 0))
#print type(hex_to_rgb(rgb_to_hex((107,142,35))))
#print hex_to_rgb("4B0082")
root = Tk()
initial_color_hex = "#0000ff" # blue
final_color_hex = "#44ccff" # light blue
STOP_TIME_MS = 2000
STEP_TIME_MS = 50
"""
def final_color(*args, **kwargs):
root.configure(background = final_color_hex)
"""
def set_color(root, hex_color, *args, **kwargs):
root.configure(background = hex_color)
def linear_fade(root,
hex_start_color,
hex_stop_color,
stop_time_ms = STOP_TIME_MS,
step_time_ms = STEP_TIME_MS,
delay_ms = 0):
root.configure(background = hex_start_color)
(r0, g0, b0) = hex_to_rgb(hex_start_color)
(rf, gf, bf) = hex_to_rgb(hex_stop_color)
delta_r = rf-r0
delta_g = gf-g0
delta_b = bf-b0
#print delta_r, delta_g, delta_b
for time in range(delay_ms, stop_time_ms+1, step_time_ms):
rt = r0 + (delta_r * time // stop_time_ms)
gt = g0 + (delta_g * time // stop_time_ms)
bt = b0 + (delta_b * time // stop_time_ms)
#print (rt, gt, bt)
hex_color_t = rgb_to_hex((rt,gt,bt))
#print time, hex_color_t
root.after(time, set_color(root, hex_color_t))
root.configure(background = initial_color_hex)
#root.after(1000, final_color)
root.geometry("400x400")
linear_fade(root, initial_color_hex, final_color_hex)
root.mainloop()
So far it seems to be going through the for loop without making the window, so I just end up with a delay and then the final color as the background.
I suppose I should go for a more minimal working example. I tried:
from Tkinter import *
root = Tk()
initial_color_hex = "#0000ff" # blue
final_color_hex = "#44ccff" # light blue
def set_color(hex_color, *args, **kwargs):
root.configure(background = hex_color)
root.configure(background = initial_color_hex)
root.after(1000, set_color(final_color_hex))
root.geometry("400x400")
root.mainloop()
But I still encounter the same problem. I did find something that sort of works somewhere, which was:
try:
import tkinter
except ImportError:
import Tkinter as tkinter
root = tkinter.Tk()
def grey(*args,**kwargs):
root.configure(background = "grey")
def bthing():
root.configure(background = "red")
root.after(1000, grey)
tkinter.Button(text = "OK", command = bthing).pack()
root.configure(background = "grey")
root.geometry("400x400")
root.mainloop()
But what is the critical difference between these two examples?
This line
root.after(time, set_color(root, hex_color_t))
does not do what you think it does. This line immediately evaluates the set_color function with the arguments root and hex_color_t. It then takes the result (which incidentally is None in this case) and schedules the result to be evaluated in time ms (needless to say, evaluating None does not affect the color of the root window).
This explains why your window immediately changes color - your code causes all the color changes immediately one after another, then executes a series of meaningless scheduled evaluations.
You can fix this by doing this:
def createColorChangeFunction(hcolor):
return lambda:set_color(root, hcolor)
root.after(time, createColorChangeFunction(hex_color_t))
The createColorChangeFunction is necessary so the various lambda functions have their own local reference to a hex color, rather than sharing one.
I tested this change and got a window fading slowly from dark to light blue.