add keyboard shortcuts to GIo.Menu - python-3.x

I am trying to add accelgroup (keyboard shortcuts) to the Gio.Menu items.
But I have not found a way to do this. Like, in this example, I want to open file with <Ctrl>+o
filemenu = Gio.Menu()
filemenu.append("Open","win.open")
accelgroup=Gtk.AccelGroup()
self.add_accel_group(accelgroup)
# Open menu
open_action = Gio.SimpleAction(name="open")
# this line is problematic
open_action.add_accelerator("activate". Gdk._keyval_from_name("O"))
open_action.connect("activate", self.MenuElem.file_open_clicked)
self.add_action(open_action)
How can I do this?

You don't add keybindings to the Gio.Action itself you add them to a Widget or Application for example:
app = # My Gtk.Application instance
window = # My Gtk.ApplicationWindow instance
action = Gio.SimpleAction.new('open', None)
window.add_action(action)
app.add_accelerator('<Primary>o', 'win.open', None)
# The 'win.' prefix is because it was added to a Gtk.ApplicationWindow

Related

to iterate the sub menu item using pywinauto

I am new to pywinauto and have just started learning. I need to find all the items present in the menubar.
I have a code to open the 7-zip application and I am trying to fetch all the menu item present in it.
if (os.path.exists(r"C:/Program Files/7-Zip/7zFM.exe")):
app = Application(backend='uia').start(r"C:/Program Files/7-Zip/7zFM.exe")
win = app.window()
app.top_window().descendants(control_type="MenuBar")
menu = app.top_window().descendants(control_type="MenuBar")[1]
for main_item in menu.children():
main_item.invoke()
subitems_level_1 = app.top_window().descendants(control_type="MenuItem")
print([i.window_text() for i in subitems_level_1])
# iterate expanded items (level 1)
for item in subitems_level_1:
if item.legacy_properties()[u'DefaultAction'] == u'Open':
# it has submenu
item.invoke()
subitems_level_2 = app.window(control_type="Menu", found_index=0).children()
print([i.window_text() for i in subitems_level_2])
time.sleep(3)
It is throwing error :
Traceback (most recent call last):
File "C:\Users\40011212\PycharmProjects\winapp\venv\lib\site-packages\pywinauto\application.py", line 250, in __resolve_control
ctrl = wait_until_passes(
File "C:\Users\40011212\PycharmProjects\winapp\venv\lib\site-packages\pywinauto\timings.py", line 458, in wait_until_passes
raise err
pywinauto.timings.TimeoutError
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:/Users/40011212/PycharmProjects/winapp/examples/7zip.py", line 33, in <module>
subitems_level_2 = app.window(control_type="Menu", found_index=0).children()
File "C:\Users\40011212\PycharmProjects\winapp\venv\lib\site-packages\pywinauto\application.py", line 396, in __getattribute__
ctrls = self.__resolve_control(self.criteria)
File "C:\Users\40011212\PycharmProjects\winapp\venv\lib\site-packages\pywinauto\application.py", line 261, in __resolve_control
raise e.original_exception
File "C:\Users\40011212\PycharmProjects\winapp\venv\lib\site-packages\pywinauto\timings.py", line 436, in wait_until_passes
func_val = func(*args, **kwargs)
File "C:\Users\40011212\PycharmProjects\winapp\venv\lib\site-packages\pywinauto\application.py", line 204, in __get_ctrl
dialog = self.backend.generic_wrapper_class(findwindows.find_element(**criteria[0]))
File "C:\Users\40011212\PycharmProjects\winapp\venv\lib\site-packages\pywinauto\findwindows.py", line 87, in find_element
raise ElementNotFoundError(kwargs)
pywinauto.findwindows.ElementNotFoundError: {'control_type': 'Menu', 'found_index': 0, 'backend': 'uia', 'process': 14956}
I have tried writing a recursive function to do this... you can refer below code... This code will work fine for 7z but for other application it may or may not... it depends on how the menu were designed during application development...
import time
import os
from pywinauto.application import Application
def printFormatedString(inString, rightSpacing):
string_length = len(inString) + rightSpacing
string_revised = inString.rjust(string_length)
print(string_revised)
def printMenuItems(menu_item, mainWindow, menuName, spacing):
# Open the Menu
menu_item.invoke()
time.sleep(0.5)
#Access the menubar via application
menu = mainWindow.child_window(title="Application", auto_id="MenuBar", control_type="MenuBar")
# Access current Titled "title" menu item
curMenu = menu.child_window(title = menuName, control_type = "Menu")
# iterate over the menu Items
for menuItem in curMenu.children():
# Get Menu Name from legacy properties
menuName = menuItem.legacy_properties().get(u'Name')
# Print formatted String based upon spacing
printFormatedString(inString = menuName, rightSpacing = spacing*2)
# If this is a submenu and recusively call this function
if menuItem.legacy_properties().get(u'ChildId') == 0:
# recursive call
printMenuItems(menu_item = menuItem, mainWindow = mainWindow, menuName = menuName, spacing = spacing*2)
# press ESC to remove the menu
mainWindow.type_keys("{ESC}")
def main():
if (os.path.exists(r"C:/Program Files/7-Zip/7zFM.exe")):
wpfApp = Application(backend='uia').start(r"C:/Program Files/7-Zip/7zFM.exe")
# access main Window of applications just started
wind = wpfApp.windows()
#Get Application Window Title
title = wind[0].get_properties()[u'texts'][0]
print("Started Application {}".format(title))
# Get Main Window
mainWindow = wpfApp.window(title = title)
# Get menu
menu = mainWindow.child_window(title="Application", auto_id="MenuBar", control_type="MenuBar")
print("No of Main Menu in App = len(menu.children()) - {}\n".format(len(menu.children())))
spacing = 3
#Iterate over all the menu in menubar
for menu_item in menu.children():
if menu_item.get_expand_state() == 0:
#Get Menu Names
menuName = menu_item.window_text()
# Print formatted String based upon spacing
printFormatedString(menuName, spacing)
# call function
printMenuItems(menu_item = menu_item, mainWindow = mainWindow, menuName = menuName, spacing = spacing)
# press ESC to remove the menu
mainWindow.type_keys("{ESC}")
if __name__ == "__main__":
main()
-------- OUTPUT -----------------
Started Application 7-Zip
No of Main Menu in App = len(menu.children()) - 6
File
Open Enter
Open Inside Ctrl+PgDn
Open Inside *
Open Inside #
Open Outside Shift+Enter
View F3
Edit F4
Rename F2
Copy To... F5
Move To... F6
Delete Del
Split file...
Combine files...
Properties Alt+Enter
Comment... Ctrl+Z
CRC
CRC-32
CRC-64
SHA-1
SHA-256
*
Create Folder F7
Create File Ctrl+N
Link...
Alternate streams
Exit Alt+F4
Edit
Select All Shift+[Grey +]
Deselect All Shift+[Grey -]
Invert Selection Grey *
Select... Grey +
Deselect... Grey -
Select by Type Alt+[Grey+]
Deselect by Type Alt+[Grey -]
View
Large Icons Ctrl+1
Small Icons Ctrl+2
List Ctrl+3
Details Ctrl+4
Name Ctrl+F3
Type Ctrl+F4
Date Ctrl+F5
Size Ctrl+F6
Unsorted Ctrl+F7
Flat View
2 Panels F9
2021-04-28
2021-04-28
2021-04-28 11:08
2021-04-28 11:08:54
2021-04-28 11:08:54.1341867
Toolbars
Archive Toolbar
Standard Toolbar
Large Buttons
Show Buttons Text
Open Root Folder \
Up One Level Backspace
Folders History... Alt+F12
Refresh Ctrl+R
Auto Refresh
Favorites
Add folder to Favorites as
Bookmark 0 Alt+Shift+0
Bookmark 1 Alt+Shift+1
Bookmark 2 Alt+Shift+2
Bookmark 3 Alt+Shift+3
Bookmark 4 Alt+Shift+4
Bookmark 5 Alt+Shift+5
Bookmark 6 Alt+Shift+6
Bookmark 7 Alt+Shift+7
Bookmark 8 Alt+Shift+8
Bookmark 9 Alt+Shift+9
- Alt+0
- Alt+1
- Alt+2
- Alt+3
- Alt+4
- Alt+5
- Alt+6
- Alt+7
- Alt+8
- Alt+9
Tools
Options...
Benchmark
Help
Contents... F1
About 7-Zip...

How to reset a FileBrowse or set a FileBrowse to a given path in PySimpleGUI?

I am using PySimpleGUI. I have the following snippet:
import PySimpleGUI as sg
layout = [[sg.Text('File', size=(4, 1)), sg.Input(key="-FILE-", default_text="browse!", size=(128, 2)), sg.FileBrowse()],
[sg.Button("Select file", key="-SELECT_FILE-"), sg.Button("Cancel", key="-SELECT_CANCEL-")]]
window = sg.Window('test reset browse', layout)
while True:
event, values = window.read()
if event == "-SELECT_CANCEL-":
window.FindElement("-FILE-").Update("cancel!")
# I want to reset also the FileBrowse initial path
if event == sg.WIN_CLOSED:
break
Any idea on how to reset / set to a given path the FileBrowse when canceling (comment line)?
Or formulated another way:
given that browse has been used to select a path
given that the cancel button is pressed
how to either:
reset the path to the initial path that was proposed the very first time the browsing was started
OR
how to set by hand the new initial path for the next browsing
?
There is a way to do this, as per this github issue answer from the creator of PySimpleGUI themself.
It turns out, if we add a key to your sg.FileBrowse object like so:
sg.FileBrowse(key="-FILEBROWSE-",)
then one may simply write
window["-FILEBROWSE-"].InitialFolder = r"C:\\"
obviously replacing the string with whatever path is desired. This, for example, will set the initial folder to the C drive.
See your full code with my changes:
layout = [
[
sg.Text('File', size=(4, 1)),
sg.Input(key="-FILE-", default_text="browse!", size=(128, 2)),
sg.FileBrowse(key="-FILEBROWSE-",) # Add key here
],
[
sg.Button("Select file", key="-SELECT_FILE-"),
sg.Button("Cancel", key="-SELECT_CANCEL-")
]
]
window = sg.Window('test reset browse', layout)
while True:
event, values = window.read()
if event == "-SELECT_CANCEL-":
window.FindElement("-FILE-").Update("cancel!")
# I want to reset also the FileBrowse initial path
# Set initial folder here
window["-FILEBROWSE-"].InitialFolder = r"C:\\"
if event == sg.WIN_CLOSED:
break
Here are the default values of Sg.FileBrowse. As you can see there is an initial_folder option you can use. I'd suggest you use this.
def FileBrowse(button_text='Browse', target=(ThisRow, -1), file_types=(("ALL Files", "*.*"),), initial_folder=None,
tooltip=None, size=(None, None), auto_size_button=None, button_color=None, change_submits=False,
enable_events=False, font=None, disabled=False,
pad=None, key=None, metadata=None):

How to access popup menu from hidden system tray icon

I use following code to access hidden icon and to show its popup menu and to click on "Sign Off" menuitem:
import time
from pywinauto.application import Application
app = Application(backend="uia").connect(path="explorer.exe")
st = app.window(class_name="Shell_TrayWnd")
t = st.child_window(title="Notification Chevron").wrapper_object()
t.click()
time.sleep(0.25)
list_box = Application(backend="uia").connect(class_name="NotifyIconOverflowWindow")
list_box_win = list_box.window(class_name="NotifyIconOverflowWindow")
list_box_win.wait('visible', timeout=30, retry_interval=3)
list_box_win.child_window(title="Citrix Workspace").click_input(button='right').menu_item('Sign Out').click_input()
Popup menu is shown, but I got error: AttributeError: 'NoneType' object has no attribute 'menu_item'
When I tried to add this code (instead of .menu_item('Sign Out').click_input()) :
connector = Application()
connector.connect(path="C:\\Program Files (x86)\\Citrix\\ICA Client\\SelfServicePlugin\\SelfService.exe")
connector.PopupMenu.MenuItem("Sign Out").ClickInput()
path is reflecting application that responsible for icon in system tray.
I got error: MatchError: Could not find 'PopupMenu' in 'dict_keys([])'. So I can I access menuitem in popup window?
BTW: It is run on windows 10 64 bit with python 3.6.
Unpolished/optimized (but working) code looks like this:
import pywinauto.application
import time
taskbar = pywinauto.application.Application(backend="uia").connect(path="explorer.exe")
windows_tray = taskbar.window(class_name="Shell_TrayWnd")
tray = windows_tray.child_window(title="Notification Chevron").wrapper_object()
tray.click()
time.sleep(1)
app_list_box = pywinauto.application.Application(backend="uia").connect(class_name="NotifyIconOverflowWindow")
app_list_box_win = app_list_box.window(class_name="NotifyIconOverflowWindow")
target_app = app_list_box_win.child_window(title = "Citrix Workspace")
target_app.click_input(button = "right")
citrix = pywinauto.application.Application().connect(path='Receiver.exe')
sign = citrix.PopupMenu.menu().get_menu_path("Sign In...")[0]
sign.click_input()
Where 'Receiver.exe' is executable of application running in system tray and "Citrix Workspace" title of of it.

Error using checkmouse

I'm trying to use checkmouse in order to undraw something from my window. When someone clicks the button it should undraw the text and write something else. I'm using checkMouse and getX() and getY() to do this but i keep receiving this error that states:
File "C:\Users\User\Documents\python\project2.py", line 71, in panel
if (clicknew.getX()>90 and clicknew.getX()<210) and (clicknew.getY()>35 and clicknew.getY() < 0):
AttributeError: 'NoneType' object has no attribute 'getX'
this code that i have done so far is as follows:
from graphics import *
#creating the game panel window
def panel():
#grey window, with coordinates flipped, with banners etc
win = GraphWin("Start Panel", 300,200)
win.setCoords(0,0,300,200)
win.setBackground("light grey")
#drawing the BoilerMazer banner with text
boilermazer = Rectangle(Point(0,200),Point(300,160))
boilermazer.setFill("white")
boilermazer.draw(win)
#text inside
banner1 = Text(Point(150,180),"BoilerMazer")
banner1.setStyle("bold")
banner1.setSize(20)
banner1.draw(win)
#initial game panel is going to have two buttons and a top scores object
#top score "screen"
toprec = Rectangle(Point(60,140),Point(240,50))
toprec.setFill("white")
toprec.draw(win)
#text inside toprec
topscores = Text(Point(150,130),"TOP SCORES")
topscores.setSize(8)
topscores.draw(win)
border = Text(Point(150,120),"======")
border.draw(win)
bigmac = Text(Point(150,110),"Big Mac 21")
bigmac.setSize(8)
bigmac.draw(win)
tt = Text(Point(150,90),"T.T 23")
tt.setSize(8)
tt.draw(win)
cshell = Text(Point(150,75),"C-Shell 25")
cshell.setSize(8)
cshell.draw(win)
macmac = Text(Point(150,55),"MacMac 27")
macmac.setSize(8)
macmac.draw(win)
#new player button that will eventually be clicked
new1 = Point(90,35)
new2 = Point(210,0)
newrec = Rectangle(new1,new2)
newrec.setFill("chartreuse2")
newrec.draw(win)
#new player button text
newplayer = Text(Point(150,18),"NEW PLAYER")
newplayer.draw(win)
#reset button
resetrec = Rectangle(Point(240,35),Point(300,0))
resetrec.setFill("red")
resetrec.draw(win)
#resettext
reset = Text(Point(270,18),"RESET")
reset.draw(win)
#secondary panel window is the game panel after they click new player
#set up points that we check between for the new player button first
#setting up the checkmouse
clicknew = win.checkMouse()
if (clicknew.getX()>90 and clicknew.getX()<210) and (clicknew.getY()>35 and clicknew.getY() < 0):
newplayer.undraw()
you can find the graphics window here:http://mcsp.wartburg.edu/zelle/python/graphics.py
I don't understand what I'm doing wrong, is there some other method that I'm supposed to be using? Thanks for your help
According to the docs, checkMouse() returns None if no mouse click has been detected priorly. So that seems to be the case.
You could put a loop around the call to checkMouse and keep checking if clicknew is not None and only in that case go on in your program. But maybe there's a better way...
UPDATE:
Example:
while True:
clicknew = win.getMouse()
if clicknew:
break
else:
time.sleep(0.1) # avoid busy waiting
# clicknew is set now => use it

Pyqt4 MDI no clean mdiarea

I am new to PyQt, I am developing an application like MDI, I use the QDesigner to build the forms (I come from Visual Basic), so far so good, but it is costing me horrors to run the application well, when I close a window, erase everything, but the frame remains on the mdi-area, click on the x and close. I attach the code.
With this I knock at the window:
def ordentrabajo(self):
self.cot = FichaOrdenTrabajo()
subwindow = QtGui.QMdiSubWindow()
self.cot.mdiarea = self.ventana.mdiArea
subwindow.setWidget(self.cot)
subwindow.setGeometry(0, 0, 595, 490)
self.ventana.mdiArea.addSubWindow(subwindow)
subwindow.showventana = self.cot.show()
And within the FichaOrdenTrabajo I close with:
def closeEvent(self, QCloseEvent):
self.emit(QtCore.SIGNAL('cerrar'))
general.saveposic('ctrlordentrabajo', self.x(), self.y())
self.subwindow.close = self.cdeta.close()
self.cdeta.hide()
# del self.subwindow
self.subwindow = None
leaving the main window in this state:
The question is how to do so that when closing the mdi-area is clean?
Thank you

Resources