I'm using tkinter to create my first GUI and i have reached a problem. How do I expand the 'enter' button of the numpad (which opens when you click a empty box) to cover the empty space currently there?
How do I designate the opening position of the numpad?
Additionally if anyone has a shorter/faster way to code this i would be interested as to how it can be done as whilst speed isn't extremely necessary for my project, it is always nice to have.
The code is as follows below:
import tkinter
from tkinter import *
from tkinter import simpledialog
def enumerate_row_column(iterable, num_cols):
for idx, item in enumerate(iterable):
row = idx // num_cols
col = idx % num_cols
yield row,col,item
class NumpadEntry(Entry):
def __init__(self,parent=None,**kw):
Entry.__init__(self,parent,**kw)
self.bind('<FocusIn>',self.numpadEntry)
self.bind('<FocusOut>',self.numpadExit)
self.edited = False
def numpadEntry(self,event):
if self.edited == False:
print("You Clicked on me")
self['bg']= '#ffffcc'
self.edited = True
new = numPad(self)
else:
self.edited = False
def numpadExit(self,event):
self['bg']= '#ffffff'
class numPad(simpledialog.Dialog):
def __init__(self,master=None,textVariable=None):
self.top = Toplevel(master=master)
self.top.protocol("WM_DELETE_WINDOW",self.ok)
self.createWidgets()
self.master = master
def createWidgets(self):
btn_list = ['1', '2', '3', '4', '5', '6', '7', '8', '0', '0', '.', 'Del', 'Enter']
# create and position all buttons with a for-loop
btn = []
# Use custom generator to give us row/column positions
for r,c,label in enumerate_row_column(btn_list,3):
# partial takes care of function and argument
cmd = lambda x = label: self.click(x)
# create the button
cur = Button(self.top, text=label, width=5, height=3, command=cmd)
# position the button
cur.grid(row=r, column=c)
btn.append(cur)
def click(self,label):
print(label)
if label == 'Del':
currentText = self.master.get()
self.master.delete(0, END)
self.master.insert(0, currentText[:-1])
elif label == 'Enter':
self.ok()
else:
currentText = self.master.get()
self.master.delete(0, END)
self.master.insert(0, currentText label)
def ok(self):
self.top.destroy()
self.top.master.focus()
class App(Frame):
def __init__(self,parent=None,**kw):
Frame.__init__(self,parent,**kw)
self.textEntryVar1 = StringVar()
self.e1 = NumpadEntry(self,textvariable=self.textEntryVar1)
self.e1.grid()
self.textEntryVar2 = StringVar()
self.e2 = NumpadEntry(self,textvariable=self.textEntryVar2)
self.e2.grid()
if __name__ == '__main__':
root = Tk()
root.geometry("550x300")
root.title("Monitoring Site GUI")
app = App(root)
app.grid()
root.mainloop()
CodePudding user response:
As you get in comment: you need to use columnspan
to use space in many columns, and sticky
(west-east) to resize button in this space.
cur.grid(row=4, column=0, columnspan=3, sticky='we')
def createWidgets(self):
# create and position all buttons
btn = []
# --- without ENTER ---
btn_list = [
'1', '2', '3',
'4', '5', '6',
'7', '8', '0',
'0', '.', 'Del'
]
# Use custom generator to give us row/column positions
for r,c,label in enumerate_row_column(btn_list, 3):
# partial takes care of function and argument
cmd = lambda x = label: self.click(x)
# create the button
cur = Button(self.top, text=label, width=5, height=3, command=cmd)
# position the button
cur.grid(row=r, column=c)
btn.append(cur)
cur.grid(row=r, column=c)
# --- only ENTER ---
cmd = lambda x="Enter": self.click(x)
# create the button
cur = Button(self.top, text="Enter", width=5, height=3, command=cmd)
# position the button
cur.grid(row=4, column=0, columnspan=3, sticky='we')
btn.append(cur)