Button will not change to active when listbox is selected? - python

I've made a function that creates a toplevel window with buttons and a listbox. I have an edit button to edit a selected item in said listbox, but I want this button disabled if nothing inside the listbox is selected.
def edit_page():
window3 = Toplevel()
frame3= Frame(window3)
frame3.pack(side=TOP)
color_list = Listbox(frame3)
color_list.grid(row=1,column=0)
edit_button = Button(frame3,text="Edit",command=fav_edit)
edit_button.grid(row=4,column=4)
if len(color_list.curselection()) > 0 :
edit_button.config(state=ACTIVE)
else:
edit_button.config(state=DISABLED)
The last thread was dead and it was filled with confusion, sorry.
It seems the if/else statement isn't working as intended. When I open this new window, the button is disabled, and when I click on the listbox, it stays disabled.
If I flip the ACTIVE and DISABLED states in the if/else, like:
if len(color_list.curselection()) > 0 :
edit_button.config(state=DISABLED)
else:
edit_button.config(state=ACTIVE)
The edit button is active, and will stay active even if the listbox is selected.
Is the window not updating? Do I need to try it another way? Any help is appreciated.
Edit: My listbox does include items/tuples inside of it even if it does not show it in this example of my project.

Used a mouse event to call to a function to check the length of the tuple.
def edit_page():
window3 = Toplevel()
frame3= Frame(window3)
frame3.pack(side=TOP)
color_list = Listbox(frame3)
color_list.grid(row=1,column=0)
edit_button = Button(frame3,text="Edit",command=fav_edit)
edit_button.grid(row=4,column=4)
color_list.bind("<Enter>",lambda *args: check_sel(edit_button,color_list.curselection()))
def check_sel(button,selection):
if len(selection) > 0:
button.config(state=ACTIVE)
else:
button.config(state=DISABLED)

Related

Only opening a Window only when it already is not open in Tkinter

I created a button in tkinter with its command being to create anew window. But I don't want it to create a new window every time I click the create a new window button. I want to tell the program to open the new window only if it is not already open. If somewhere in the background the window is already open and the user presses the create a new window button I want it to move that window on the first layer of the user's screen (bringing it upfront from all the other open windows).
Here is my code --
def main():
main_bg = "Gray"
main_fg = "White"
import tkinter as tk
employees = []
window = tk.Tk()
window.configure(bg=main_bg)
window.title("Business app")
window.geometry("1100x650")
def open_new_window():
random_window = tk.Toplevel(window)
random_window.configure(bg=main_bg)
random_window.geometry("600x600")
random_button = tk.Button(window, text="Do Something", font="Times 32", bg=main_bg, fg=main_fg, command=open_new_window)
random_button.pack()
window.mainloop()
if __name__ == "__main__":
main()
I have searched websites like Geeksforgeeks and this website but I could not find the solution I was looking for. Please help.
NOTE -- PLEASE DO NOT CLOSE THIS QUESTION AND POINT ME TOWARDS ANOTHER FORUM BECAUSE I HAVE CHECKED OTHERS IN THIS WEBSITE AS I MENTIONED ABOVE
Added grab_set() will prevent open new window again.
def open_new_window():
random_window = tk.Toplevel(window)
#random_window.configure(bg=main_bg)
random_window.geometry("600x600")
random_window.grab_set()
Result:
When you click Do Something will prevent open new window. Unless close the topelevel window and then open new window again
You can save a reference to the widget, and then check the reference to see if it's set. If it is set, you can then call winfo_exists to check whether the reference points to an existing window.
random_window = None
...
def open_new_window():
global random_window
if random_window and random_window.winfo_exists():
# the window exists, so do nothing
return
random_window = tk.Toplevel(window)
random_window.configure(bg=main_bg)
random_window.geometry("600x600")

Radio Button and Checkbox don't update variable value

