I was trying to create a QRcode generating app in python with tkinter that you enter color and then text and it generates a QRcode but it closes instantly upon startup. (the problem did not happen when I didn't have the color part), (in the future I'm also planning to add a save QR as png button) here's what I have:
from tkinter import *
from tkinter import messagebox
import pyqrcode
from tkinter import colorchooser
import re
def choose_color():
x = 0
# variable to store hexadecimal code of color
color_code = colorchooser.askcolor(title ="Choose color")
print(color_code)
x = 1
root = Tk()
button = Button(root, text = "Select color",
command = choose_color)
button.pack()
if 'x' == 1:
str = 'color_code' # Your Hex
match = re.search(r'^#(?:[0-9a-fA-F]{3}){1,2}$', str)
if match:
print('Hex is valid')
ws = Tk()
ws.title("PythonGuides")
ws.config(bg='color_code')
def generate_QR():
if len(user_input.get())!=0 :
global qr,img
qr = pyqrcode.create(user_input.get())
img = BitmapImage(data = qr.xbm(scale=8))
else:
messagebox.showwarning('warning', 'All Fields are Required!')
try:
display_code()
except:
pass
def display_code():
img_lbl.config(image = img)
output.config(text="QR code of " + user_input.get())
lbl = Label(
ws,
text="Enter message or URL",
bg='color_code'
)
lbl.pack()
user_input = StringVar()
entry = Entry(
ws,
textvariable = user_input
)
entry.pack(padx=10)
button = Button(
ws,
text = "generate_QR",
width=15,
command = generate_QR
)
button.pack(pady=10)
img_lbl = Label(
ws,
bg='color_code')
img_lbl.pack()
output = Label(
ws,
text="",
bg='color_code'
)
output.pack()
ws.mainloop()
else:
print('Hex is not valid')
The reason the program closes immediately is because there is no root.mainloop()
. Even if there was, there are a lot of other errors that would prevent the program from working.
The first problem is if 'x' == 1
. Here you are comparing the literal string "x" to the number 1. These are never going to be equal, so the other window will never show up. I can see what you are trying to do with x
, but it won't work as you expect. It is better just to get rid of x
completely and call a function after the user selects a colour. I've called this function show_qr_window
.
The second problem is how you get the hex code. You use the output of colorchooser.askcolor
, which is a tuple containing an rgb tuple representing the colour and it's hex value. You only want the hex value, so you want color_code[1]
, as the hex value is the second item. I've also added an if
statement to make sure color_code
is not None. color_code
will be None if the user does not choose a colour and just closes the window. If the user has chosen a colour, it is passed to show_qr_window
. Because we've checked the user has chosen a colour, you can get rid of all of the other validation as colorchooser
will always return a valid hex value. You also no longer have to import re
.
The third issue is that you've used Tk
twice. This will cause your program to not work properly. Instead, change ws = Tk()
to ws = Toplevel()
.
The next issue is str = 'color_code'
. This is not how you define a variable. You want to do color_code = 'a string'
. In this case, the string is passed to show_qr_window
as the variable color
, so you can use color_code = color
. You also have to change all of the bg = 'color_code'
to bg = color_code
, as color_code
is a variable, not a string.
The rest of your code seems to work (I haven't tested the qr code generation as I don't have that module installed). Here is the code with all of the fixes:
from tkinter import *
from tkinter import messagebox
import pyqrcode
from tkinter import colorchooser
def choose_color():
# variable to store hexadecimal code of color
color_code = colorchooser.askcolor(title ="Choose color")
if color_code != None:
show_qr_window(color_code[1])
root = Tk()
button = Button(root, text = "Select color",
command = choose_color)
button.pack()
root.mainloop()
def show_qr_window(color):
ws = Toplevel()
color_code = color
ws.config(bg = color_code)
def generate_QR():
if len(user_input.get())!=0 :
global qr,img
qr = pyqrcode.create(user_input.get())
img = BitmapImage(data = qr.xbm(scale=8))
else:
messagebox.showwarning('warning', 'All Fields are Required!')
try:
display_code()
except:
pass
def display_code():
global img
img_lbl.config(image = img)
output.config(text="QR code of " + user_input.get())
lbl = Label(
ws,
text="Enter message or URL",
bg=color_code
)
lbl.pack()
user_input = StringVar()
entry = Entry(
ws,
textvariable = user_input
)
entry.pack(padx=10)
button = Button(
ws,
text = "generate_QR",
width=15,
command = generate_QR
)
button.pack(pady=10)
img_lbl = Label(
ws,
bg=color_code)
img_lbl.pack()
output = Label(
ws,
text="",
bg=color_code
)
output.pack()
ws.mainloop()
Assuming generate_QR()
and display_code()
work as they should (I haven't tested them but they look fine), this code will run as expected.