Python – Learn Queue GUI

Tkinter GUI to learn Queue, Put, Get, Empty, Full, Exception Handling

Short video about 42sec

Python Learn Queue – Code Text

# -*- coding: utf-8 -*-
# 
#Date: 4/11/2023 Time 3:24 PM
#

from tkinter import *
from queue import Queue,Full,Empty
import threading as td

def Test_Q_Empty(q):
      if(q.empty()):
          canv1.itemconfigure(Queue_Empty_LED,fill='lightgreen')
      else:
          canv1.itemconfigure(Queue_Empty_LED,fill='grey')
      return

def Test_Q_Full(q):
      if(q.full()):
          canv2.itemconfigure(Queue_Full_LED,fill='lightgreen')
      else:
          canv2.itemconfigure(Queue_Full_LED,fill='grey')
      return        
          
def Refresh_Label_autoscroll():
    global Label_Result_List
    RESULT['text']=""
    for line in Label_Result_List:
       RESULT['text']=RESULT['text'] + str(line)+"\n"
    myWindow.update()   
    return   

Test_Result_List=[]
#Test_Result_Dict={'TestName':"",'Measured':0,'Result':"NotTested"} Dont DO THIS or all will be the same

Num_of_Test=20
TRD={}
for i in range(Num_of_Test):
    Test_Result_Dict={} #this way
    Test_Result_Dict['TestName']="TestName_"+"{:02d}".format(i)  #formating 2 digits
    Test_Result_Dict['Measured']=i+100
    Test_Result_Dict['Result']="Passed"
    Test_Result_List.append(Test_Result_Dict)
    print(Test_Result_Dict)    

#Google promtp: print a list with carriage return in one line
#my find credit: stackoverflow "Printing list element on spearate lines in Python": (3rd Answer)
print(*Test_Result_List,sep="\n")
Label_Result_List=[]
#beginner error -- wrong way touching one will affect the other (like pointer) Label_Result_List=Test_Result_List
Label_Result_List=Test_Result_List.copy() #use copy to make a Different list

#print(Test_Result_List)

#GUI setup below
myWindow=Tk()
myWindow.title("Python-Learn_Queue_GUI")
myWindow.minsize(810,460)


# do this or frame in window will not follow window (expanding)
myWindow.grid_rowconfigure(0,weight=1)  #need on row define as 1 for expanding row wise bottomframe
myWindow.grid_columnconfigure(0,weight=1)
#only one frame so 0,0 configure

#frame1 
# adjust r,c,sticky, row and column config as need
frame1=Frame(myWindow,width=50,height=50,bg='lightblue')
frame1.grid(row=0, column=0, sticky='NWES', padx=10, pady=10, columnspan=1)
frame1.rowconfigure(8,weight=1) #only expand after last button
frame1.columnconfigure(5,weight=1) #the lastcol goes along with rigth side expanding
#where do you want it to exapand column5  last row 

#LED info
LTRY=5 #light top right Y
LTRX=15 #light top right X
dia=20


#Label used canv text instead so its close to led
#Q_EMPTY=Label(frame1, text="Q is Empty",width=15)
#Q_EMPTY.grid(row=3, column=2, padx=10, pady=(10,0), columnspan=1,sticky='N')



#Led Indictor
canv1=Canvas(frame1,width=150, height=30, bg='lightblue', bd=1, highlightthickness=1)
canv1.grid(row=4, column=2, columnspan=1,sticky="")
Queue_Empty_LED=canv1.create_oval(LTRX,LTRY,LTRX+dia,LTRY+dia,fill='black')
Queue_Empty_Text=canv1.create_text(80,LTRX,width=100,text="Q is Empty")

#Label
#Q_FULL=Label(frame1, text="Q is Full",width=15)
#Q_FULL.grid(row=5, column=2, padx=10, pady=(10,0), columnspan=1,sticky='N')

#Led Indictor

