Skip to content

Commit

Permalink
Merge pull request StarkOdinson612#2 from StarkOdinson612/VideoFeed
Browse files Browse the repository at this point in the history
Video feed
  • Loading branch information
StarkOdinson612 authored Sep 11, 2023
2 parents a65cf46 + 700a994 commit 2a4f2af
Show file tree
Hide file tree
Showing 11 changed files with 260 additions and 109 deletions.
17 changes: 17 additions & 0 deletions setup.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
from cx_Freeze import setup,Executable

include_files = ['QRCodeAttendanceV2', 'src']

options = {
'build.exe': {
'include_files':include_files
}
}

setup(
name="QR Attendance",
version=0.1,
description="A QR-based attendance system utilizing JSON data storage (local)",
executables=[Executable("src/main.py", base="Win32GUI")],
options=options
)
9 changes: 7 additions & 2 deletions src/Constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,10 @@ class Constants:
src_dir = os.path.abspath(os.path.join(script_dir, '..'))

# Specify the path to the JSON file
JSON_PATH = os.path.join(src_dir, 'src','Data', 'MemberList.json')
JSON_PATH = os.path.join(src_dir, 'src', 'Data', 'MemberList.json')
MEETING_DATES_PATH = os.path.join(src_dir, 'src', 'Data', 'AllDates.txt')
RESOURCES_PATH = os.path.join(src_dir, 'src', 'Resources')
DOWNLOADS_PATH = os.path.join(os.path.expanduser("~"), "Downloads")

RED_COLOR = "#D63D3D"
RED_HOVER_COLOR = "#BC3535"
Expand All @@ -18,4 +21,6 @@ class Constants:
GREEN_HOVER_COLOR = "#30A15F"

BLUE_COLOR = "#409DBF"
BLUE_HOVER_COLOR = "#327A94"
BLUE_HOVER_COLOR = "#327A94"

GRAY_BG_COLOR = "#949494"
Empty file added src/Data/AllDates.txt
Empty file.
41 changes: 1 addition & 40 deletions src/Data/MemberList.json
Original file line number Diff line number Diff line change
@@ -1,40 +1 @@
{
"182576": {
"name": "Ishaan",
"attendance": {
"2023-09-06": "0"
}
},
"1": {
"name": "Ishaan",
"attendance": {}
},
"2": {
"name": "Gene",
"attendance": {}
},
"3": {
"name": "Banana",
"attendance": {}
},
"4": {
"name": "Onion",
"attendance": {}
},
"5": {
"name": "Mason",
"attendance": {}
},
"6": {
"name": "Bob",
"attendance": {}
},
"7": {
"name": "Joe",
"attendance": {}
},
"8": {
"name": "Bong",
"attendance": {}
}
}
{}
21 changes: 14 additions & 7 deletions src/QRTools/QRDaemon.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import json
from queue import Queue

import cv2
import time

Expand All @@ -7,9 +9,10 @@


class QRDaemon:
def __init__(self, member_list: MembersFrame):
def __init__(self, member_list: MembersFrame, img_q: Queue):
self.member_list = member_list
self.qr_code_detector = cv2.QRCodeDetector()
self.img_q = img_q

# Function to decode and display QR code
def read_qr_code(self, image):
Expand All @@ -24,37 +27,41 @@ def read_qr_code(self, image):
temp = json.load(f)
if not temp.get(data) is None:
self.member_list.sign_in(data)
time.sleep(2)

print("QR Code Data:", data)

# Display the QR code data on the screen
cv2.putText(image, data, (50, 50), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2)
cv2.imshow("QR Code Reader", image)

cv2.waitKey(0)

def main(self):
# Initialize the camera or read a video file
itime = time.time()
cap = cv2.VideoCapture(0) # Change to the appropriate camera index or video file path
print(time.time() - itime)

while True:
# Read a frame from the camera or video file
ret, frame = cap.read()

gray_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

if not ret:
break

gray_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
if not self.img_q.full():
self.img_q.put(gray_frame)

# Detect and decode QR codes in the frame
self.read_qr_code(gray_frame)

