Take user input through tkinter, create barcode from that input - input

I want to take user input through tkinter gui. When the user confirms his entry by pressing a button, I want to create a barcode from that input.
The barcode will be saved as an image and it will be named after the user input, so for example "456789.png".
I have the gui working, but I have a problem with the barcode-creation-process.
When I confirm my entry, I get the error message:
"TypeError: StringVar object is not iterable".
Here is my code
from barcode import generate
from barcode.writer import ImageWriter
from tkinter import Tk, Entry, Label, Button
root = Tk()
root.geometry("640x640+0+0")
heading = Label(root, text="Barcode Creator", fg="steelblue", font=("arial", 16)).pack()
label1 = Label(root, text = "Enter Barcode: ", font=("arial", 16, "bold"), fg = "black").place(x=10, y = 200)
name = StringVar()
entry_box = Entry(root, textvariable = name, width=25, bg="lightgreen").place(x=280, y=210)
def create_code():
create = generate('code128', name, output = name, writer = ImageWriter())
create
work = Button(root, text = "Create Barcode", width = 30, height = 5,
bg = "lightblue", command = create_code).place(x=250, y=300)
root.mainloop()

the error is here
from tkinter import Tk, Entry, Label, Button
thet should be
from tkinter import Tk, Entry, Label, Button, StringVar
pay attention when you select your import

Related

Tkinter and pandas output into a label

