tkinter: press button to get its own grid - python

I am trying to create a column of buttons which when they are pressed, the grid that down a row show pop up another two buttons.
for i in tlist:
opl.append(Tk.Button(self.frame, width = 12 , text=i[3],command = lambda:self.pressedop(i[2], a)))
opl[a].grid(row=a, column=0, columnspan=2)
a = a + 1
That successfully create a column of buttons, with text(i[3]) correctly shown, but when a button is pressed, i[2] will be last button's info, and a will be last button's row +1.
Is there a way which I can pass the i[2] and it's own grid_info down?

I don't understand your question, but you can use widget.grid_forget() to remove a widget from the geometry manager. If you then want it in a different row, just widget.grid() with the new row and column. A simple example
try:
import Tkinter as tk ## Python 2.x
except ImportError:
import tkinter as tk ## Python 3.x
from functools import partial
opl = []
top = tk.Tk()
def move_it(num):
for ctr in range(num, 5):
opl[ctr].grid_forget()
opl[ctr].grid(row=6, column=ctr)
for but_num in range(5):
opl.append(tk.Button(top, width = 12 , text=str(but_num),
command = partial(move_it, but_num)))
opl[-1].grid(row=but_num, column=0, columnspan=2)
top.mainloop()

Related

Is there a function to switch "Tab" and "Enter" button in tkinter?

I'm creating a Gui with Tkinter with a lot of Entry widgets. However, I don't like the fact of clicking on Tab button to go from one entry to another. I would like it to be the Enter key that does this. Is there a function to make it happen ?? here is the list of all entries:
```python
entries = [self.entMath1, self.entMath2, self.entFran1,
self.entFran2, self.entSvt1, self.entSvt2, self.entEps1,
self.entEps2, self.entHg1, self.entHg2, self.entPc1,
self.entPc2, self.entAng1, self.entAng2, self.entPhi1,
self.entPhi2, self.entM1, self.entM2, self.entM3,
self.entM4]
for i in range(len(entries_1) - 1):
entries_1[i].bind("<Return>", lambda e: entries_1[i].focus_set())
```
all these entries are placed with place() method.
You can bind the <Return> key event on the Entry widget. Then in the bind callback, get the next widget in the focus order by .tk_focusNext() and move focus to this widget:
import tkinter as tk
root = tk.Tk()
for i in range(10):
e = tk.Entry(root)
e.grid(row=0, column=i)
e.bind('<Return>', lambda e: e.widget.tk_focusNext().focus_set())
root.mainloop()
Have a read of this answer binding enter to a widget for the difference between <Return> and <Enter>
From that, you can build something like
import tkinter as tk
top = tk.Tk()
frm = tk.Frame(top)
frm.pack()
# List of entries
seq = [None]
next = []
entmax = 5
for ii in range(entmax):
ent = tk.Entry(frm)
ent.pack(side=tk.LEFT, padx=5, pady=5)
seq.append(ent)
next.append(ent)
# Now set the entries to move to the next field
for ix in range(1, entmax, 1):
seq[ix].bind('<Return>', lambda e: next[ix].focus_set())
top.mainloop()

tkinter: How to add a list of strings to text on buttons in order?

I want to create a column of 10 buttons and have them numbered in order.
Is there a simpler way to do it using for loops that I can add the text to these buttons rather than coding out each button line by line?
This is what I have but it only puts the the number 10 text in each button?
I want each button numbered starting from 1 thru 10.
from tkinter import *
root = Tk()
#Create Buttons
def create_buttons():
number_text = []
for nums in range(0,10):
number_text.append(str(nums))
for col in range(10):
for num in number_text:
buttons = Button(root, font=30, text = num, padx=15, pady=10)
buttons.grid(row=0, column=col)
create_buttons()
root.mainloop()
This is my solution for your problem,
from tkinter import *
root = Tk()
#Create Buttons
def create_buttons():
for num in range(1,11):
buttons = Button(root, font=30, text =str(num), padx=15, pady=10)
buttons.grid(row=0, column=num)
create_buttons()
root.mainloop()
Actually, you can solve this one easily. Every time you should try to reduce the complexity of the program. Don't think much. So I supposed this code much easier to solve your problem. Here I using only one loop and that loop I use for the given name for the button and also the given column number. You using the same parameters for the Button widget and grid manipulation. When we use another name for the button you should want to create a list. That code example is given below,
from tkinter import *
root = Tk()
button_name=[f'number_{i}' for i in range(10)]
#Create Buttons
def create_buttons():
for num in range(1,11):
buttons = Button(root, font=30, text =str(button_name[num-1]), padx=15, pady=10)
buttons.grid(row=0, column=num)
create_buttons()
root.mainloop()
It might be because the 1st button gets overlapped by 2nd ... so on to 9th button. So, you see 9 on top, which hides other buttons.
Try a different way -
from tkinter import *
root = Tk()
#Create Buttons
def create_buttons():
number_text = [*range(1,10+1)] # Or you could just do this in your way
for col in range(10):
buttons = Button(root, font=30, text = number_text[col] , padx=15, pady=10)
buttons.grid(row=0, column=col)
create_buttons()
root.mainloop()
This will take the index number_text[col] and show the buttons.