# Wait for 2 seconds before processing the next code
time.sleep(2)
time.sleep(0.05)

# Close the displayed window if 'q' key is pressed
if cv2.waitKey(1) & 0xFF == ord('q'):
break

# Release the camera and close all OpenCV windows
cap.release()
cv2.destroyAllWindows()
cv2.destroyAllWindows()
Binary file added src/Resources/blank_img.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
99 changes: 69 additions & 30 deletions src/UI/Dashboard/DashboardUI.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,22 @@
import os.path
import threading
import time
from queue import Queue
from PIL import Image

import PIL
import customtkinter

from src.Constants import Constants
from src.QRTools.QRDaemon import QRDaemon
from src.UI.Dashboard.MembersFrame import MembersFrame

import threading


class DashboardUI:
def __init__(self, parent: customtkinter.CTkTabview):
self.ID = "Dashboard"
self.parent = parent
self.parent.tab(self.ID).grid_columnconfigure((0, 1, 2), weight=1, pad=10)
self.parent.tab(self.ID).grid_columnconfigure((0, 1, 2, 3), weight=1, pad=10)
self.parent.tab(self.ID).grid_rowconfigure(0, weight=1)

self.parent.member_section = MembersFrame(master=parent.tab(self.ID))
Expand All @@ -20,52 +25,86 @@ def __init__(self, parent: customtkinter.CTkTabview):
sticky="nsew",
rowspan=2,
pady=(15, 0),
padx=15)
padx=15,
columnspan=3)

self.sign_out_all = customtkinter.CTkButton(master=parent.tab(self.ID),
text="Sign Out All",
fg_color=Constants.RED_COLOR,
bg_color="transparent",
hover_color=Constants.RED_HOVER_COLOR,
command=self.parent.member_section.sign_out_all)
self.sign_out_all.grid(row=3, column=0, sticky="sew", pady=(10, 10), padx=15)
self.sign_out_all.grid(row=3, column=1, sticky="sew", pady=(10, 10), padx=15)

self.right_frame = RightFrame(self.parent.tab(self.ID), member_section=self.parent.member_section)
self.right_frame.grid(row=0, column=3, padx=10, pady=10, sticky="nsew")


self.manual_sign_in = ManualSignIn(member_section=self.parent.member_section,
master=parent.tab(self.ID))
self.manual_sign_in.grid(row=0, column=1, pady=10, padx=10, sticky="new")
# self.bob = customtkinter.CTkEntry(master=parent.tab(self.ID))
# self.bob.grid(row=0,column=1,sticky="n")
#
# self.submit = customtkinter.CTkButton(master=parent.tab(self.ID), command=self.add_bit)
# self.submit.grid(row=2,column=1)
# self.rem = customtkinter.CTkButton(master=parent.tab(self.ID), command=self.remove_bit)
# self.rem.grid(row=3, column=1)

# parent.label = customtkinter.CTkLabel(master=parent.tab(self.ID))
# parent.label.grid(row=0, colpipumn=0, padx=0, pady=0)


class RightFrame(customtkinter.CTkFrame):
def __init__(self, master: any, member_section: MembersFrame, **kwargs):
super().__init__(master, **kwargs)

self.member_section = member_section

