-
Notifications
You must be signed in to change notification settings - Fork 1.9k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
5 changed files
with
258 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +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.
254 changes: 254 additions & 0 deletions
254
gui-programming/qrcode-generator-reader-gui/qrcode_generator_detector.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,254 @@ | ||
# this imports everything from the tkinter module | ||
from tkinter import * | ||
# importing the ttk module from tkinter that's for styling widgets | ||
from tkinter import ttk | ||
# importing message boxes like showinfo, showerror, askyesno from tkinter.messagebox | ||
from tkinter.messagebox import showinfo, showerror, askyesno | ||
# importing filedialog from tkinter | ||
from tkinter import filedialog as fd | ||
# this imports the qrcode module | ||
import qrcode | ||
# this imports the cv2 module | ||
import cv2 | ||
|
||
|
||
|
||
# the function to close the window | ||
def close_window(): | ||
# this will ask the user whether to close or not | ||
# if the value is yes/True the window will close | ||
if askyesno(title='Close QR Code Generator-Detector', message='Are you sure you want to close the application?'): | ||
# this destroys the window | ||
window.destroy() | ||
|
||
|
||
|
||
|
||
# the function for generating the QR Code | ||
def generate_qrcode(): | ||
# getting qrcode data from data_entry via get() function | ||
qrcode_data = str(data_entry.get()) | ||
# getting the qrcode name from the filename_entry via get() function | ||
qrcode_name = str(filename_entry.get()) | ||
# checking if the qrcode_name/filename_entry is empty | ||
if qrcode_name == '': | ||
# if its empty display an error message to the user | ||
showerror(title='Error', message='An error occurred' \ | ||
'\nThe following is ' \ | ||
'the cause:\n->Empty filename entry field\n' \ | ||
'Make sure the filename entry field is filled when generating the QRCode') | ||
|
||
# the else statement will execute when the qrcode_name/filename_entry is filled | ||
else: | ||
# confirm from the user whether to generate QR code or not | ||
if askyesno(title='Confirmation', message=f'Do you want to create a QRCode with the provided information?'): | ||
# the try block for generating the QR Code | ||
try: | ||
# Creating an instance of QRCode class | ||
qr = qrcode.QRCode(version = 1, box_size = 6, border = 4) | ||
# Adding data to the instance 'qr' | ||
qr.add_data(qrcode_data) | ||
# | ||
qr.make(fit = True) | ||
# the name for the QRCode | ||
name = qrcode_name + '.png' | ||
# making the QR code | ||
qrcode_image = qr.make_image(fill_color = 'black', back_color = 'white') | ||
# saving the QR code | ||
qrcode_image.save(name) | ||
# making the Image variable global | ||
global Image | ||
# opening the qrcode image file | ||
Image = PhotoImage(file=f'{name}') | ||
# displaying the image on the canvas via the image label | ||
image_label1.config(image=Image) | ||
# the button for resetting or clearing the QR code image on the canvas | ||
reset_button.config(state=NORMAL, command=reset) | ||
|
||
# this will catch all the errors that might occur | ||
except: | ||
showerror(title='Error', message='Please provide a valid filename') | ||
|
||
# the function for resetting or clearing the image label | ||
def reset(): | ||
# confirming if the user wants to reset or not | ||
if askyesno(title='Reset', message='Are you sure you want to reset?'): | ||
# if yes reset the label | ||
image_label1.config(image='') | ||
# and disable the button again | ||
reset_button.config(state=DISABLED) | ||
|
||
|
||
# the function to open file dialogs | ||
def open_dialog(): | ||
# getting the file name via the askopenfilename() function | ||
name = fd.askopenfilename() | ||
# deleting every data from the file_entry | ||
file_entry.delete(0, END) | ||
# inserting the file in the file_entry | ||
file_entry.insert(0, name) | ||
|
||
|
||
# the function to detect the QR codes | ||
def detect_qrcode(): | ||
|
||
# getting the image file from the file entry via get() function | ||
image_file = file_entry.get() | ||
# checking if the image_file is empty | ||
if image_file == '': | ||
# show error when the image_file entry is empty | ||
showerror(title='Error', message='Please provide a QR Code image file to detect') | ||
|
||
# executes when the image_file is not empty | ||
else: | ||
# code inside the try will detect the QR codes | ||
try: | ||
# reading the image file with cv2 | ||
qr_img = cv2.imread(f'{image_file}') | ||
# using the QRCodeDetector() function | ||
qr_detector = cv2.QRCodeDetector() | ||
# making the qrcodde_image global | ||
global qrcode_image | ||
# opening the qrcode_image using the PhotoImage | ||
qrcode_image = PhotoImage(file=f'{image_file}') | ||
# displaying the image via the image label | ||
image_label2.config(image=qrcode_image) | ||
# using the detectAndDecode() function detect and decode the QR code | ||
data, pts, st_code = qr_detector.detectAndDecode(qr_img) | ||
# displaying data on the data_label | ||
data_label.config(text=data) | ||
|
||
# this catches any errors that might occur | ||
except: | ||
# displaying an error message | ||
showerror(title='Error', message='An error occurred while detecting data from the provided file' \ | ||
'\nThe following could be ' \ | ||
'the cause:\n->Wrong image file\n' \ | ||
'Make sure the image file is a valid QRCode') | ||
|
||
|
||
|
||
|
||
|
||
# creating the window using the Tk() class | ||
window = Tk() | ||
# creates title for the window | ||
window.title('QR Code Generator-Detector') | ||
# adding the window's icon | ||
window.iconbitmap(window, 'icon.ico') | ||
# dimensions and position of the window | ||
window.geometry('500x480+440+180') | ||
# makes the window non-resizable | ||
window.resizable(height=FALSE, width=FALSE) | ||
# this is for closing the window via the close_window() function | ||
window.protocol('WM_DELETE_WINDOW', close_window) | ||
|
||
|
||
|
||
"""Styles for the widgets, labels, entries, and buttons""" | ||
# style for the labels | ||
label_style = ttk.Style() | ||
label_style.configure('TLabel', foreground='#000000', font=('OCR A Extended', 11)) | ||
|
||
# style for the entries | ||
entry_style = ttk.Style() | ||
entry_style.configure('TEntry', font=('Dotum', 15)) | ||
|
||
# style for the buttons | ||
button_style = ttk.Style() | ||
button_style.configure('TButton', foreground='#000000', font=('DotumChe', 10)) | ||
|
||
# creating the Notebook widget | ||
tab_control = ttk.Notebook(window) | ||
|
||
# creating the two tabs with the ttk.Frame() | ||
first_tab = ttk.Frame(tab_control) | ||
second_tab = ttk.Frame(tab_control) | ||
|
||
# adding the two tabs to the Notebook | ||
tab_control.add(first_tab, text='QR Code Generator') | ||
tab_control.add(second_tab, text='QR Code Detector') | ||
# this makes the Notebook fill the entire main window so that its visible | ||
tab_control.pack(expand=1, fill="both") | ||
|
||
|
||
# creates the canvas for containing all the widgets in the first tab | ||
first_canvas = Canvas(first_tab, width=500, height=480) | ||
# packing the canvas to the first tab | ||
first_canvas.pack() | ||
|
||
# creates the canvas for containing all the widgets in the second tab | ||
second_canvas = Canvas(second_tab, width=500, height=480) | ||
# packing the canvas to the second tab | ||
second_canvas.pack() | ||
|
||
|
||
"""Widgets for the first tab""" | ||
|
||
# creating an empty label | ||
image_label1 = Label(window) | ||
# adding the label to the canvas | ||
first_canvas.create_window(250, 150, window=image_label1) | ||
|
||
# creating a ttk label | ||
qrdata_label = ttk.Label(window, text='QRcode Data', style='TLabel') | ||
# creating a ttk entry | ||
data_entry = ttk.Entry(window, width=55, style='TEntry') | ||
|
||
# adding the label to the canvas | ||
first_canvas.create_window(70, 330, window=qrdata_label) | ||
# adding the entry to the canvas | ||
first_canvas.create_window(300, 330, window=data_entry) | ||
|
||
# creating a ttk label | ||
filename_label = ttk.Label(window, text='Filename', style='TLabel') | ||
# creating a ttk entry | ||
filename_entry = ttk.Entry(width=55, style='TEntry') | ||
|
||
# adding the label to the canvas | ||
first_canvas.create_window(84, 360, window=filename_label) | ||
# adding the entry to the canvas | ||
first_canvas.create_window(300, 360, window=filename_entry) | ||
|
||
|
||
# creating the reset button in a disabled mode | ||
reset_button = ttk.Button(window, text='Reset', style='TButton', state=DISABLED) | ||
# creating the generate button | ||
generate_button = ttk.Button(window, text='Generate QRCode', style='TButton', command=generate_qrcode) | ||
|
||
# adding the reset button to the canvas | ||
first_canvas.create_window(300, 390, window=reset_button) | ||
# adding the generate button to the canvas | ||
first_canvas.create_window(410, 390, window=generate_button) | ||
|
||
|
||
"""Below are the widgets for the second tab""" | ||
|
||
# creating the second image label | ||
image_label2 = Label(window) | ||
# creating the data label | ||
data_label = ttk.Label(window) | ||
|
||
# adding the second image label to the second_canvas | ||
second_canvas.create_window(250, 150, window=image_label2) | ||
# adding the data label to the canvas | ||
second_canvas.create_window(250, 300, window=data_label) | ||
|
||
# creating the file_entry | ||
file_entry = ttk.Entry(window, width=60, style='TEntry') | ||
# creating the browse button | ||
browse_button = ttk.Button(window, text='Browse', style='TButton', command=open_dialog) | ||
|
||
# adding the entry to the canvas | ||
second_canvas.create_window(200, 350, window=file_entry) | ||
# adding the generate button to the canvas | ||
second_canvas.create_window(430, 350, window=browse_button) | ||
|
||
# creating the detect button | ||
detect_button = ttk.Button(window, text='Detect QRCode', style='TButton', command=detect_qrcode) | ||
# adding the detect button to the canvas | ||
second_canvas.create_window(65, 385, window=detect_button) | ||
|
||
|
||
# run the main window infinitely | ||
window.mainloop() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
python-opencv | ||
qrcode |