Turtle circle shape in a main GUI TK - python-3.x

First of all, thanks for stopping by into my post. I'm a amateur Python writer. Right now, I'm writing a code that will control some Agilent instruments, into my GUI I need to display a virtual LED that can show to the operator the current test progress status, like, yellow = testing, green = passed, red= failed.
I found that turtle module can easily create a circle by adding turtle.shape('cicle'), please see below a turtle code I have:
I want to make it clear, I did not wrote the below code, I found the code in this webpage.
from turtle import Screen, Turtle
CURSOR_SIZE = 30
def blink():
pen, fill = turtle.color()
turtle.color(fill, pen)
screen.ontimer(blink, 500) # 1/4 second blink
screen = Screen()
turtle = Turtle()
turtle.hideturtle()
turtle.shape('circle')
turtle.shapesize(50 / CURSOR_SIZE)
turtle.color('red', 'Yellow')
turtle.showturtle()
blink()
So, I want to place the button into my main GUI window:
########## Main Window Design##########
main = Tk()
main.geometry('860x500+65+0')
main.title('Firmware Upgrade System 1.0')
Label(main,text='Firmware Upgrade System 1.0', font=("Tahoma", 20)).place(x=0,y=0)
##! UUT 1 ####################################
LabelFrame(main, text=' UUT 1 INFORMATION : ', font=("Tahoma", 10), height=120, width=420, bd=2, relief='groove' ).place(x=10,y=40)
LabelFrame(main, text='Serial Number',font=("Tahoma", 10), height=47, width=110, bd=3, relief='ridge').place(x=13,y=60)
LabelFrame(main, text='Firmware Version',font=("Tahoma", 10), height=47, width=119, bd=3, relief='ridge').place(x=126,y=60)
def fw_upgrade():
print("pas")
blink()
#######Buttons and Functions
Button(main, text="FIRMWARE UPGRADE", font=("Tahoma", 12), height=1, width=20, command=fw_upgrade).place(x=450,y=440)
So, every time I execute the code, it opens a secondary window with the virtual LED. How to incorporate into my main GUI?
Thanks for your help...

The regular Turtle and Screen always create a new window.
The turtle module has another RawTurtle class which works exactly the same as Turtle, but draws on an existing tk.Canvas, turtle.TurtleScreen or turtle.Screen instance that you must provide. Take a look at the turtle docs, they have lots of examples too
You should also call mainloop() on the Tk() window at the end of your code so that the window stays open.
(It's also a good idea to store the instances of your LabelFrames and all the widgets in variables if you're likely to change any of their properties or text later on)
from tkinter import Tk, Label, LabelFrame, Button, Canvas
from turtle import TurtleScreen, RawTurtle
def fw_upgrade():
print("pas")
########## Main Window Design##########
main = Tk()
main.geometry('860x500+65+0')
main.title('Firmware Upgrade System 1.0')
label1 = Label(main,text='Firmware Upgrade System 1.0', font=("Tahoma", 20))
label1.place(x=0,y=0)
##! UUT 1 ####################################
frame1 = LabelFrame(main, text=' UUT 1 INFORMATION : ', font=("Tahoma", 10), height=120, width=420, bd=2, relief='groove' )
frame1.place(x=10,y=40)
frame2 = LabelFrame(main, text='Serial Number',font=("Tahoma", 10), height=47, width=110, bd=3, relief='ridge')
frame2.place(x=13,y=60)
frame3 = LabelFrame(main, text='Firmware Version',font=("Tahoma", 10), height=47, width=119, bd=3, relief='ridge')
frame3.place(x=126,y=60)
btn = Button(main, text="FIRMWARE UPGRADE", font=("Tahoma", 12), height=1, width=20, command=fw_upgrade)
btn.place(x=450,y=440)
canv = Canvas(main)
turtlescr = TurtleScreen(canv)
canv.place(x=0, y=100)
CURSOR_SIZE = 30
turtle = RawTurtle(turtlescr)
turtle.hideturtle()
turtle.shape('circle')
turtle.shapesize(50 / CURSOR_SIZE)
turtle.color('red', 'Yellow')
turtle.showturtle()
main.mainloop()