canv2=Canvas(frame1,width=150, height=30, bg='lightblue', bd=1, highlightthickness=1)
canv2.grid(row=5, column=2, columnspan=1,sticky="")
Queue_Full_LED=canv2.create_oval(LTRX,LTRY,LTRX+dia,LTRY+dia,fill='black')
Queue_Full_Text=canv2.create_text(80,LTRX,width=100,text="Q is full")

canv3=Canvas(frame1,width=150, height=30, bg='lightblue', bd=1, highlightthickness=1)
canv3.grid(row=6, column=2, columnspan=1,sticky="")
Queue_Msg_LED=canv3.create_oval(LTRX,LTRY,LTRX+dia,LTRY+dia,fill='black')
Queue_Mag_Text=canv3.create_text(80,LTRX,width=100,text="Q Exception Handled ")
#achor and justify tricky in create text it work better without them in this case


#Label
APP_NAME=Label(frame1, text=" Testing - Queue Functions ",width=25)
APP_NAME.grid(row=0, column=0, padx=10, pady=10, columnspan=1,sticky='')

#Label
COMPANY_NAME=Label(frame1, text="testengineerresource.com",width=25)
COMPANY_NAME.grid(row=0, column=5, padx=10, pady=10, columnspan=1,sticky='E')

#Label
USERMSG=Label(frame1, text="Message Area",width=25)
USERMSG.grid(row=2, column=5, padx=10, pady=10, columnspan=1,sticky='E')

#Label
RESULT=Label(frame1, text="NoInfoYet",width=25,height=20,anchor='nw',justify='left')
RESULT.grid(row=3, column=5, padx=10, pady=10, columnspan=1,rowspan=7,sticky='NWSE')
#rowspan all rows so button not affected
#only Result Label will expand with window all directions



#Button
Q_PUT=Button(frame1, text='Q_PUT',width=15, command=lambda:frame_Button_Q_PUT("Q_PUT"))
Q_PUT.grid(row=3, column=0,padx=10,pady=10,sticky='')

Test_Index=0

def frame_Button_Q_PUT(button_text):
    global Done_Flag
    global Test_Index
    print(button_text)
    Test_Q_Full(que)
    Test_Q_Empty(que)
    if(Test_Index<Num_of_Test):
        try:    
            print("Test Index: ",Test_Index)
            print(Test_Result_List[Test_Index])
            if(que.empty()):
                Done_Flag=False
                td.Thread(target=Tell_Manager_Done(que), daemon=True).start()
            que.put(Test_Result_List[Test_Index],block=False)  #not que.put= NO, added timeout so you can see affect but will not hang app
            #que.put(Test_Result_List[Test_Index],timeout=1)  #not que.put= NO, added timeout so you can see affect but will not hang app
            Label_Result_List.append("Queue Add:"+str(Test_Result_List[Test_Index]))
            Label_Result_List.pop(0)
            Refresh_Label_autoscroll()  #a way to gave a scrollable label could not find a good label end to autoscroll, almost a que by list, really should have been text with scrollbar
            canv3.itemconfigure(Queue_Msg_LED,fill='gray')
            Test_Index=Test_Index+1
        except Full:
            canv3.itemconfigure(Queue_Msg_LED,fill='red')
            Label_Result_List.pop(0)
            Label_Result_List.append("Queue is Full and attempted Put performed, Suggest Q_Get") 
            Refresh_Label_autoscroll()  #  
            print("Handling Que Error Put on a Filled up que")
            pass  #continue
    else:
        Label_Result_List.pop(0)
        Label_Result_List.append("No more Test in List")        
        Refresh_Label_autoscroll()
        Reload_TestList['state']='normal'
    Test_Q_Full(que)
    Test_Q_Empty(que)
    print(button_text)
    return





#Button  ======Q_GET
Q_GET=Button(frame1, text='Q_GET',width=15, command=lambda:frame_Button_Q_GET("Q_GET"))
Q_GET.grid(row=4, column=0,padx=10,pady=10,sticky='')

