1+ # this imports everything from the tkinter module
2+ from tkinter import *
3+ # importing the ttk module from tkinter that's for styling widgets
4+ from tkinter import ttk
5+ # importing message boxes like showinfo, showerror, askyesno from tkinter.messagebox
6+ from tkinter .messagebox import showinfo , showerror , askyesno
7+ # importing filedialog from tkinter
8+ from tkinter import filedialog as fd
9+ # this imports the qrcode module
10+ import qrcode
11+ # this imports the cv2 module
12+ import cv2
13+
14+
15+
16+ # the function to close the window
17+ def close_window ():
18+ # this will ask the user whether to close or not
19+ # if the value is yes/True the window will close
20+ if askyesno (title = 'Close QR Code Generator-Detector' , message = 'Are you sure you want to close the application?' ):
21+ # this destroys the window
22+ window .destroy ()
23+
24+
25+
26+
27+ # the function for generating the QR Code
28+ def generate_qrcode ():
29+ # getting qrcode data from data_entry via get() function
30+ qrcode_data = str (data_entry .get ())
31+ # getting the qrcode name from the filename_entry via get() function
32+ qrcode_name = str (filename_entry .get ())
33+ # checking if the qrcode_name/filename_entry is empty
34+ if qrcode_name == '' :
35+ # if its empty display an error message to the user
36+ showerror (title = 'Error' , message = 'An error occurred' \
37+ '\n The following is ' \
38+ 'the cause:\n ->Empty filename entry field\n ' \
39+ 'Make sure the filename entry field is filled when generating the QRCode' )
40+
41+ # the else statement will execute when the qrcode_name/filename_entry is filled
42+ else :
43+ # confirm from the user whether to generate QR code or not
44+ if askyesno (title = 'Confirmation' , message = f'Do you want to create a QRCode with the provided information?' ):
45+ # the try block for generating the QR Code
46+ try :
47+ # Creating an instance of QRCode class
48+ qr = qrcode .QRCode (version = 1 , box_size = 6 , border = 4 )
49+ # Adding data to the instance 'qr'
50+ qr .add_data (qrcode_data )
51+ #
52+ qr .make (fit = True )
53+ # the name for the QRCode
54+ name = qrcode_name + '.png'
55+ # making the QR code
56+ qrcode_image = qr .make_image (fill_color = 'black' , back_color = 'white' )
57+ # saving the QR code
58+ qrcode_image .save (name )
59+ # making the Image variable global
60+ global Image
61+ # opening the qrcode image file
62+ Image = PhotoImage (file = f'{ name } ' )
63+ # displaying the image on the canvas via the image label
64+ image_label1 .config (image = Image )
65+ # the button for resetting or clearing the QR code image on the canvas
66+ reset_button .config (state = NORMAL , command = reset )
67+
68+ # this will catch all the errors that might occur
69+ except :
70+ showerror (title = 'Error' , message = 'Please provide a valid filename' )
71+
72+ # the function for resetting or clearing the image label
73+ def reset ():
74+ # confirming if the user wants to reset or not
75+ if askyesno (title = 'Reset' , message = 'Are you sure you want to reset?' ):
76+ # if yes reset the label
77+ image_label1 .config (image = '' )
78+ # and disable the button again
79+ reset_button .config (state = DISABLED )
80+
81+
82+ # the function to open file dialogs
83+ def open_dialog ():
84+ # getting the file name via the askopenfilename() function
85+ name = fd .askopenfilename ()
86+ # deleting every data from the file_entry
87+ file_entry .delete (0 , END )
88+ # inserting the file in the file_entry
89+ file_entry .insert (0 , name )
90+
91+
92+ # the function to detect the QR codes
93+ def detect_qrcode ():
94+
95+ # getting the image file from the file entry via get() function
96+ image_file = file_entry .get ()
97+ # checking if the image_file is empty
98+ if image_file == '' :
99+ # show error when the image_file entry is empty
100+ showerror (title = 'Error' , message = 'Please provide a QR Code image file to detect' )
101+
102+ # executes when the image_file is not empty
103+ else :
104+ # code inside the try will detect the QR codes
105+ try :
106+ # reading the image file with cv2
107+ qr_img = cv2 .imread (f'{ image_file } ' )
108+ # using the QRCodeDetector() function
109+ qr_detector = cv2 .QRCodeDetector ()
110+ # making the qrcodde_image global
111+ global qrcode_image
112+ # opening the qrcode_image using the PhotoImage
113+ qrcode_image = PhotoImage (file = f'{ image_file } ' )
114+ # displaying the image via the image label
115+ image_label2 .config (image = qrcode_image )
116+ # using the detectAndDecode() function detect and decode the QR code
117+ data , pts , st_code = qr_detector .detectAndDecode (qr_img )
118+ # displaying data on the data_label
119+ data_label .config (text = data )
120+
121+ # this catches any errors that might occur
122+ except :
123+ # displaying an error message
124+ showerror (title = 'Error' , message = 'An error occurred while detecting data from the provided file' \
125+ '\n The following could be ' \
126+ 'the cause:\n ->Wrong image file\n ' \
127+ 'Make sure the image file is a valid QRCode' )
128+
129+
130+
131+
132+
133+ # creating the window using the Tk() class
134+ window = Tk ()
135+ # creates title for the window
136+ window .title ('QR Code Generator-Detector' )
137+ # adding the window's icon
138+ window .iconbitmap (window , 'icon.ico' )
139+ # dimensions and position of the window
140+ window .geometry ('500x480+440+180' )
141+ # makes the window non-resizable
142+ window .resizable (height = FALSE , width = FALSE )
143+ # this is for closing the window via the close_window() function
144+ window .protocol ('WM_DELETE_WINDOW' , close_window )
145+
146+
147+
148+ """Styles for the widgets, labels, entries, and buttons"""
149+ # style for the labels
150+ label_style = ttk .Style ()
151+ label_style .configure ('TLabel' , foreground = '#000000' , font = ('OCR A Extended' , 11 ))
152+
153+ # style for the entries
154+ entry_style = ttk .Style ()
155+ entry_style .configure ('TEntry' , font = ('Dotum' , 15 ))
156+
157+ # style for the buttons
158+ button_style = ttk .Style ()
159+ button_style .configure ('TButton' , foreground = '#000000' , font = ('DotumChe' , 10 ))
160+
161+ # creating the Notebook widget
162+ tab_control = ttk .Notebook (window )
163+
164+ # creating the two tabs with the ttk.Frame()
165+ first_tab = ttk .Frame (tab_control )
166+ second_tab = ttk .Frame (tab_control )
167+
168+ # adding the two tabs to the Notebook
169+ tab_control .add (first_tab , text = 'QR Code Generator' )
170+ tab_control .add (second_tab , text = 'QR Code Detector' )
171+ # this makes the Notebook fill the entire main window so that its visible
172+ tab_control .pack (expand = 1 , fill = "both" )
173+
174+
175+ # creates the canvas for containing all the widgets in the first tab
176+ first_canvas = Canvas (first_tab , width = 500 , height = 480 )
177+ # packing the canvas to the first tab
178+ first_canvas .pack ()
179+
180+ # creates the canvas for containing all the widgets in the second tab
181+ second_canvas = Canvas (second_tab , width = 500 , height = 480 )
182+ # packing the canvas to the second tab
183+ second_canvas .pack ()
184+
185+
186+ """Widgets for the first tab"""
187+
188+ # creating an empty label
189+ image_label1 = Label (window )
190+ # adding the label to the canvas
191+ first_canvas .create_window (250 , 150 , window = image_label1 )
192+
193+ # creating a ttk label
194+ qrdata_label = ttk .Label (window , text = 'QRcode Data' , style = 'TLabel' )
195+ # creating a ttk entry
196+ data_entry = ttk .Entry (window , width = 55 , style = 'TEntry' )
197+
198+ # adding the label to the canvas
199+ first_canvas .create_window (70 , 330 , window = qrdata_label )
200+ # adding the entry to the canvas
201+ first_canvas .create_window (300 , 330 , window = data_entry )
202+
203+ # creating a ttk label
204+ filename_label = ttk .Label (window , text = 'Filename' , style = 'TLabel' )
205+ # creating a ttk entry
206+ filename_entry = ttk .Entry (width = 55 , style = 'TEntry' )
207+
208+ # adding the label to the canvas
209+ first_canvas .create_window (84 , 360 , window = filename_label )
210+ # adding the entry to the canvas
211+ first_canvas .create_window (300 , 360 , window = filename_entry )
212+
213+
214+ # creating the reset button in a disabled mode
215+ reset_button = ttk .Button (window , text = 'Reset' , style = 'TButton' , state = DISABLED )
216+ # creating the generate button
217+ generate_button = ttk .Button (window , text = 'Generate QRCode' , style = 'TButton' , command = generate_qrcode )
218+
219+ # adding the reset button to the canvas
220+ first_canvas .create_window (300 , 390 , window = reset_button )
221+ # adding the generate button to the canvas
222+ first_canvas .create_window (410 , 390 , window = generate_button )
223+
224+
225+ """Below are the widgets for the second tab"""
226+
227+ # creating the second image label
228+ image_label2 = Label (window )
229+ # creating the data label
230+ data_label = ttk .Label (window )
231+
232+ # adding the second image label to the second_canvas
233+ second_canvas .create_window (250 , 150 , window = image_label2 )
234+ # adding the data label to the canvas
235+ second_canvas .create_window (250 , 300 , window = data_label )
236+
237+ # creating the file_entry
238+ file_entry = ttk .Entry (window , width = 60 , style = 'TEntry' )
239+ # creating the browse button
240+ browse_button = ttk .Button (window , text = 'Browse' , style = 'TButton' , command = open_dialog )
241+
242+ # adding the entry to the canvas
243+ second_canvas .create_window (200 , 350 , window = file_entry )
244+ # adding the generate button to the canvas
245+ second_canvas .create_window (430 , 350 , window = browse_button )
246+
247+ # creating the detect button
248+ detect_button = ttk .Button (window , text = 'Detect QRCode' , style = 'TButton' , command = detect_qrcode )
249+ # adding the detect button to the canvas
250+ second_canvas .create_window (65 , 385 , window = detect_button )
251+
252+
253+ # run the main window infinitely
254+ window .mainloop ()
0 commit comments