Tkinter Menu and Buttons - python

I'm trying to make a Tkinter menu that is like a taskbar checker.
So if I go to this menu and check a box, a specific button then appears on my window, and then the user can select multiple buttons based on what they want.
The program is just a bunch of buttons that after entering text in my text field, and clicking the button, a web browser launches with a search of the website that the button is linked to.
How can I make a menu like I mentioned above?
Edit:
I've just tried basic menu stuff:
buttonmenu = Menu(menubar, tearoff=0)
buttonmenu.add_command(label="button1", command=turnbuttononoff)
buttonmenu.add_command(label="button2", command=turnbuttononoff)
buttonmenu.add_command(label="button3", command=turnbuttononoff)
buttonmenu.add_command(label="button4", command=turnbuttononoff)
buttonmenu.add_command(label="button5", command=turnbuttononoff)
This just creates a basic menu. And if I could have a function that triggers a button to be turned on or off that would be great.
So essentially just a function to swap a button from being shown to not being shown
def turnbuttononoff():
#togglebutton here
ANSWER:
I made a dictionary of the data of where each button was stored, and then checked to see if the button was active, and if it was, turned it off, and if it was inactive, turn it off.
Making this a command lambda function for each button works.
def Toggle_Button(myButton):
if myButton.winfo_ismapped()==1:
myButton.grid_forget()
else:
myButton.grid(row=gridData[myButton][0],column=gridData[myButton][1])

gridData = {}
gridData[button] = [row,col]
def Toggle_Button(myButton):
if myButton.winfo_ismapped()==1:
myButton.grid_forget()
else:
myButton.grid(row=gridData[myButton][0],column=gridData[myButton][1])
If you already have buttons on a grid, use button.grid_info to find what you need, it returns a dictionary.

Related

How to create a dropdown menu on clicking Qaction in PyQt5?

I am making an application where I want to create a dropdown menu if anyone clicks on the Qaction.
My code
self.navtb = QToolBar("Navigation")
self.navtb.setIconSize(QSize(25, 25))
self.navtb.setMovable(False)
self.addToolBar(self.navtb)
option_btn = QAction(QIcon(os.path.join('images', 'options.png')), "Option", self)
self.navtb.addAction(option_btn)
A QAction can have an associated menu which you can simply set with setMenu(). This menu will pop up (drop down) on click+hold.
Now all you need is to set your button to directly go for the menu on click by altering its popup mode. Note that while the wording pop up is used, the menu will be a proper drop-down menu in a toolbar scenario.
In your example it would roughly translate to:
option_btn.setMenu(...)
self.navtb.widgetForAction(option_btn).setPopupMode(QToolButton.InstantPopup)
For reference, this is how I do it in my code in C++:
// initialize compute menu and let button display menu without holding mouse
actionComputeDisplay->setMenu(new QMenu(widget));
auto btn = qobject_cast<QToolButton*>(toolBar->widgetForAction(actionComputeDisplay));
btn->setPopupMode(QToolButton::ToolButtonPopupMode::InstantPopup);

How to cause ttk OptionMenu dropdown selection (expansion) on object focus via tab traversion?

We have a Tkinter form with ttk OptionMenu dropdown boxes on it. When you click on the dropdown you can start typing your selection and the dropdown will automatically focus on the selection that starts with those characters.
The problem occurs when you use tab to traverse to the menu, rather than using the mouse. Tab will highlight the ttk.OptionMenu however it will not expand the dropdown to begin typing text unless you hit the spacebar or click.
Is there are way to force click() or something any time the OptionMenu gets tab focused?
I attempted to do some stuff with .bind and .configure but I'm definitely lost :)
cust_selection = StringVar(window)
customers = getcustomerlist() # pulls customer list from file
vic_name_lbl = Label(window, text="Select Customer:")
vic_name_lbl.grid(column=0, row=3)
vic_name_box = ttk.OptionMenu(window, cust_selection, *customers)
vic_name_box.grid(column=1, row=3, sticky=(W,E))
vic_name_box.configure(width=15)
Not sure if this is helpful, but the documentation says that all ttk widgets have a takefocus attribute, which:
Determines whether the window accepts the focus during keyboard
traversal. 0, 1 or an empty string is returned. If 0 is returned, it
means that the window should be skipped entirely during keyboard
traversal. If 1, it means that the window should receive the input
focus as long as it is viewable. And an empty string means that the
traversal scripts make the decision about whether or not to focus on
the window.

how to check if button is clicked on tkinter

I am trying to create a car configurator using tkinter as a gui in my free time.
I have managed to open a tkinter box with images that act as buttons.
What I want to do is for the user to click on a button. I want to check which button has been clicked (i.e if the family car button is clicked, how can I check that it has been clicked).
I have done my research on this website, and all of the solutions I have found have been in javascript or other languages.
Once the button has been clicked, I want a new window to be opened ONLY containing attributes for a family car i.e a family car can have a red exterior colour, but a sports car cannot have a red exterior colour at all.
Here is my code below:
from tkinter import *
import tkinter as tk
def create_window():
window = tk.Toplevel(root)
root = tk.Tk()
familycar = PhotoImage(file = "VW family car.png")
familylabel = Button(root, image=familycar)
familybutton = Button(root, image=familycar, command=create_window)
familybutton.pack()
So how can I check that the family car button has been clicked?
Thanks
Use a Boolean flag.
Define isClicked as False near the beginning of your code, and then set isClicked as True in your create_window() function.
This way, other functions and variables in your code can see whether the button's been clicked (if isClicked).
Not sure what you asked, do you want to disable it or check its status in another routine ?
Or just to count the times it has been clicked,
In order to do that Simple solution would be to add a general variable that will be updated inside the create_window method (general because you want to allow access from other places).
First, you would need to initialize a function in which you want to execute on the button click.
example:
def button_clicked():
print('I got clicked')
Then, when you define the target button, you'll have to set the 'command' argument to the required function(the button_clicked function in this context).