def frame_Button_Q_GET(button_text):
  global Done_Flag  
  print(button_text)
  Test_Q_Empty(que)
  Test_Q_Full(que)  
  try:
    item=que.get(block=False) #equivalent .get_nowait #see how block= false behaves, t1sec this can halt here if no que most time not desired 
    #item=(que.get(timeout=1)) #t1sec this  can halt here if no que most time not desired 

    Label_Result_List.pop(0)
    Label_Result_List.append("Queue Get:"+str(item))
    Refresh_Label_autoscroll()  #a way to gave a scrollable label could not find a good label end to autoscroll, almost a que by list, really should have been text with scrollbar    
    canv3.itemconfigure(Queue_Msg_LED,fill='gray')
  except Empty: #credit stackoverflow:"Python Queue.Empty Exception handling" the last answer in list help me
      canv3.itemconfigure(Queue_Msg_LED,fill='red')
      print("Handling Que Error Get on an empty que")
      Label_Result_List.pop(0)
      Label_Result_List.append("Queue is Empty and attempted Get performed, Suggest Q_PUT") 
      Refresh_Label_autoscroll()  #  
      #####que.task_done() # can not use in tkinter GUI
      Done_Flag=True
      pass  #continue
  Test_Q_Empty(que)
  Test_Q_Full(que)
  return



#Button
Q_DATA=Button(frame1, text='Q_DATA',width=15, command=lambda:frame_Button_Q_DATA("Q_DATA"))
Q_DATA.grid(row=7, column=0,padx=10,pady=10,sticky='')

def frame_Button_Q_DATA(button_text):
  print(button_text)
  Label_Result_List.pop(0)
  Label_Result_List.append("How many item in q: "+str(que.qsize())) 
  Refresh_Label_autoscroll()  # 
  for item in list(que.queue):
      print("Item in Que",item)
      Label_Result_List.pop(0)
      Label_Result_List.append("Item in que: "+str(item)) 
      Refresh_Label_autoscroll()  # 
  return

#Button
Reload_TestList=Button(frame1, text='Reload_TestList',width=15, command=lambda:frame_Button_Reload_TestList("Reload Test List"))
Reload_TestList.grid(row=8, column=0,padx=10,pady=10,sticky='')

def frame_Button_Reload_TestList(button_text):
  print(button_text)
  global Test_Index
  Test_Index=0
  Reload_TestList['state']='disabled'
  return

def Wait_Here():
    global Done_Flag
    print("Thread:Manager wait for you to finish gets", Done_Flag)
    if Done_Flag:
        Label_Result_List.pop(0)
        Label_Result_List.append("Manager I finished reviewing my current que items, more work please") 
        Refresh_Label_autoscroll()
        print("Told Manager I finished my current review of tests")
        Done_Flag=False
    else:
        myWindow.after(1000,Wait_Here)  
        

def Tell_Manager_Done(que):
    global Done_Flag
    print("Started thread")
    #que.join() # YOU know you can not use this in a tkinter GUI
    Done_Flag=False
    Wait_Here()
    #myWindow.update()
    print("finshied a thread")
    return



que=Queue(10)  #max size to to start learning
USERMSG['text']="Max Size of Q=: "+str(que.maxsize)


#show starting list for put to use
RESULT['text']=""
for line in Label_Result_List:
  RESULT['text']=RESULT['text'] + str(line)+"\n"
Reload_TestList['state']='disable'
Done_Flag=True #since at start empty que

#GUI main loop  
myWindow.mainloop()


Download of code

Notes

  • Presentation: Python Learn Queue GUI using
  • Programming Language used: Python 3.7 in Spyder
  • Presentation app: Microsoft’s PowerPoint
  • Python and Tkinter are products of respective company
  • Lots of Help and credit to “Stackoverflow” product of respective company
  • Presentation shown to spark ideas of use.
  • This presentation is not connected to or endorsed by any company.
  • Use at your own risk.
  • Tags: Python, Python3.7, Tkinter, Queue, Canvas ,GUI, List, Dictionary, and Thread (limited scope)

About LV_TS_Test_Engineer_3000_VI

Automated Test Equipment Software
This entry was posted in Test Sector and tagged , , , , , , , , , . Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s