I have a GUI that uses a class that calls a function that provides a popup window.
The popup box has a button that gets a directory from the user using askdirectory() from tkinter.filedialog, a pair of radio buttons(RadioG, RadioY), and checkbox(state_checkbox) that I want to update the two different variables(driveletter and statevalue) . I've set the drive letter to "G:" and that value is held correctly, but doesn't update if I select the "Y:" Radio button. I have the IntVar.set(1), but that checkbox does not populate as checked and checking/unchecking it keeps the value at 1 and does not update it to 0 when unchecked.
Any advice on what I'm missing to keep my values from updating is appreciated.
relevant section of code below:
class preferences(Preferences):
def save_preferences(self):
# Used to reset the folder location desired by the user
self.prefdialog = tk.Tk()
self.prefdialog.title('Set Preferences')
self.driveletter = tk.StringVar()
self.driveletter.set("G:")
self.statevalue = tk.IntVar()
self.statevalue.set(1)
self.fpath = '\\Desktop'
self.RadioG = tk.Radiobutton(self.prefdialog, text="G:", variable=self.driveletter,
value="G:", command=lambda: print(self.driveletter.get()))
self.RadioG.grid(row=3,column=0,sticky=tk.W,pady=4)
self.RadioY = tk.Radiobutton(self.prefdialog, text="Y:", variable=self.driveletter,
value="Y:", command=lambda: print(self.driveletter.get()))
self.RadioY.grid(row=3,column=1,sticky=tk.W,pady=4)
self.state_checkbox = tk.Checkbutton(
self.prefdialog, text="Check to use state folders",
variable=self.statevalue, command=lambda: print(self.statevalue.get()))
self.state_checkbox.grid(row=4,column=0,sticky=tk.W,pady=4)
self.prefdialog.mainloop()
For posterity: Looks like my issue was using Tk() twice. Per Bryan since I'm trying to create a popup window, I should be calling Toplevel(), not a second instance of Tk(). I also definitely called mainloop() twice, once for my main window and once for this popup window.

Customizing QPrintPreviewDialog with pyQt5

Based on the answer of Question with C++, I'm trying to do similar with PyQt5. I want to remove some buttons of QPrintPreviewDialog and add new ones. I can get the toolbar by toolbar = dialog.findChildren(QToolBar) and the buttons by buttons = dialog.findChildren(QToolButton), where dialog = QPrintPreviewDialog(printer), then I make a loop tor the buttons to check its names.
code snipped:
dialog = QPrintPreviewDialog(printer)
buttons = dialog.findChildren(QToolButton)
actions = dialog.findChildren(QAction)
toolbar = dialog.findChildren(QToolBar)
toolbar[0].addAction("PDF", saveaspdf) # This works fine to add a button
# and connection to saveaspdf()
for button in buttons:
print("entry:", button.objectName(), button.text())
if button.text() == 'Portrait' or button.text() == 'Landscape':
button.setDisabled(True) # Button will be disabled
button.setVisible(False) # Button still visible, but disabled
dialog.paintRequested.connect
I tried something with toolbar.removeAction()but I found no way to identify the demanded action. Also I don't think that's the solution. Also any .removeWidget(button) doesn't solve the problem.
So, please can you explain me this line from the mentioned page of c++ and give me a hint for PyQt:
//toolbarlist.first()->removeAction(toolbarlist.first()->actions().at(3));
Assuming you want to remove the Portrait and Landscape buttons then you must search through the QAction text and remove it from the QToolBar.
toolbar = dialog.findChild(QToolBar)
ACTIONS_TEXT = [
QCoreApplication.translate("QPrintPreviewDialog", text)
for text in ("Portrait", "Landscape")
]
for action in toolbar.actions():
if action.text() in ACTIONS_TEXT:
toolbar.removeAction(action)

getting radio button selection in PySide using Python 3.4

