Python Forum
[Tkinter] [SOLVED] Create per button popup menu py2.7
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
[Tkinter] [SOLVED] Create per button popup menu py2.7
#1
Simplified code:
from Tkinter import *
root = Tk()
def hello():
	print("this is a hello:")
def test():
	print("this is a test:")
def popup(event):
		try:
			popup_menu.tk_popup(event.x_root, event.y_root, 0)
		finally:
			popup_menu.grab_release()

def generate_buttons():
    rowset = 0
    colset = 0
    for i in range(10):
        Packer = Frame(root, bg="white", borderwidth=1, relief=RAISED)
        B= Button(Packer, command=test, borderwidth=0, bg="red")
        L = Label(Packer, text="button %s" %i, justify=CENTER, bg="white")
        B.bind("<Button-3>", popup)
        B.pack(side=TOP, fill=BOTH, expand=1)
        L.pack(side=TOP)
        Packer.pack(side=LEFT)
        Packer.grid(padx=5, pady=5, sticky="nsew", row=rowset, column=colset)
        if colset == 3:
            colset = 0
            rowset +=1
        else:
            colset += 1
popup_menu = Menu(root, tearoff=0)
popup_menu.add_command(label="test ", command=hello)
generate_buttons()
root.mainloop()
Objective:
Pass the buttons lable to the popup menu so i can refernce it later

def hello():
	print("this is a hello:")
##OUTPUT "this is a hello:"
#to
##
def hello(text):
	print("this is a hello: %s" %text)
##OUTPUT "this is a hello: button 1"
So each button can pass a differnet variable to the popup menu.
I have tried quite a few things. I tried putting the popup menu inside the generate_buttons function but then its not defined in the popup function, or i have issues passing the event variable to the popup function.
Reply
#2
I don't know what's wrong but you do seem to have defined hello 3 times.
Post the real code not what you have so it can be examined properly.
Reply
#3
You bind each Button to test() and to popup(). Pick one or the other and have it do everything. Also you can not use both grid and pack on the Frame Packer. To answer your question, use partial to send values from a Button to a function, so if you use test()
from functools import partial

def test(string_passed):
    print("this is a test:", string_passed)

