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