The radio buttons are in a submenu off the main menubar.
Cannot get the value of the radio box clicked in PySide this worked perfectly in Tkinter
and also how would one set default radio button checked in PySide?
in PySide: Cannot get value of radio box when changed/selected in pyside. This Works perfectly in tkinter below
os.chdir(user+'database')
dbfiles=glob.glob('ias*.db')
#self.var=('ias'+yr+'.db') used to set default radio button? somehow
self.ag = QActionGroup(self)
for self.x in dbfiles: #dbfiles is a "list" of 3 databases
dbselect = self.ag.addAction(QAction(self.x, self, checkable=True))#how to set default?
self.menuDatabases.addAction(dbselect)
self.ag.triggered.connect(self.displaydb) #need to trigger something else?
def displaydb(self):
print(self.x) #need to print something else maybe?
In TK; Works perfectly here change radio button and will print database name to textbox
os.chdir(os.path.expanduser('~')+'/Desktop/data/database')
self.dbfiles=glob.glob('ias*.db')
self.var=StringVar()
self.var.set('ias'+str(dte)+'.db')
for x in self.dbfiles:
dbfle.add_radiobutton(label=x,variable=self.var, value=x,command=self.sel)
def sel(self):
selection = "You changed to database: " + str(self.var.get())
self.b.delete(1.0,END)
self.b.insert(END,selection)
To set one of the actions checked at the start:
self.ag.actions()[0].setChecked(true)
#selects first action, or do this at creation time
and change the callback:
def sel(self, action):
print action.text()

Python tkinter, how to disable background buttons from being clicked

When opening a new tkinter window, I only want the user to be able to click buttons on the new window. They should not be able to click on buttons from other windows that are part of the application. How would I accomplish this?
Here is a snip of my code:
def exportEFS(self):
self.exportGUI = Toplevel()
Button(self.exportGUI, text='Backup', command=self.backup).pack(padx=100,pady=5)
Button(self.exportGUI, text='Restore', command=self.restore).pack(padx=100,pady=5)
def backup(self):
self.backupWindow = Toplevel()
message = "Enter a name for your Backup."
Label(self.backupWindow, text=message).pack()
self.entry = Entry(self.backupWindow,text="enter your choice")
self.entry.pack(side=TOP,padx=10,pady=12)
self.button = Button(self.backupWindow, text="Backup",command=self.backupCallBack)
self.button.pack(side=BOTTOM,padx=10,pady=10)
In this snip, once the backupWindow is opened, the exportGUI remains open, but the user should not be able to click "Backup" or "Restore" while the backupWindow is opened.
Thanks!
You will want to call grab_set on the TopLevel window so that all keyboard and mouse events are sent to that.
def exportEFS(self):
self.exportGUI = Toplevel()
Button(self.exportGUI, text='Backup', command=self.backup).pack(padx=100,pady=5)
Button(self.exportGUI, text='Restore', command=self.restore).pack(padx=100,pady=5)
def backup(self):
self.backupWindow = Toplevel()
self.backupWindow.grab_set()
message = "Enter a name for your Backup."
Label(self.backupWindow, text=message).pack()
self.entry = Entry(self.backupWindow,text="enter your choice")
self.entry.pack(side=TOP,padx=10,pady=12)
self.button = Button(self.backupWindow, text="Backup",command=self.backupCallBack)
self.button.pack(side=BOTTOM,padx=10,pady=10)
What you can do is set the state to disabled. As so:
self.button.config(state="disabled")
And to enable it, you just use:
self.button.config(state="normal")
However, you must assign your buttons to variables first, like this:
self.backup=Button(self.exportGUI, text='Backup', command=self.backup)
self.backup.pack(padx=100,pady=5)
self.restore=Button(self.exportGUI, text='Restore', command=self.restore)
self.restore.pack(padx=100,pady=5)
so you would disable these using:
self.backup.config(state="disabled")
self.restore.config(state="disabled")
and re-enable using:
self.backup.config(state="normal")
self.restore.config(state="normal")
Please note however, that while the button is disabled, nothing can be changed to that button, both through the code, or through the user using it. So that means if you wanted to change the text of that button, you would have to change the state of the button to "normal" before changing it (if it already isn't in that state, which by default, all widgets are in that state when first created).
Cheers :)

Categories

Resources