## pass the button number to the function
B= Button(Packer, text=i, command=partial(test, i), borderwidth=0, bg="red")
Reply
#4
I have not defined Hello 3 times.
The first code is the example, my actual code is 300+ lines and messy. The example code is everything you need to answer the question.
The second code is what im getting currently vs what i want as an output (the ##OUTPUT comments show what i would get)
I am not looking on how to pass a variable to a function, thats as simple as "command= lambda i=1: test(i)" my question is regarding the popup menu and how i can pass a variable to that menu.
popup_menu.add_command(label="test ", command=hello)
When i right click a button the popup menu shows and i can click the test option, when i click test it runs the function hello. What im looking for is to run "hello(text)" with text being the name of the button i clicked.
I also plan on using a single mouse click to open a new window so that's why that is still there.
Reply
#5
Well I hope woooee's answer gives you the solution then.
Reply
#6
ok well this has taken me the best part of 12 hours and is a bit messy but the functionality is there.

from Tkinter import *
from time import sleep
root = Tk()

def hello(text):
	print("this is button: %s" %text)

def popup(event, popup_menu):
		
		try:
			popup_menu.tk_popup(event.x_root, event.y_root, 0)
		finally:
			popup_menu.grab_release()
			
def all_children(element):
	list = element.winfo_children()
	for item in list:
		if item.winfo_children():
			list.extend(item.winfo_children())
	return list

def test(event):
	if event.widget.winfo_class() == 'Label': ##get the main perent frame of the clicked widget, or return the widget if is perent
		perent = event.widget.master
	else:
		perent = event.widget##--

	clearBG = all_children(perent.master) ##make all widges default to white
	for c in clearBG:
		c.configure(bg="white")

	perent.configure(bg="blue") ##set the perent widget to blue
	list = all_children(perent) #recursivly gets all children of the perent
	for l in list:
		l.configure(bg="blue") ##sets all children to blue

	
def createpopup(event):
	if event.widget.winfo_class() == 'Label': ##get the main perent frame of the clicked widget, or return the widget if is perent
		perent = event.widget.master
	else:
		perent = event.widget##--

	clearBG = all_children(perent.master) ##make all widges default to white
	for c in clearBG:
		c.configure(bg="white")

	perent.configure(bg="blue") ##set the perent widget to blue
	list = all_children(perent) #recursivly gets all children of the perent
	for l in list:
		l.configure(bg="blue") ##sets all children to blue
		textvar = l.cget("textvariable") ##gets the textvariable entry
	popup_menu = Menu(root, tearoff=0) ##create the popup menu
	popup_menu.add_command(label="Open ", command=lambda text=textvar: hello(text))
	popup_menu.add_command(label="Encrypt and Delete Local ", command=lambda text=textvar: hello(text))
	popup_menu.add_command(label="Encrypt Keep Local ", command=lambda text=textvar: hello(text))
	popup_menu.add_command(label="Share", command=lambda text=textvar: hello(text))	
	popup_menu.add_command(label="Delete ", command=lambda text=textvar: hello(text))
	popup_menu.add_command(label="Check Owner ", command=lambda text=textvar: hello(text))
	sleep(0.15)##prevents accidental right click of menu items
	popup(event, popup_menu) ##passes both the event and the new popup menu to the correct function to spawn the menu

def retag(tag, *args):
	for widget in args:
		widget.bindtags((tag,) + widget.bindtags())

def generate_buttons():
	rowset = 0
	colset = 0
	for i in range(12):
		l = "button %s" %i
		Packer = Frame(root, bg="white", borderwidth=1, relief=RAISED, width=50, height=50)
		B= Label(Packer, textvariable=l, borderwidth=0, bg="white", width=10, height=10)
		L = Label(Packer, text=l,  textvariable=l, justify=CENTER, bg="white")
		B.pack(side=TOP, fill=BOTH, expand=1)
		L.pack(side=TOP, fill=BOTH, expand=1)
		retag("right", Packer, B, L)
		Packer.bind_class("right", "<Button-3>", lambda e = Event():createpopup(e))
		retag("left", Packer, B, L)
		Packer.bind_class("left", "<Button-1>", lambda e = Event():test(e))
		Packer.grid(padx=5, pady=5, sticky="nsew", row=rowset, column=colset)
		if colset == 3:
			colset = 0
			rowset +=1
		else:
			colset += 1
popup_menu = Menu(root, tearoff=0)
popup_menu.add_command(label="test ", command=hello)
generate_buttons()
root.mainloop()
If you left click any of the Frames (or their respective children), it will run the test function. However if you right click them, it will create a popup menu and have the textvariable of the button you clicked, it will then pass that to the hello function and print it out.

Hopefully this will be usefull to someone generating popup menus in the future.
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  [PyQt] Hover over highlighted text and open popup window DrakeSoft 2 1,448 Oct-29-2022, 04:30 PM
Last Post: DrakeSoft
  [WxPython] [SOLVED] How to change button label? Winfried 3 2,020 May-31-2022, 06:37 PM
Last Post: Winfried
  Class function does not create command button Heyjoe 2 2,227 Aug-22-2020, 08:06 PM
Last Post: Heyjoe
  POPUP on widget Entry taratata2020 4 3,673 Mar-10-2020, 05:04 PM
Last Post: taratata2020
  [PySimpleGui] How to alter mouse click button of a standard submit button? skyerosebud 3 4,949 Jul-21-2019, 06:02 PM
Last Post: FullOfHelp
  [WxPython] How to show remove button at the right side of the hovering item of a combobox popup? indrajitmajumdar 0 2,492 Mar-28-2019, 11:24 AM
Last Post: indrajitmajumdar
  Simple Button click on image file to create action? jpezz 4 6,795 Mar-27-2019, 10:08 PM
Last Post: jpezz
  Please advice Linux library - tray icon, popup windows, ICQ/Skype style etc ramendik 5 3,990 Dec-03-2017, 04:35 AM
Last Post: Larz60+
  popup message box code runs in Windows, but not in Linux Luke_Drillbrain 13 14,786 May-10-2017, 01:05 AM
Last Post: metulburr

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020