Related

Tk-Inter messagebox secondary window error

First of all, thanks for stop by in my post. I'm a python amateur writer and I'm working in a GUI to capture some customer information, the first step is users make sure system is ON before they execute my application, for this, I use a messagebox.showinfo command.
However, this command also opens a secondary window (not sure why). Searching on internet, I realize that the best way to give ride of is with the instruction "withdraw".
my GUI should have a picture, which I use "Photoimage" for this but for some reason, the picture I'm trying to allocate into my GUI it goes to the secondary window open by messagebox.showinfo.
Does any one know why my picture ends on the secondary window and not in my main GUI?
the code below you can use in your computer you may need to create a folder in C and load a picture so you can see what I'm seeing here.
Thanks for stopping by.
from tkinter import *
import tkinter.messagebox
from tkinter import messagebox
import tkinter as tk
import os
################ To Avoid Parasite Window To Open ##################
##root = tkinter.Tk()
##root.withdraw()
messagebox.showinfo(message="Make sure System is ON", title="My App 1.00")
def configure():
print ("hi")
####################### Main Window Design ##########################
##
#####################################################################
main = tkinter.Tk()
main.resizable(0,0)
main.geometry('490x510+700+50')
main.title('My App 1.00')
Label(main, text='GSYSTEM 1.00', font=("Tahoma", 20)).place(x=5,y=0)
LabelFrame(main, text=' Enter Data: ', font=("Tahoma", 14), height=180, width=480, bd=2, relief='ridge' ).place(x=5,y=100)
######################### PN ######################################
tmudir = "C:\\System"
os.chdir(tmudir)
Label(main, text='Scan Product :',font=("Tahoma", 12)).place(x=10,y=150)
LabelFrame(main, font=("Tahoma", 10), height=30, width=180, bd=3, relief='ridge').place(x=110,y=147)
pn_label = PhotoImage(file='TNL.png')
Label(image=pn_label).place(x=310,y=120)
####################### Main Window Design JO #######################
##
#####################################################################
LabelFrame(main, text=' ORDER INFO: ', font=("Tahoma", 14), height=100, width=480, bd=2, relief='ridge' ).place(x=5,y=360)
Label(main, text='Scan Order:',font=("Tahoma", 12)).place(x=10,y=385)
joborderinfo = Entry(main,font=("Arial Narrow", 12))
joborderinfo.place(x=265,y=385)
########## Main Window Design Buttons Start and Config ##############
##
#####################################################################
power_supply_btn = Button(main, text="START TEST", font=("Tahoma", 21), height=1, width=24, command=configure)
power_supply_btn.place(x=55,y=40)
power_supply_btn.config(state=NORMAL)
mainloop()
SystemExit()
You have to create the main window first, and thee use withdraw() to show only the message. You would do it like this:
import tkinter as tk
from tkinter import messagebox
main = tk.Tk()
main.withdraw()
messagebox.showinfo(message="Make sure System is ON", title="My App 1.00")
main.deiconify() # undo the withdraw() command.
def configure():
print ("hi")
main.resizable(0,0)
main.geometry('490x510+700+50')
main.title('My App 1.00')
# rest of your code

Tkinter continuously loop main event