self.qrb = customtkinter.CTkButton(master=parent.tab(self.ID),
self.img_queue = Queue()

self.grid_columnconfigure(0, weight=1)
self.grid_rowconfigure(1, weight=1)

self.manual_sign_in = ManualSignIn(member_section=self.member_section,
master=self)
self.manual_sign_in.grid(row=0, column=0, pady=10, padx=10, sticky="new")

self.image_frame = customtkinter.CTkFrame(master=self)
self.image_frame.grid(row=1, column=0, padx=10, pady=10, sticky="nsew")
self.image_frame.grid_columnconfigure(0, weight=1)
self.image_frame.grid_rowconfigure(0, weight=1)

self.image_w = customtkinter.CTkImage(
light_image=Image.open(os.path.join(Constants.RESOURCES_PATH, 'blank_img.png')),
size=(20, 20))
self.img_label = customtkinter.CTkLabel(self.image_frame, image=self.image_w, text="")
self.img_label.grid(row=0, column=0, padx=5, pady=10, sticky="")

self.qrb = customtkinter.CTkButton(master=self,
text="QR",
fg_color=Constants.BLUE_COLOR,
bg_color="transparent",
hover_color=Constants.BLUE_HOVER_COLOR,
command=self.launch_qr)
self.qrb.grid(row=1, column=1, padx=10, pady=10)
# self.bob = customtkinter.CTkEntry(master=parent.tab(self.ID))
# self.bob.grid(row=0,column=1,sticky="n")
#
# self.submit = customtkinter.CTkButton(master=parent.tab(self.ID), command=self.add_bit)
# self.submit.grid(row=2,column=1)
# self.rem = customtkinter.CTkButton(master=parent.tab(self.ID), command=self.remove_bit)
# self.rem.grid(row=3, column=1)

self.qrb.grid(row=2, column=0, padx=10, pady=10)

def read_cam_img(self):
while True:
if self.img_queue.full():
continue
self.image_w.configure(light_image=Image.fromarray(self.img_queue.get()))
self.img_label.configure(image=self.image_w, text="")
time.sleep(0.05)

def launch_qr(self):
qr_daemon = QRDaemon(member_list=self.parent.member_section)
self.image_w.configure(size=(400,400))
qr_daemon = QRDaemon(member_list=self.member_section, img_q=self.img_queue)
qr_daemon_thread = threading.Thread(target=qr_daemon.main)
qr_daemon_thread.daemon = True
qr_daemon_thread.start()

def add_bit(self):
id = self.bob.get()
self.bob.select_clear()

self.parent.member_section.sign_in(id)

def remove_bit(self):
id = self.bob.get()
self.parent.member_section.sign_out(id)

# parent.label = customtkinter.CTkLabel(master=parent.tab(self.ID))
# parent.label.grid(row=0, column=0, padx=0, pady=0)
img_update_thread = threading.Thread(target=self.read_cam_img)
img_update_thread.daemon = True
img_update_thread.start()


class ManualSignIn(customtkinter.CTkFrame):
Expand Down
38 changes: 28 additions & 10 deletions src/UI/Dashboard/MemberWidget.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,23 +11,41 @@ def __init__(self, master, id, name, **kwargs):
self.name = name
self.master = master

self.grid_columnconfigure((0, 1, 2), weight=1)
self.name_label = customtkinter.CTkLabel(master=self, text=self.name,bg_color="transparent")
self.name_label.grid(row=0, column=0, padx=10, pady=10, sticky="w")

self.grid_columnconfigure(0, weight=1)
self.signout_button = customtkinter.CTkButton(master=self,
text="Sign Out",
command=self.button_event,
text=self.name,
command=self.sign_in_ph,
fg_color=Constants.RED_COLOR,
bg_color="transparent",
hover_color=Constants.RED_HOVER_COLOR)
self.signout_button.grid(row=0, column=2, padx=10, pady=10, sticky="e")
hover_color=Constants.RED_HOVER_COLOR,
border_spacing=10,
corner_radius=5)

self.signout_button.grid(row=0, column=0, padx=8, pady=8, sticky="nsew")

def get_id(self):
return self.id

def get_name(self):
return self.name

def button_event(self):
self.master.sign_out(self.id)
def set_button_state(self, is_signed_in: bool):
if is_signed_in:
self.signout_button.configure(fg_color=Constants.GREEN_COLOR,
hover_color=Constants.GREEN_HOVER_COLOR,
command=self.sign_out_ph,
border_spacing=10,
corner_radius=5)

else:
self.signout_button.configure(fg_color=Constants.RED_COLOR,
hover_color=Constants.RED_HOVER_COLOR,
command=self.sign_in_ph,
border_spacing=10,
corner_radius=5)

def sign_in_ph(self):
self.master.sign_in(self.id)

def sign_out_ph(self):
self.master.sign_out(self.id)
Loading

0 comments on commit 2a4f2af

Please sign in to comment.