Page 1 of 1
tkinter numpad on entry click
Posted: Mon Apr 11, 2016 1:30 am
by Davies
is it possible to have an entry in a main tkinter window
Code: Select all
import Tkinter as tk
from Tkinter import *
root = tk.Tk()
root.geometry("200x100")
e = Entry(root, width=10, background='white', textvariable=file, justify=CENTER, font='-weight bold')
e.grid(padx=10, pady=5, row=17, column=1, sticky='W,E,N,S')
root.mainloop()
then have a numpad appear when the entry is clicked on?
Code: Select all
try:
# Python2
import Tkinter as tk
except ImportError:
# Python3
import tkinter as tk
# needs Python25 or higher
from functools import partial
def click(btn):
# test the button command click
s = "Button %s clicked" % btn
boot.title(s)
boot = tk.Tk()
boot['bg'] = 'green'
# create a labeled frame for the keypad buttons
# relief='groove' and labelanchor='nw' are default
lf = tk.LabelFrame(boot, text=" keypad ", bd=3)
lf.pack(padx=15, pady=10)
# typical calculator button layout
btn_list = [
'7', '8', '9',
'4', '5', '6',
'1', '2', '3',
'0', 'Close', 'Del']
# create and position all buttons with a for-loop
# r, c used for row, column grid values
r = 1
c = 0
n = 0
# list(range()) needed for Python3
btn = list(range(len(btn_list)))
for label in btn_list:
# partial takes care of function and argument
cmd = partial(click, label)
# create the button
btn[n] = tk.Button(lf, text=label, width=10, height=5, command=cmd)
# position the button
btn[n].grid(row=r, column=c)
# increment button index
n += 1
# update row/column position
c += 1
if c == 3:
c = 0
r += 1
boot.mainloop()
Re: tkinter numpad on entry click
Posted: Mon Apr 11, 2016 8:57 am
by paddyg
You can bind events to tk widgets. So you would
e.bind('<Button-1>', numpad_show)
where numpad_show() is a function that shows or hides the numpad (probably best to make this an instance of a new dialogue window
http://effbot.org/tkinterbook/tkinter-d ... indows.htm)
Re: tkinter numpad on entry click
Posted: Mon Apr 11, 2016 11:08 am
by scotty101
How does this work for you?
There are a few bugs and hacks but it seems to do the job.
Code: Select all
from tkinter import *
from tkinter import simpledialog
class App(Frame):
def __init__(self,parent=None,**kw):
Frame.__init__(self,parent,**kw)
self.textEntryVar = StringVar()
self.e = Entry(self, width=10, background='white', textvariable=self.textEntryVar, justify=CENTER, font='-weight bold')
self.e.grid(padx=10, pady=5, row=17, column=1, sticky='W,E,N,S')
self.e.bind('<FocusIn>',self.numpadEntry)
self.e.bind('<FocusOut>',self.numpadExit)
self.edited = False
def numpadEntry(self,event):
if self.edited == False:
print("You Clicked on me")
self.e['bg']= '#ffffcc'
self.edited = True
new = numPad(self,self)
else:
self.edited = False
def numpadExit(self,event):
self.e['bg']= '#ffffff'
class numPad(simpledialog.Dialog):
def __init__(self,master=None,parent=None):
self.parent = parent
self.top = Toplevel(master=master)
self.top.protocol("WM_DELETE_WINDOW",self.ok)
self.createWidgets()
def createWidgets(self):
btn_list = ['7', '8', '9', '4', '5', '6', '1', '2', '3', '0', 'Close', 'Del']
# create and position all buttons with a for-loop
# r, c used for row, column grid values
r = 1
c = 0
n = 0
# list(range()) needed for Python3
btn = []
for label in btn_list:
# partial takes care of function and argument
cmd = lambda x = label: self.click(x)
# create the button
cur = Button(self.top, text=label, width=10, height=5, command=cmd)
btn.append(cur)
# position the button
btn[-1].grid(row=r, column=c)
# increment button index
n += 1
# update row/column position
c += 1
if c == 3:
c = 0
r += 1
def click(self,label):
print(label)
if label == 'Del':
currentText = self.parent.textEntryVar.get()
self.parent.textEntryVar.set(currentText[:-1])
elif label == 'Close':
self.ok()
else:
currentText = self.parent.textEntryVar.get()
self.parent.textEntryVar.set(currentText+label)
def ok(self):
self.top.destroy()
self.top.master.focus()
if __name__ == '__main__':
root = Tk()
root.geometry("200x100")
app = App(root)
app.grid()
root.mainloop()
Re: tkinter numpad on entry click
Posted: Mon Apr 11, 2016 11:44 am
by paddyg
@scotty101, excellent. @Davies - to get the python2 and 3 system you would need a line like
import tkSimpleDialog as simpledialog
in your try block (I only have tk for python2 on this laptop!)
Re: tkinter numpad on entry click
Posted: Mon Apr 11, 2016 1:32 pm
by Davies
Thank you very much for this,
ive been able to produce some code that will display the numpad on entry click, then a click anywhere on root will destroy the numpad
Code: Select all
import Tkinter as tk
from Tkinter import *
from functools import partial
root = tk.Tk()
root.geometry("200x100")
num_run = 0
btn_funcid = 0
def click(btn):
global num_run
text = "%s" % btn
if not text == "Del" and not text == "Close":
e.insert(END, text)
if text == 'Del':
e.delete(0, END)
if text == 'Close':
boot.destroy()
num_run = 0
root.unbind('<Button-1>', btn_funcid)
def numpad():
global num_run, boot
boot = tk.Tk()
boot['bg'] = 'green'
lf = tk.LabelFrame(boot, text=" keypad ", bd=3)
lf.pack(padx=15, pady=10)
btn_list = [
'7', '8', '9',
'4', '5', '6',
'1', '2', '3',
'0', 'Del', 'Close']
r = 1
c = 0
n = 0
btn = list(range(len(btn_list)))
for label in btn_list:
cmd = partial(click, label)
btn[n] = tk.Button(lf, text=label, width=10, height=5, command=cmd)
btn[n].grid(row=r, column=c)
n += 1
c += 1
if c == 3:
c = 0
r += 1
def close(event):
global num_run, btn_funcid
if num_run == 1:
boot.destroy()
num_run = 0
root.unbind('<Button-1>', btn_funcid)
def run(event):
global num_run, btn_funcid
if num_run == 0:
num_run = 1
numpad()
btn_funcid = root.bind('<Button-1>', close)
e = Entry(root, width=10, background='white', textvariable=file, justify=CENTER, font='-weight bold')
e.bind('<Button-1>', run)
e.grid(padx=10, pady=5, row=17, column=1, sticky='W,E,N,S')
root.mainloop()
Re: tkinter numpad on entry click
Posted: Mon Apr 11, 2016 1:34 pm
by Davies
thank you very much scotty, seems you answered the question as i was testing some different way arounds.
thanks for the code, seems a lot more advanced than mine
Re: tkinter numpad on entry click
Posted: Mon Apr 11, 2016 1:37 pm
by scotty101
Great but consider my object oriented version.
Might be a bit more expansible in larger applications where you have more than one entry box.
Re: tkinter numpad on entry click
Posted: Mon Apr 11, 2016 1:55 pm
by Davies
cheers scotty, will do.
i need to put more time into learning class and object orientated programming, i can understand it to some degree and most of my code is written by converting orientated code from examples but i struggle to write orientated from scratch and struggle to compile multiple class's .
this code is been added to a 1200 line .py script which was the first python program i created and does not use orientated programming(but works as intended), which is why its wrote in such a manner but future projects i will be exploring orientated programming.
i have found a few very basic tutorials on class that dont seem to explain much, if anyone knows of good tutorials please share.
does anybody know if root.bind('<Button-1>', close) will still be called on the tap of a touchscreen? i dont currently have one set up but intend on using one.
Re: tkinter numpad on entry click
Posted: Mon Apr 11, 2016 2:17 pm
by scotty101
Looks like you had the same problem as me.
I found that when closing the keypad, it would re-enter the entry box and then open the keypad back up again. I'm not sure what the non-hack fix for this is but my way seemed to work.
Re: tkinter numpad on entry click
Posted: Mon Apr 11, 2016 2:27 pm
by Davies
my current code seems to work as intended when tested in pycharm, not tried on raspberry.
i had it working ok for just clicking the entry but had some issues having it open the keypad when i wanted to click anywhere on root to close it, but was able to overcome that by disabling the code for that call when numpad isnt displayed. it was opening and closing on just one click.
what do you consider a hack within code?
Re: tkinter numpad on entry click
Posted: Mon Apr 11, 2016 2:42 pm
by Davies
is it possible to designate screen coordinates for the numpad?
Re: tkinter numpad on entry click
Posted: Mon Apr 11, 2016 3:16 pm
by scotty101
Re: tkinter numpad on entry click
Posted: Mon Apr 11, 2016 3:18 pm
by scotty101
Davies wrote:
what do you consider a hack within code?
I was unsure about the line of code where you unbind the event. I couldn't see where you rebind the event again to allow you to click on the entry again to change the value.
Re: tkinter numpad on entry click
Posted: Sun Oct 22, 2017 1:03 pm
by Dhanumjay18
Hello @scotty101. I am trying to develop an application in tkinter which has multiple entry boxes. I am trying to create a numpad of my own which will popup on selecting specific entry box. Can you help me how to populate numbers in selected entry box? Thanks in advance
Re: tkinter numpad on entry click
Posted: Mon Oct 23, 2017 8:31 am
by scotty101
Dhanumjay18 wrote: ↑Sun Oct 22, 2017 1:03 pm
Hello @scotty101. I am trying to develop an application in tkinter which has multiple entry boxes. I am trying to create a numpad of my own which will popup on selecting specific entry box. Can you help me how to populate numbers in selected entry box? Thanks in advance
The
post I made above gives a decent example of how to make a numpad pop up when you focus on an entry widget and how to populate it with numbers. Give it a try.
If it doesn't do what you want, then you'll need to be more specific about why.
Re: tkinter numpad on entry click
Posted: Sat Jun 23, 2018 1:42 am
by Genex36
@scotty101
Hey. I checked out your code about the numPad and it is amazing, but i have some problem implenting it in my code, i have a class based tkinter menu.
my problems are:
1) i can't implent it with the rest of the program because i can't reach the label inside the class.
2) i wanted to make this system available for more than 1 entry, so i can't just say "e" but i have to pass at least the labelID
i'm not an expert and i'm still learning if you need my code i can upload it but it's not that short
Re: tkinter numpad on entry click
Posted: Sat Jun 23, 2018 10:51 pm
by rickyh89
I'm decent with tkinter, what you exactly need to do? I use class oriented code for all my tkinter stuff.
Re: tkinter numpad on entry click
Posted: Sun Jun 24, 2018 12:54 am
by rickyh89
so what i think you want to do off reading this...
create a .py file called NumPad.py or whatever name. the purpose of this is to have a generic script that will create the popup keypad. you can then use this with however many entry fields you want. inside this script you can set the entry fields as variables which will be imported from the main file. if you make your entry or labels inside the main file global than you can import those global variables into the NumPad.py file. that numpad can then interact with the labels and entries you want.
this is a quick example to show using variables and entries from another file. You could use this same way with a NumPad file. set the numbers to the labels in your case or inside you entries.
Code: Select all
### online.py
import Tkinter as tk
from Tkinter import *
import online2
class Page_one(tk.Tk):
def __init__(self):
tk.Tk.__init__(self)
self.labels_one()
self.buttons_one()
self.entries_one()
def labels_one(self):
global lab_var
lab_var = StringVar()
label1 = Label(self, text="Welcome to page one")
label1.grid()
label2 = Label(self, textvariable = lab_var)
label2.grid()
def buttons_one(self):
text_one_button = Button(self, text="print entered text", command=lambda:online2.get_text(entry_one_var,lab_var))
text_one_button.grid()
def entries_one(self):
# must be global so var used outside this class in other functions on another file.
global entry_one_var
entry_one_var=StringVar()
entry_one = Entry(self, textvariable= entry_one_var)
entry_one.grid()
if __name__ == "__main__":
app = Page_one()
app.geometry("200x100")
app.mainloop()
Code: Select all
### online2.py
from Tkinter import *
import Tkinter as tk
import __main__ as M
def get_text(e_var,lab_var):
A = e_var.get()
B = lab_var
print A
B.set(A)
again i am not 100% what your asking cause this thread went back and forth few times with different code. maybe put up your code you have an what you want to do with that code and i can help make it work rather than re-write it... although from what i seen above i think i wouldve went about the binding and few other things different but if it works than doesnt matter.
Re: tkinter numpad on entry click
Posted: Sun Jun 24, 2018 3:20 am
by Paeryn
rickyh89 wrote: ↑Sun Jun 24, 2018 12:54 am
Code: Select all
### online2.py
from Tkinter import *
import Tkinter as tk
import __main__ as M
def get_text(e_var,lab_var):
A=StringVar()
B=StringVar()
A = e_var.get()
B = lab_var
print A
B.set(A)
This is bad code, what is the purpose of the first two lines of
get_text()? They create two
StringVar objects which are immediately thrown away when you reassign
A and
B in the next two lines,
A isn't even a
StringVar in the rest of the function, it's a plain string.
Re: tkinter numpad on entry click
Posted: Sun Jun 24, 2018 3:30 am
by rickyh89
Your right about the stringvar, this I took from a project from awhile ago. Didn't bother looking it over. Either way though it still shows how he can use another file to communicate with his main file. Much better to organize everything. His 1200 line code without classes would be easier for him to work with if he had an example of dividing his code up into modules. So wouldn't exactly say entire thing is bad code, it's a pretty straight forward example to use going forward. Other than the error I overlooked of course... which I'll edit now for when it's seen
Re: tkinter numpad on entry click
Posted: Tue Jun 26, 2018 2:43 am
by Genex36
ok, I'm checking it out, by the way, I have a problem with string var, for some reason they aren't showing up at all... I've tried in a different code without matplotlib and it's actually working, but when I put it on my script with matplot.. looks like it all messed up, maybe I can make a Post and post my script with details for asking your help.
Thank you very much!
re-post: i've made the post here ->
viewtopic.php?f=32&t=216750&p=1332986#p1332986