Skip to content

Commit 0f881a9

Browse files
committed
add qrcode gui tutorial
1 parent 0300b45 commit 0f881a9

File tree

5 files changed

+258
-0
lines changed

5 files changed

+258
-0
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,5 +250,6 @@ This is a repository of all the tutorials of [The Python Code](https://www.thepy
250250
- [How to Create an Alarm Clock App using Tkinter in Python](https://www.thepythoncode.com/article/build-an-alarm-clock-app-using-tkinter-python). ([code](gui-programming/alarm-clock-app))
251251
- [How to Build a GUI Voice Recorder App in Python](https://www.thepythoncode.com/article/make-a-gui-voice-recorder-python). ([code](gui-programming/voice-recorder-app))
252252
- [How to Make a Chess Game with Pygame in Python](https://www.thepythoncode.com/article/make-a-chess-game-using-pygame-in-python). ([code](gui-programming/chess-game))
253+
- [How to Build a GUI QR Code Generator and Detector Using Python](https://www.thepythoncode.com/article/make-a-qr-code-generator-and-reader-tkinter-python). ([code](gui-programming/qrcode-generator-reader-gui))
253254

254255
For any feedback, please consider pulling requests.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# [How to Build a GUI QR Code Generator and Detector Using Python](https://www.thepythoncode.com/article/make-a-qr-code-generator-and-reader-tkinter-python)
Binary file not shown.
Lines changed: 254 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,254 @@
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+
'\nThe 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+
'\nThe 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()
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
python-opencv
2+
qrcode

0 commit comments

Comments
 (0)