I'm making a trivia game where data is from www.opentdb.com. I want it to continually loop through the main program after it tells you whether your answer is correct or not. (clicking an answer and shows green label but will stay at that screen). I would like it to wait a few seconds and have tried using .after(3000, main()) but do not know how to reset the screen and repeat.Im sorry if this sounds very confusing. Thank you for your assistance :)
from tkinter import *
import trivia
import html
t = trivia.Trivia()
root = Tk()
root.geometry("1366x768")
root.configure(bg='#4dc4ff')
root.iconbitmap("icon.ico")
root.title("Trivia Party!")
frame = Frame(root, bg='#4dc4ff')
class Buttons:
def __init__(self, text):
self.text = html.unescape(text) # remove html entities
self.correct_label = Label(root, text="Correct!", font=("Arial", 30), background="#98FB98", width=20, height=2) # green correct label
def reveal_answer(self):
if self.text == t.return_correct_answer(): # if its the right answer
self.correct_label.pack(pady=175)
frame.destroy()
else:
self.correct_label.config(text="Incorrect", background="#ff6347")
self.correct_label.pack(pady=175)
Label(root, background="#4dc4ff", text=("The correct answer was: " + t.return_correct_answer()),
font=("Arial", 40)).pack()
frame.destroy()
def create(self):
Button(frame, text=self.text, borderwidth=0, highlightbackground="#00abff", font=("Helvetica", 30),
command=self.reveal_answer).pack(side=LEFT, expand=YES)
frame.pack(fill=BOTH, expand=YES)
buttons = []
question = Label(frame, text=html.unescape(t.return_question()), font=("Arial", 25), height=3, bg="#00abff").pack(fill=X)
for i in t.all_answers: # t.all_answers is pulling all of the multiple choice answers ie "coke", "pepsi" "sprite"
buttons.append(Buttons(i).create()) # i is the individual answer eg "pepsi" and is making a button
root.mainloop()

How to close a new windows that is created by a function

I have a tkinter UI which has a frame, the frame has 2 canvases, 1 canvas has a button that creates a top-level window (named top). That top-level window has a CLOSE button that closes the top window (which is easily done by top.destoy). But, I need the CLOSE button to also call a function that does something. So, since CLOSE button cannot be configured to call something() and destroy(), I set the button to call sequence() which calls something() and top.destroy().
When I run this and hit the CLOSE button, I get the error name 'top' is not defined. I know why it's happening, but I don't know how to fix this. Any ideas?
import time
import tkinter as tk
import tkinter.font
from tkinter import*
window = Tk()
window.geometry("1920x1080")
window.title("HOME")
f1 = Frame (window, bg="white")
f1.pack()
c1 = Canvas(f1, height=200, width=1960, bg="white")
label = Label(f1, text="Running Apps", font= "Cambria 30 bold").pack()
c1.pack(anchor=N)
r = c1.create_rectangle(400, 50, 550, 150, fill="white", activefill="black")
r2 = c1.create_rectangle(550, 50, 700, 150, fill="white", activefill="black")
c2 = tk.Canvas(f1, height=800, width=1960, bg="white")
c2.pack(side="bottom")
def sequence():
top.destroy()
c1.itemconfig(r, fill="white") #something()
def openApp1():
c1.itemconfig(r, fill="red")
top = Toplevel()
top.geometry("1920x1080")
top.title("App 1")
cvs1 = tk.Canvas(top, height="880", width="800", bg="red")
Closebutton = Button(cvs1, text="CLOSE", command=sequence, padx="20", pady="0", justify="center", height="1", width="6", font="Cambria 20 bold", borderwidth="7")
cvs1.create_window(400, 600, window=Closebutton)
label1 = Label(top, text="I am App 1", font= "Cambria 50 bold")
label1.place(x=630, y=100)
cvs1.pack()
button1= Button(c2, bg="red", text="App 1", command=openApp1, padx="20", pady="10", justify="center", height="3", width="10", font="Cambria 30 bold", borderwidth="10")
c2.create_window(100, 200, anchor=NW, window=button1)
window.mainloop()
Use global top inside openApp1 and it will assign TopLevel to global variable (instead of local variable) and it will resolve problem in sequence
def openApp1():
global top
c1.itemconfig(r, fill="red")
top = Toplevel()

Can I stack a Frame on top of a canvas? (Tkinter)