I need some assistance, I have written an application that queries all records in a table and prints it out but when I run the program it prints it out in the IDE, and trying to get it to print in the lower label.
from __future__ import print_function
from ast import Lambda
import sqlalchemy as sa
import pandas as pd
import tkinter as tk
from tkinter import *
from PIL import ImageTk, Image
server = 'ABQSQ03t'
username = 'TECO//AAPWP'
password = '*****##'
timeout = '60'
database = 'NMGC_PIM_DEV'
driver = 'ODBC+Driver+17+for+SQL+Server'
engine = sa.create_engine(
f'mssql+pyodbc://{server}/{database}?username={username}?password={password}?timeout=
{timeout}&driver={driver}')
cn = engine.connect()
root = tk.Tk()
root.title("Compliance SQL Backend Reporting")
HEIGHT = 800
WIDTH = 1000
#background image
canv = tk.Canvas(root, width=80, height=80, bg='white')
canv.place(relwidth=1, relheight=1)
img = ImageTk.PhotoImage(Image.open("NMGC_Emera_color240x75.png")) # PIL solution
canv.create_image(20, 20, anchor='nw', image=img)
background_label= tk.Label(root, image=img)
background_label.place(x=0,y=0, relwidth=1, relheight=1)
#button Functionaility
#def test_function(entry):
#print("Button Clicked you typed:", entry)
def test_function(entry):
sql = pd.read_sql(f'Select * from [dbo].[{entry}]', con=cn)
df=pd.DataFrame(sql)
final_str = print(sql)
#Guid setup
canvas = tk.Canvas(root, height = HEIGHT, width=WIDTH)
canvas.pack()
frame = tk.Frame(root, bg='#7B94AD', bd=5)
frame.place(relx=0.5, rely=0.1, relwidth=0.75, relheight=0.1, anchor='n')
entry = tk.Entry(frame, bg='white')
entry.place(relwidth=0.65, relheight=1)
button = tk.Button(frame, text='Generate Report', font = 40, command=lambda:
test_function(entry.get()))
button.place(relx=0.7, relheight=1, relwidth=0.3)
lower_frame = tk.Frame(root, bg='#7B94AD', bd=10)
lower_frame.place(relx=0.5, rely=0.25, relwidth=0.75, relheight=0.6, anchor='n')
label=tk.Label(lower_frame, bg='white', textvariable=test_function)
label.place(relwidth=1, relheight=1)
root.mainloop()
Sample dataframe headers:
APPGROUPID APPTITLE DESCRIPTION ORGAREANAME CONGROUPNAME DISPLAYLEVELCOUNT CreatedDate CreatedBy ModifiedDate ModifiedBy

Tkinter: How can I check if any of the widgets of a specific frame have changed?

What is the best way to check if any widget (or variable linked to it) of a given frame(frm1) has changed and take an action. For example activate a button.
I would like that when something was typed in the entries or changed the combobox or checkbox, the 'changed_content' function would be executed
from tkinter import *
from tkinter import ttk
from tkinter.messagebox import showinfo
class Defaultframe(Tk):
def __init__(self):
Tk.__init__(self)
self.geometry('500x300')
self.title('Tkinter')
self.text1 = StringVar()
self.text2 = StringVar()
self.text3 = StringVar()
self.var1 = IntVar()
self.var2 = IntVar()
self.set_widgets()
return
def changed_content(self):
showinfo('Information', 'The content has been changed')
self.btn2.configure(state='normal')
return
def set_widgets(self):
#Frame1
self.frm1 = ttk.Frame(self).pack(side=TOP)
self.lbl = ttk.Label(self.frm1, text='Text1').pack(pady=5)
self.ent1 = ttk.Entry(self.frm1, textvariable=self.text1).pack(pady=5)
self.lbl = ttk.Label(self.frm1, text='Text2').pack(pady=5)
self.my_ent = ttk.Entry(self.frm1, textvariable=self.text2).pack(pady=5)
self.cbb = ttk.Combobox(self.frm1,
values=[0, 30, 60, 90, 120, 150, 180],
state='readonly',
textvariable=self.var2)
self.cbb.pack(pady=5)
self.cbb.current(3)
self.ckb = ttk.Checkbutton(self.frm1, text='Hello', variable=self.var1, onvalue=1, offvalue=0).pack(pady=5)
#---
#Frame2
self.frm2 = ttk.Frame(self).pack(side=BOTTOM, fill=X)
ttk.Separator(self.frm2, orient=HORIZONTAL).pack(side=TOP, expand=1, fill=X)
self.my_ent3 = ttk.Entry(self.frm2, textvariable=self.text3).pack(side=LEFT, padx=1)
self.btn1 = ttk.Button(self.frm2, text='Cancel').pack(side=RIGHT, padx=1)
self.btn2 = ttk.Button(self.frm2, text='Save')
self.btn2.pack(side=RIGHT, padx=1)
self.btn2.configure(state=DISABLED)
#---
if __name__== '__main__':
app = Defaultframe()
app.mainloop()
Solving for any widget is tough - you'll have to write code specifically for a canvas or a scrollbar or any other widget that isn't associated with a tkinter variable.
For widgets that are associated with a tkinter variable you can apply a trace that will call a function whenever the value changes.
In your code it might look something like this:
class Defaultframe(Tk):
def __init__(self):
...
self._watch_variables(self.text1, self.text2, self.text3, self.var1, self.var2)
def _watch_variables(self, *vars):
for var in vars:
var.trace_add("write", self._handle_trace)
def _handle_trace(self, *args):
self.changed_content()

Own drag icon with same color and font settings as the default drag icon in a Gtk.TreeView

The Gtk.TreeView implements a default drag icon. It use the background color of the TreeView, it's font and the complete row-content as string.
I want the same (background-color, font-face, font-size, font-color) but with a shorter string (only the second of three columns).
In the example below create my own cairo.Surface to create such an icon. But color and font is a problem. I don't know how to set them up or (much more important) to ask the TreeView or Gtk itself for the current color and font values.
How does the TreeView get this values?
#!/usr/bin/env python3
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk
from gi.repository import Gdk
import cairo
class MainWindow(Gtk.Window):
def __init__(self):
Gtk.Window.__init__(self, title="TreeView Drag and Drop")
self.connect("delete-event", Gtk.main_quit)
self.box = Gtk.Box()
self.add(self.box)
# "model" with dummy data
self.store = Gtk.TreeStore(int, str, int)
for i in range(5):
self.store.append(None, [i, 'Item {}'.format(i), i]) # treeview
self.tree = Gtk.TreeView(model=self.store)
self.box.pack_start(self.tree, True, True, 0)
# build columns
colA = Gtk.TreeViewColumn('Col A', Gtk.CellRendererText(), text=0)
self.tree.append_column(colA)
colB = Gtk.TreeViewColumn('Col B', Gtk.CellRendererText(), text=1)
self.tree.append_column(colB)
colC = Gtk.TreeViewColumn('Col C', Gtk.CellRendererText(), text=2)
self.tree.append_column(colC)
# enable default drag and drop
self.tree.set_reorderable(True)
# DnD events
self.tree.connect_after("drag-begin", self.drag_begin)
def drag_begin(self, widget, context):
model, path = widget.get_selection().get_selected_rows()
text = model[path][1]
# dummy surface/context
surface = cairo.ImageSurface(cairo.Format.RGB24, 0, 0)
cr = cairo.Context(surface)
# calculate text size
txtext = cr.text_extents(text)
width = int(txtext.width)
height = int(txtext.height)
offset = 10
# creal surface/context
surface = cairo.ImageSurface(cairo.Format.RGB24,
width + (offset*2),
height + (offset*2))
cr = cairo.Context(surface)
cr.set_source_rgb(1, 1, 1) # text color: white
cr.move_to(0+offset, height+offset)
cr.show_text(text)
# use the surface as drag icon
Gtk.drag_set_icon_surface(context, surface)
win = MainWindow()
win.show_all()
Gtk.main()
What I tried (but not worked) was cairo.Surface.create_similar()',cairo.Surface.create_similar_image()andGtk.TreeView.create_row_drag_icon()`.
This answer is based on a foreign mailing list posting.
The widget has a Gtk.StyleContext. A Pango.Layout is used to render the text based on the style informations in the Gtk.StyleContext.
def drag_begin(self, widget, context):
model, path = widget.get_selection().get_selected_rows()
text = model[path][1]
stylecontext = widget.get_style_context()
# new pango layout
pl = widget.create_pango_layout(text)
ink_rec, log_rect = pl.get_pixel_extents()
padding = 5
# create surface/context
surface = cairo.ImageSurface(cairo.Format.RGB24,
log_rect.width + (padding*2),
log_rect.height + (padding*2))
cr = cairo.Context(surface)
Gtk.render_background(stylecontext, cr, 0, 0,
log_rect.width + (padding*2),
log_rect.height + (padding*2))
Gtk.render_layout(stylecontext, cr, padding, padding, pl)
# border
line_width = cr.get_line_width()
cr.rectangle(-1+line_width, -1+line_width,
log_rect.width+(padding*2)-line_width,
log_rect.height+(padding*2)-line_width)
cr.stroke()
# use the surface as drag icon
Gtk.drag_set_icon_surface(context, surface)

How do I store an integer input from the user into a variable in Tkinter?

For my Python class were using turtle graphics.
We have too draw a target that appears at a random location on the screen. Got that.
Then a pop up window appears asking for what you think the coordinates of the target are. First the pop up box asks you to enter the x coordinate then it asks you to enter the y coordinate.
I'm having trouble saving the users inputed integers from my Tkinter window into variables I can use later in the program.
from Tkinter import *
window = Tk()
window.title("Player Input")
window.geometry('+350+130')
thexinput = IntVar()
L1 = Label(window, text="Enter the x coordinate for Mike")
L1.pack( side = LEFT)
E1= Entry(window, textvariable= thexinput, bd =5)
E1.pack(side = RIGHT)
def userinput():
global inp
a = raw_input(thexinput.get())
inp = a
b = Button(window, text = 'Submit', command = userinput)
b.pack(side = BOTTOM)
window.mainloop()
You don't need to use raw_input, you just need to call the get method of the entry widget.
a = thexinput.get()

Access windows for notebook in Tkinter

I have been trying to create an open windows which asks you for username and password before opening a notebook in Tkinter, I have both, but I don't know how to put them together. In other words, what I want is to open a notebook once the username and password requested are correct.
Thank you very much in advance!
What I have done so far is as follows:
import Tkinter
from Tkinter import *
import ttk
from ttk import * #Combobox Definition
import tkMessageBox #for Welcome Message
import Tkinter as tk # For Main Frame Definition
from Tkinter import Tk, Text, BOTH, W, N, E, S
from ttk import Frame, Button, Label, Style
root = Tk()
root.title("Model A")
root.minsize(400, 220)
root.maxsize(410, 240)
# start of Notebook (multiple tabs)
notebook = ttk.Notebook(root)
notebook.pack(fill='both', expand='yes')
notebook.pressed_index = None
# create a child frame for each page
frameOne = Tkinter.Frame(notebook, bg='white',width=560, height=100)
frameOne.pack(fill='both', expand=True)
# create the pages
notebook.add(frameOne, text='Simple calculation')
#Login Starts
failure_max = 8
passwords = [('name','password')]
def make_entry(parent, caption, width=None, **options):
tk.Label(parent, text=caption).pack(side=tk.TOP)
entry = tk.Entry(parent, **options)
if width:
entry.config(width=width)
entry.pack(side=tk.TOP, padx=10, fill=tk.BOTH)
return entry
def enter(event):
check_password()
def check_password(failures=[]):
if (user.get(), password.get()) in passwords:
root.destroy()
return
failures.append(1)
if sum(failures) >= failure_max:
root.destroy()
raise SystemExit('Unauthorized login attempt')
else:
root.title('Try again. Attempt %i/%i' % (sum(failures)+1, failure_max))
parent = Tkinter.Frame(notebook, padx=10, pady=18, bg='white')
parent.pack(fill=tk.BOTH, expand=True)
user = make_entry(parent, "User name:", 16, show='')
password = make_entry(parent, "Password:", 16, show="*")
b = tk.Button(parent,borderwidth=4,text="Login",width=10,pady=8,command=check_password)
b.pack(side=Tkinter.BOTTOM)
password.bind('<Return>', enter)
#Close Application Button
def quit(root):
root.destroy()
tk.Button(root, text="Close Application", command=lambda root=root:quit(root)).pack()
#Calculation Starts
def defocus(event):
event.widget.master.focus_set()
def multiply(*args):
try:
product.set(round(float(Num_One.get())*float(Num_Two.get())))
except ValueError:
pass
Num_One = StringVar()
Num_Two = StringVar()
product = DoubleVar()
ttk.Label(frameOne, text="Select First Number:").grid(column =3, row = 0)
NumOne_Select = Combobox(frameOne, values=("1", "2", "3","4", "5"),textvariable=Num_One)
NumOne_Select.grid(column=4, row=0, columnspan="5", sticky="nswe")
Num_One.trace("w", multiply)
ttk.Label(frameOne, text="Select Second Number:").grid(column =3, row = 6 )
NumTwo_Select = Combobox(frameOne, values=("1", "2", "3","4", "5"),textvariable=Num_Two)
NumTwo_Select.grid(column=4, row=6, columnspan="5", sticky="nswe")
Num_Two.trace("w", multiply)
ttk.Label(frameOne, text = "Product:").grid(column = 3, row = 8)
ttk.Label(frameOne, textvariable=product).grid(column = 4, row = 8)
user.focus_set()
parent.mainloop()
root.mainloop()
You have several things going wrong in your code:
you're calling mainloop twice; you should only ever call it once.
you shouldn't pack or grid widgets inside the notebook. You are packing a widget and then using notebook.add; omit the pack.
you are calling destroy on the root window if the password is good. This causes your application to exit. Don't call destroy.
Normally the way this is done is that the notebook is a child of the root window, and the username/password dialog is an instance of Toplevel. You can hide the root window and pop up the dialog, and then if the user logs in, you can destroy the dialog and un-hide the main window.