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)
Related
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)
I am automating the steps to change the policy for the logoff button. The steps involved are:
Open Local Group Policy using gpedit.msc
Select "Start Menu and Taskbar" from the dropdown in User Configuration > Administrative Template from the left pane
In the right pane, double click on "Change Start Menu power button"
Select the radio button "Enabled"
From the dropdown menu of options: Select "Log Off"
I have gotten through the third step, but I have a problem in mapping the "Change Start Menu Power Button" from the second step. My code is as below:
from pywinauto import Application
Application().start(r'mmc gpedit.msc')
app = Application(backend="uia").connect(path='mmc.exe')
#app.LocalGroupPolicyEditor.dump_tree()
Admin_template = app.LocalGroupPolicyEditor.child_window(title="User
Configuration", control_type="TreeItem").child_window(title="Administrative
Templates", control_type="TreeItem") # since there are same templates
Admin_template.double_click_input() # it expands the subtree
#Admin_template.dump_tree()
Start_menu = Admin_template.child_window(title="Start Menu and Taskbar",
control_type="TreeItem").double_click_input()
Start_menu.dump_tree()
#Admin_template.child_window(title="Start Menu and Taskbar",
control_type="TreeItem").dump_tree()
#Change_start_menu = Start_menu.child_window(title="Change Start Menu power
#button", control_type="MenuItem").double_click_input()
#Change_start_menu.dump_tree()
I have trouble in finding and mapping the elements in the right pane. Also, when I use Start_menu.dump_tree(), there are only "Notification" elements shown. However, the rest, which includes "Change Start Menu power button," is what I'll be double clicking next.
I appreciate the help. Thanks.
It was kinda tricky, but this should do the job (it does all the steps you've listed - presses OK - and closes the program):
import pywinauto
pywinauto.Application().start(r'mmc gpedit.msc')
app = pywinauto.Application(backend="uia").connect(path='mmc.exe')
admin_template = app.LocalGroupPolicyEditor.child_window(title="User Configuration", control_type="TreeItem").child_window(title="Administrative Templates", control_type="TreeItem")
admin_template.double_click_input()
start_menu = admin_template.child_window(title="Start Menu and Taskbar", control_type="TreeItem")
start_menu.double_click_input()
option_list = app.LocalGroupPolicyEditor.child_window(auto_id="12786", control_type="List")
# Just select any of the first options to change the focus to the list.
first_elem = option_list.child_window(title="Add Search Internet link to Start Menu", control_type="ListItem")
first_elem.click_input()
# Used to scroll down the window so that the wanted option becomes visible.
pywinauto.keyboard.send_keys("cccc")
option = option_list.child_window(title="Change Start Menu power button", control_type="ListItem")
option.double_click_input()
pop_up = app.LocalGroupPolicyEditor.child_window(auto_id="tableLayoutFullForm", control_type="Pane")
radio = pop_up.child_window(title="Enabled", auto_id="radioButtonEnabled", control_type="RadioButton")
radio.click_input()
drop_down = pop_up.child_window(title="Choose one of the following actions", auto_id="dropDownListChoose one of the following actions", control_type="ComboBox")
drop_down.click_input()
# 'Hack' to first select the Restart option and then the next option after that which starts with l (=Log off).
# This ensures that the correct setting gets set despite of what the setting was before.
pywinauto.keyboard.send_keys("rl{ENTER}")
ok = pop_up.child_window(title="OK", auto_id="buttonOK", control_type="Button")
ok.click_input()
app.kill()
Make sure to run this script as administrator or else it will fail.
Feel free to ask if you got any questions about the code :)
Edit:
If you're running a version of pywinauto <0.6.0, you'll have to replace the two occurances (lines 19 and 34) of pywinauto.keyboard.send_keys() with:
pywinauto.SendKeysCtypes.SendKeys()
If that doesn't work you could try:
pywinauto.keyboard.SendKeys()
https://docs.bokeh.org/en/latest/docs/user_guide/interaction/widgets.html (You can see select)
I want to call a button, text input and slider in using select.
plot_button = Button(label="plot")
color_button = Button(label="Color", disabled=True)
axis_start_value_text = TextInput(title=" Start value=", value="270")
axis_slider = Slider(value=0, start=0, end=100, step=1, title="Title")
button_map = {
"plot": plot_button,
"Color": color_button,
"Start value": axis_start_value_text,
"Slider": axis_slider
}
button_call = Select(title="Button call", options=sorted(button_map.keys()),
value="plot")
In the Select button, when I click on a button, text_input and slider the button appears on the screen that I clicked. İs it possible?
I put up an example app on bitbucket.
You can give css_classes to your widgets, or widgetbox, and then access the div elements contaning the widgets in a CustomJS callback.
I have not found a way to set the display to None from the start, couldn't do it with customm css. So I use a timeout function, you'd need to tweak the timing of the timeout function if you don't want the widgets to appear before they are made invisible.
EDIT:
I updated the code, in fact there is a clean way to hide the widgets initially without using a timeout callback. I use a custom css for that with display:none for all objects with class "hidden". Then in the CustomJS you just need to add or remove the "hidden" to the class name of the widgetboxes.
I'm using EPD traits for a basic GUI interface. I'm able to pop up a settings window using code like this:
settings_w.configure_traits(kind="livemodal")
The window has 'OK' and 'Cancel' buttons and I want to do something different depending on which button was pressed to exit the window. Seems like it should be simple but I can't figure out how to set this up.
Theoretically I'd like to do something like this:
# Display the settings widget
settings_w.configure_traits(kind="livemodal")
if settings_w.CancelButtonPressed:
pass
else:
print "I got the input"
But let me know if there's a better or more correct way to do this.
Also FWIW: here's the view properties of my settings window with standard OK and Cancel buttons:
view = View(
settings_group,
title = 'Settings Editor',
width = 500,
buttons = [OKButton, CancelButton, 'Help' ],
kind = 'modal',
handler = SaveRestore_Handler()
)
If I understand the question, checking the output of configure_traits should do what you want:
result = settings_w.configure_traits(kind="livemodal")
if result:
print "The user pressed OK."
else:
print "The user pressed Cancel or closed the window."
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 :)