I'm new to coding and am attempting to make some sort of EPOS type system just as a project for the shop I work in. I want to stack a frame to have a keypad for a log in code on top of a background image, just for the start of the program. Essentially no matter how I try to stack the different Tkinter widgets, it never seems to work.
I've tried placing the canvas which holds the image in the main Tk() and then place the frame on top of that, to then use a grid structure to build the keypad put that didn't work.
I tried different combinations of which widget parents which other widget etc, and couldn't get anything to work. It usually ended up with no frame visible, and the 1920x1080 image being pushed to the bottom right of the screen.
screen_width = 1920
screen_height = 1080
screen_geometry = '{}x{}'.format(screen_width, screen_height)
main_window = Tk()
main_window.title('Shop')
main_window.resizable(0,0)
main_window.geometry(screen_geometry)
background_image = PhotoImage(master=C, file='logo.png')
C = Canvas(main_window, bg="blue", height=screen_height, width=screen_width)
background_label = Label(C, image=background_image)
background_label.place(x=0, y=0, relwidth=1, relheight=1)
C.place(x=0, y=0, relwidth=1, relheight=1)
login_window = Frame(main_window, borderwidth=5, relief=GROOVE)
login_window.config(width=10, height=10)
login_window.place(x=0, y=0, relwidth=1, relheight=1)
test_button = Button(login_window, text="test")
test_button.grid(column=0, row=0)
main_window.mainloop()
I expected the logo to be placed underneath the frame, and then I'd be able to use the frame with a normal grid structure, but it didn't seem to work at all.
This code is messy and poor, so some constructive criticism and help overall would be lovely.
Thank you.
From my understanding, you want to have a login window with a background image and a keypad at the center of the window. Below is a sample code:
from tkinter import *
screen_width = 1920 // 2
screen_height = 1080 // 2
screen_geometry = '{}x{}'.format(screen_width, screen_height)
main_window = Tk()
main_window.title('Shop')
main_window.resizable(0, 0)
main_window.geometry(screen_geometry)
# background image
background_image = PhotoImage(file='logo.png')
background_label = Label(main_window, image=background_image)
background_label.place(x=0, y=0, relwidth=1, relheight=1)
# keypad at the center of window
login_frame = Frame(main_window)
login_frame.place(relx=0.5, rely=0.5, anchor=CENTER)
display = Label(login_frame, bg='black', font=('', 20))
display.grid(row=0, column=0, columnspan=3, sticky='ew')
def input_digit(n):
print(n)
font = ('', 16, 'bold')
numpad = []
for number in range(9):
row = number // 3
col = number % 3
btn = Button(login_frame, text=number+1, font=font, width=5, height=2)
btn.grid(row=row+1, column=col)
btn.config(command=lambda n=number+1:input_digit(n))
numpad.append(btn)
main_window.mainloop()

How to use tick() in a class [Python 3.x]

So basically I am doing a school project and it involves classes and tkinter, I want to put my tick() function into the class so that I can have a clock in my program, however I can't seem to get it to work when I add it to a class?
Any help/advice would be appreciated.
import urllib.request
from tkinter import *
from tkinter import ttk
import time
class MainWindow(object):
def __init__(self):
self.root = Tk()
self.root.state("zoomed") #to make it full screen
self.root.title("Vehicle Window Fitting - Management System")
self.root.configure(bg="grey80")
self.frame_1 = Frame(self.root, width=1350, height=50)
self.frame_1.pack(side=TOP, fill=X, expand=1, anchor=N)
self.title_lbl = Label(self.frame_1, font=('arial', 12, 'bold'), text="Vehicle Window Fitting - Management System", bd=5, anchor=W)
self.title_lbl.pack(side=LEFT) #puts title on left side
self.clockFrame = Frame(self.frame_1, width=100, height=50, bd=4, relief="ridge")
self.clockFrame.pack(side=RIGHT)#puts clock frame on right
self.clockLabel = Label(self.clockFrame, font=('arial', 12, 'bold'), bd=5, anchor=E)
self.clockLabel.pack() #puts the number in the clock frame
def tick(self, curtime=''): #acts as a clock, changing the label when the time goes up
newtime = time.strftime('%H:%M:%S')
if newtime != curtime:
curtime = newtime
self.clockLabel.config(text=curtime)
self.clockLabel.after(200, tick, curtime)
(more code here but irrelevant)
then:
window = MainWindow()
clock = window.tick()
Everything is in place correctly but the clock won't change it is stationary. I have managed to get it working outside of a class but how do I implement it into a class?
fixed by changing
self.clockLabel.after(200, tick, curtime)
to
self.clockLabel.after(200, self.tick, curtime)
took me a long time to figure that one out haha

Resources