Implementing checkable buttons in Pyqt5 file menu to act similarly to radio buttons

I have created a file menu in PyQt5 with a "File" option with two checkable buttons (button1, button2). Unfortunately, I have not found a way to implement radio buttons into the file menu so I assume at the moment it is not possible. Instead, I would like to make these two checkable buttons act like radio buttons - this means that if one is checked the other becomes unchecked. Only one can be checked at a given time.
I have attempted to do it this way (which I find the most logical and straightforward), but it does not work:
def fileMenu(self):
if self.button1.isChecked() == True:
self.button2.setChecked(False)
If I check button2 and then check button1, button2 does not uncheck. Is there any other way to do this or any error in my code preventing it from working? Or... ideally is there any way to implement radio buttons into the file menu?
You can accomplish this using a QActionGroup. You would have to group all those buttons together under an action group. It will not work otherwise.
The documentation can be found here.
Here is an example of implementing a QActionGroup with two radio buttons:
w is your QtMainWindow, ag is defining the QActionGroup, and menu is the name of your menu.
ag = QtGui.QActionGroup(w, exclusive=True)
a = ag.addAction(action_a)
menu.addAction(a)
b = ag.addAction(action_b)
menu.addAction(b)

Hide and show ttk.Combobox dropdown list

Situation: When I use the mouse button to click the "down-arrow" of a ttk.Combobox it's standard behaviour is to show a dropdown list. When the down arrow is clicked on the second time, the combobox dropdown list will become hidden.
Using the keyboard. it is possible to show the combobox dropdown list by pressing the "down-arrow" once. Pressing the "down-arrow" further will scroll down the dropdown list to its end. Pressing the "up-arrow" repeatedly will scroll up the dropdown list until the highlight/selection reaches to the top of the dropdown list, but it does not finally hide the dropdown list.
Question: Without using the mouse or keyboard, that is, using computer programming, how can I hide an expose dropdown list of a ttk.Combobox. I am aware that the w.event_generate("<Down>") command can be used to program a ttk.Combobox to show it's dropdown list. But how do I achieve the opposite? That is, how can I use the same w.event_generate() command to hide the dropdown list? Or what other tkinter command should I use to achieve what I want?
I made several attempts at this question and finally found a way to hide the combobox droplist via programming. My code is shown below.
OBSERVATIONS:
Using "combobox_widget_object.event_generate('<Button-1>')" can
cause the combobox dropdown list to show. Event '<Button-1>' appears to be
inherently defined to cause this behavior.
Running 2 of this command back to back do not lead to the showing
and hiding of the combobox dropdown list. It still only SHOWS the dropdown
list as with a single command.
The "combobox_widget_object.after(delay_ms, callback=None, *args)"
method can be used to instruct the combobox to run a function
after certain time delays. That function should contain the
"combobox_widget_object.event_generate('<Button-1>')" method to cause the
hiding of the dropdown list.
CODE:
# tkinter modules
import tkinter as tk
import tkinter.ttk as ttk
"""
Aim:
Create a combobox widget and use w.event_generate(sequence, sequence,**kw) to
simulate external stimuli to cause combobox dropdown list to show and hide.
Author: Sun Bear
Date: 16/01/2017
"""
# Function to activate combobox's '<Button-1>' event
def _source_delayed_clicked():
print ('\n def __source_delayed_clicked():')
print('Delayed 2nd simulation of external stimuli')
print('HIDE combobox Dropdown list. \n'
'IT WORKED!')
source.event_generate('<Button-1>')
root = tk.Tk()
source_var=tk.StringVar()
reference=['Peter', 'Scotty', 'Walter', 'Scott', 'Mary', 'Sarah']
# Create Main Frame in root
frame0 = ttk.Frame(root, borderwidth=10, relief=tk.RAISED)
frame0.grid(row=0, column=0, sticky='nsew')
# Create Combobox
source = ttk.Combobox(frame0, textvariable=source_var, values=reference)
source.grid(row=0, column=0, sticky='nsew')
# Simulate external stimuli using w.event_generate(sequence,**kw)
print('\n', '1st simulation of external stimuli using: \n'
' source.event_generate('"<Button-1>"') \n'
' SHOW Combobox Dropdown List.')
source.event_generate('<Button-1>')
#source.event_generate('<Button-1>') # running another similar command
# back to back didn't work
delay = 1000*6 # 6 seconds delay
source.after(delay, _source_delayed_clicked)
Update:
Alternatively, to hide the combobox dropdown list, the command
source.event_generate('<Escape>') can be used in place of the source.event_generate('<Button-1>') command defined in the function def _source_delayed_clicked(). This simulates pressing the keyboard "Esc" key.

Categories