Davies
Posts: 150
Joined: Sat Apr 04, 2015 4:24 pm

tkinter numpad on entry click

Mon Apr 11, 2016 1:30 am

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()

User avatar
paddyg
Posts: 2126
Joined: Sat Jan 28, 2012 11:57 am
Location: UK

Re: tkinter numpad on entry click

Mon Apr 11, 2016 8:57 am

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)
also https://groups.google.com/forum/?hl=en-GB&fromgroups=#!forum/pi3d

scotty101
Posts: 2912
Joined: Fri Jun 08, 2012 6:03 pm

Re: tkinter numpad on entry click

Mon Apr 11, 2016 11:08 am

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()
Electronic and Computer Engineer
Pi Interests: Home Automation, IOT, Python and Tkinter

User avatar
paddyg
Posts: 2126
Joined: Sat Jan 28, 2012 11:57 am
Location: UK

Re: tkinter numpad on entry click

Mon Apr 11, 2016 11:44 am

@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!)
also https://groups.google.com/forum/?hl=en-GB&fromgroups=#!forum/pi3d

Davies
Posts: 150
Joined: Sat Apr 04, 2015 4:24 pm

Re: tkinter numpad on entry click

Mon Apr 11, 2016 1:32 pm

Thank you very much for this,
paddyg wrote: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)
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()
Last edited by Davies on Tue Apr 12, 2016 11:19 am, edited 1 time in total.

Davies
Posts: 150
Joined: Sat Apr 04, 2015 4:24 pm

Re: tkinter numpad on entry click

Mon Apr 11, 2016 1:34 pm

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

scotty101
Posts: 2912
Joined: Fri Jun 08, 2012 6:03 pm

Re: tkinter numpad on entry click

Mon Apr 11, 2016 1:37 pm

Great but consider my object oriented version.
Might be a bit more expansible in larger applications where you have more than one entry box.
Electronic and Computer Engineer
Pi Interests: Home Automation, IOT, Python and Tkinter

Davies
Posts: 150
Joined: Sat Apr 04, 2015 4:24 pm

Re: tkinter numpad on entry click

Mon Apr 11, 2016 1:55 pm

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.

scotty101
Posts: 2912
Joined: Fri Jun 08, 2012 6:03 pm

Re: tkinter numpad on entry click

Mon Apr 11, 2016 2:17 pm

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.
Electronic and Computer Engineer
Pi Interests: Home Automation, IOT, Python and Tkinter

Davies
Posts: 150
Joined: Sat Apr 04, 2015 4:24 pm

Re: tkinter numpad on entry click

Mon Apr 11, 2016 2:27 pm

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?

Davies
Posts: 150
Joined: Sat Apr 04, 2015 4:24 pm

Re: tkinter numpad on entry click

Mon Apr 11, 2016 2:42 pm

is it possible to designate screen coordinates for the numpad?

scotty101
Posts: 2912
Joined: Fri Jun 08, 2012 6:03 pm

Re: tkinter numpad on entry click

Mon Apr 11, 2016 3:16 pm

Yep. You can specify the coordinates.

http://stackoverflow.com/questions/1491 ... ndow-opens
Electronic and Computer Engineer
Pi Interests: Home Automation, IOT, Python and Tkinter

scotty101
Posts: 2912
Joined: Fri Jun 08, 2012 6:03 pm

Re: tkinter numpad on entry click

Mon Apr 11, 2016 3:18 pm

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.
Electronic and Computer Engineer
Pi Interests: Home Automation, IOT, Python and Tkinter

Dhanumjay18
Posts: 1
Joined: Sun Oct 22, 2017 12:52 pm

Re: tkinter numpad on entry click

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

scotty101
Posts: 2912
Joined: Fri Jun 08, 2012 6:03 pm

Re: tkinter numpad on entry click

Mon Oct 23, 2017 8:31 am

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.
Electronic and Computer Engineer
Pi Interests: Home Automation, IOT, Python and Tkinter

Genex36
Posts: 8
Joined: Sat Jun 23, 2018 1:18 am

Re: tkinter numpad on entry click

Sat Jun 23, 2018 1:42 am

@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

rickyh89
Posts: 28
Joined: Mon Jun 18, 2018 11:01 pm

Re: tkinter numpad on entry click

Sat Jun 23, 2018 10:51 pm

I'm decent with tkinter, what you exactly need to do? I use class oriented code for all my tkinter stuff.

rickyh89
Posts: 28
Joined: Mon Jun 18, 2018 11:01 pm

Re: tkinter numpad on entry click

Sun Jun 24, 2018 12:54 am

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.
Last edited by rickyh89 on Sun Jun 24, 2018 3:31 am, edited 1 time in total.

User avatar
Paeryn
Posts: 2021
Joined: Wed Nov 23, 2011 1:10 am
Location: Sheffield, England

Re: tkinter numpad on entry click

Sun Jun 24, 2018 3:20 am

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.
She who travels light — forgot something.

rickyh89
Posts: 28
Joined: Mon Jun 18, 2018 11:01 pm

Re: tkinter numpad on entry click

Sun Jun 24, 2018 3:30 am

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

Genex36
Posts: 8
Joined: Sat Jun 23, 2018 1:18 am

Re: tkinter numpad on entry click

Tue Jun 26, 2018 2:43 am

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

Return to “Python”

Who is online

Users browsing this forum: No registered users and 5 guests