Make Buttons on Tkinter automatically go to next line when reach border of the frame

I'm trying to make a tkinter script that will print a lot of buttons with functions like this.
from tkinter import *
def printbutton(x:int):
print(x)
root = Tk()
root.geometry('500x500')
for x in range(1,100):
Button(root, text = str(x), command = lambda:printbutton(x)).pack(side="left")
root.mainloop()
But it print all button in a line and expanded outside of my GUI. I want my button automatically go to the next line for convenient, but I don't know how to do it.
Firstly, I would suggest use grid() instead of pack() for more clarity in such cases.
Next, to pass the value of the button in function, bind your printbutton(b) with your button itself. This is because at the end of for loop, the value of x is 99 and this x will be then passed with every button.
Now, to print buttons in a new line after you reach up to the width of the window, I used a simple logic, you can edit the value of width variable according to your window and button size.
So, here's what you are looking for:
from tkinter import *
def printbutton(btn):
print(btn["text"])
root = Tk()
root.geometry('500x500')
r,c = 0,0
width = 21
for x in range(1,100):
b = Button(root, text = str(x))
b.grid(row=r, column=c, sticky=N+S+E+W) #use grid system
b["command"] = lambda b=b: printbutton(b) #now b is defined, so add command attribute to b, where you attach your button's scope within a lambda function
#printbutton(b) is the function that passes in the button itself
c+=1
if c==width:
r+=1
c=0
root.mainloop()

How to add a new entry box when clicking a button (Python, Tkinter)

Hi i want to add a new entry box when clicking a button. How can i do that ?
What've done is im able to "for loop" a group of entry boxes. But i want the entry boxes to appear one by one by clicking a button.
What've done
My code:
import tkinter as tk
from tkinter import *
root = Tk()
root.title("Entry box")
root.geometry("700x500")
my_entries = []
def something():
entry_list = ''
for entries in my_entries:
entry_list = entry_list + str(entries.get()) + '\n'
my_label.config(text=entry_list)
print(my_entries[0].get())
for x in range(5):
my_entry = Entry(root)
my_entry.grid(row=0, column=x, pady=20, padx=5)
my_entries.append(my_entry)
my_button = Button(root, text="Click Me!", command=something)
my_button.grid(row=1, column=0, pady=20)
There is not much of work here, create a variable to keep track of the columns you are inserting the widget into and then just insert it based on that number, like:
# Rest of your code..
my_entries = []
count = 0 # To keep track of inserted entries
def add():
global count
MAX_NUM = 4 # Maximum number of entries
if count <= MAX_NUM:
my_entries.append(Entry(root)) # Create and append to list
my_entries[-1].grid(row=0,column=count,padx=5) # Place the just created widget
count += 1 # Increase the count by 1
Button(root, text='Add', command=add).grid(row=1, column=1, padx=10) # A button to call the function
# Rest of your code..
Though I am not sure about your other function and its functionality, but it should work after you create entries and then click that button.

getting row and column from mouse click event

I have code to display rows and columns.
I wanted to get the row and column in shell,if I click with my mouse over the specified location consisting like R0/C0 in the GUI
My coding:
import Tkinter
root = Tkinter.Tk( )
for r in range(3):
for c in range(4):
Tkinter.Label(root, text='R%s/C%s'%(r,c),
borderwidth=1 ).grid(row=r,column=c)
root.mainloop( )
If i click my mouse over R2/C2 in the GUI,then it should display the output in shell as R2/C2
Please help me on how to attain this!
import Tkinter
root = Tkinter.Tk()
def handle_click(text):
print text
for r in range(3):
for c in range(6):
text = 'R%s/C%s'%(r,c)
label = Tkinter.Label(root, text=text, borderwidth=1 )
label.grid(row=r,column=c)
label.bind("<Button-1>", lambda e, text=text:handle_click(text))
root.mainloop()

Categories

Resources