How can I programmatically open the 'Proxies' tab in 'Network' dialog box?
System Preferences > Network > Advanced > Proxies
For those using Chrome, if you go to Menu > Settings > Show Advanced Settings > Change proxy settings... , the 'Network' box shows up, and its already on the 'Proxies' tab.
I want to achieve this using python.
The way to do this is through Apple Events. If you open AppleScript Editor, you can Open Dictionary on System Preferences and see the commands:
tell application "System Preferences"
reveal pane "com.apple.preference.network"
end tell
So, how do you do this from Python? There are three options:
Create some AppleScript and run it via PyObjC, or via a wrapper like py-applescript.
Use ScriptingBridge, Apple's AppleEvents-to-Python (and -Ruby and -ObjC) bridge.
Use appscript, a third-party AppleEvents-to-Python (and …) bridge.
Appscript is a lot better, but it's effectively an abandoned project, and ScriptingBridge comes with Apple's version of Python. So, I'll show that first:
import ScriptingBridge
sp = ScriptingBridge.SBApplication.applicationWithBundleIdentifier_('com.apple.SystemPreferences')
panes = sp.panes()
pane = panes.objectWithName_('com.apple.preference.network')
anchors = pane.anchors()
dummy_anchor = anchors.objectAtIndex_(0)
dummy_anchor.reveal()
You may notice that the ScriptingBridge version is a lot more verbose and annoying than the AppleScript. There are a few reasons for this.
ScriptingBridge isn't really an AppleEvent-Python bridge, it's an AppleEvent-ObjC bridge wrapped up in PyObjC, so you have to use horribleObjectiveCSyntax_withUnderscores_forEachParameterNamed_.
It's inherently horribly verbose.
The "obsolete" method of looking applications up by name isn't exposed in ScriptingBridge, so you have to find the bundle ID (or file:// URL) of the app and open that.
Most importantly, ScriptingBridge doesn't expose the actual object model; it forces it into a CocoaScripting OO-style model and exposes that. So, while System Preferences knows how to reveal anything, the ScriptingBridge wrapper only knows how to call the reveal method on an anchor object.
While the last two are the most troublesome, the first two can be annoying as well. For example, even using bundle IDs and following the CocoaScripting model, here's what the equivalent looks like in AppleScript:
tell application "com.apple.SystemPreferences"
reveal first anchor of pane "com.apple.preference.network"
end tell
… and in Python with appscript:
import appscript
sp = appscript.app('com.apple.SystemPreferences')
sp.panes['com.apple.preference.network'].anchors[1].reveal()
Meanwhile, in general, I wouldn't recommend any Python programmer move any of their logic into AppleScript, or try to write logic that crosses the boundaries (because I subscribe to the Geneva conventions against torture). So, I immediately start with ScriptingBridge or appscript in any case where we might need so much as an if statement. But in this case, as it turns out, we don't need that. So, using an AppleScript solution might be the best answer. Here's the code with py-applescript, or with nothing but what Apple gives you out of the box:
import applescript
scpt = 'tell app "System Preferences" to reveal pane "com.apple.preference.network"'
applescript.AppleScript(scpt).run()
import Foundation
scpt = 'tell app "System Preferences" to reveal pane "com.apple.preference.network"'
ascpt = Foundation.NSAppleScript.alloc()
ascpt.initWithSource_(scpt)
ascpt.executeAndReturnError_(None)
Related
Hello I'm once again looking for help. While trying to automate Audacity I came to a problem with what I could find being that it doesn't recognize the sub menu Audacity uses. Whenever I run this code:
app = Application(backend= 'uia').start(r'C:\Program Files (x86)\Audacity\audacity.exe')
app.Audacity.menu_select('File->Import')
app.Audacity.menu_select('Import->Audio... Ctrl+Shift+I')
It can't select the audio part (The whole submenu of Import is this way) but tries to find the nearest name to that, which apparently is somewhere in the transport menu. Also when I try to run print_control_identifiers() it doesn't show the submenu or any submenu in fact, even when trying to control the depth, it doesn't find the submenu.
you can use 'inspect.exe' to identify the control on your application, you can try UIA or MSAA to see which automation tech is feasible for the application.
or you can use other tools AccessBridgeExplorer or clicknium recorder to check whether the control can be recognized.
I want to retrieve information from a tooltip in the system tray programmatically.
The image shows the tooltip.
Now, I found that by using Microsoft's inspect.exe, which is "a Windows-based tool that enables you select any UI element and view the element's accessibility data", that it is in theory possible to retrieve this value programmatically.
Hovering over the the pandora icon in the toolbar shows me the following properties
It shows one property "name" that contains the exact data I need. I'm unsure how to retrieve this value programmatically using the win32api. I have a hwnd to the pandora icon already.
Additionally, a different ui spy tool, UiSpy.exe calls this same property "helpText" (different song name :p)
I tried using getWindowText(pandoraSystrayIconHwnd) but that returns a different text. Does anyone know what this "name" value is, and how I can retrieve it using the win32api? It should be possible because inspect.exe is an external program that can access the data somehow
I'm doing this in Python, as the target application is written in Python already.
These spy apps are probably using Active Accessibility and/or UI Automation.
You can try calling AccessibleObjectFromWindow on the toolbar HWND or AccessibleObjectFromPoint if you care about the mouse position and then call IAccessible::get_accName.
Keep in mind that the classname and window hierarchy of the tray icon toolbar is undocumented.
If you only care about Pandora and not other applications then I would strongly suggest that you look for other alternatives first. Perhaps they have a hidden window with the title etc.
If you don't mind hacks then you could take a look at TraySaver, it is open source and knows the internal format of the data stored for each icon in the tray toolbar. Keep in mind that it is pretty old and might not work on newer versions of Windows. If you go down this path (and I don't recommend it) then you have to remember that you need to support both 32-bit and 64-bit Explorer.
Maybe GUI automation library pywinauto could help you. It uses Win32 API or UI Automation under the hood (by your choice). Core concept is described in the Getting Started Guide.
Method .window_text() returns exactly the same as Name property shows in Inspect.exe.
To interact with tray area icons you can use this example on StackOverflow.
Does anyone have any ideas on how to use the Mac’s built-in dictation tool to create strings to be used by Python?
To launch a dictation, you have to double-press the Fn key inside any text editor. If this is the case, is there a way to combine the keystroke command with the input command? Something like:
Step 1: Simulate a keystroke to double-press the Fn key, launching the Dictation tool, and then
Step 2. Creating a variable by using the speech-to-text content as part of the input function, i.e. text_string = input(“Start dictation: “)
In this thread (Can I use OS X 10.8's speech recognition/dictation without a GUI?) a user suggests he figured it out with CGEventCreateKeyboardEvent(src, 0x3F, true), but there is no code.
Any ideas? Code samples would be appreciated.
UPDATE: Thanks to the suggestions below, I've imported AppScript. I'm trying the code to work along these lines, with no success:
from appscript import app, its
se = app('System Events')
proc = app.processes[its.frontmost == True]
mi = proc.menu_bars[1].menu_bar_items['Edit'].menus[1].menu_items['Start Dictation']
user_voice_text = input(mi.click())
print(user_voice_text)
Any ideas on how I can turn on the dictation tool to be input for a string?
UPDATE 2:
Here is a simple example of the program I'm trying to create:
Ideally i want to launch the program, and then have it ask me: "what is 1 + 1?"
Then I want the program to turn on the dictation tool, and I want the program to record my voice, with me answering "two".
The dictation-to-text function will then pass the string value = "two" to my program, and an if statement is then used to say back "correct" or "incorrect".
Im trying to pass commands to the program without ever typing on the keyboard.
First, FnFn dictation is a feature of the NSText (or maybe NSTextView?) Cocoa control. If you've got one of those, the dictated text gets inserted into that control. (It also uses that control's existing text for context.) From the point of view of the app using an NSTextView, if you just create a standard Edit menu, the Start Dictation item gets added to the end, with FnFn as a shortcut, and anything that gets dictated appears as input, just like input typed on a keyboard, or pasted or dragged with the mouse, or via any other input method.
So, if you don't have a GUI app, enabling dictation is going to be pointless, because you have no way to get the input.
If you do have a GUI app, the simplest thing to do is just get the menu item via NSMenu, and click the item.
You're almost certainly using some kind of GUI library, like PyQt or Tkinter, which has its own way of accessing your app's menu. But if not, you can do it directly through Cocoa (using PyObjC—which comes with Apple's pre-installed Python, but which you'll have to pip install if you're using a third-party Python):
import AppKit
mb = AppKit.NSApp.mainMenu()
edit = mb.itemWithTitle_('Edit').submenu()
sd = edit.indexOfItemWithTitle_('Start Dictation')
edit.performActionForItemAtIndex_(sd)
But if you're writing a console program that runs in the terminal (whether Terminal.app or an alternative like iTerm), the app you're running under has its own text widget and Edit menu, and you can parasitically use its menu instead.
The problem is that you don't have permission to just control other apps unless the user allows it. In older versions of OS X, this was done just by turning on "assistive scripting for accessibility" globally. As of 10.10, there's an Accessibility anchor in the Privacy tab of the Security & Privacy pane of System Preferences that has a list of apps that have permissions. Fortunately, if you're not on the list, the first time you try to use accessibility features, it'll pop up a dialog, and if the user clicks on it, it'll launch System Preferences, reveal that anchor, add your app to the list with the checkbox disabled, and scroll it into view, so all the user has to do is click the checkbox.
The AppleScript to do this is:
tell application "System Events"
click (menu item "Start Dictation" of menu of menu bar item "Edit"
of menu bar of (first process whose frontmost is true))
end tell
The "right" way to do the equivalent in Python is via ScriptingBridge, which you can access via PyObjC… but it's a lot easier to use the third-party library appscript:
from appscript import app, its
se = app('System Events')
proc = app.processes[its.frontmost == True]
mi = proc.menu_bars[1].menu_bar_items['Edit'].menus[1].menu_items['Start Dictation']
mi.click()
If you really want to send the Fn key twice, the APIs for generating and sending keyboard events are part of Quartz Events Services, which (even though it's a CoreFoundation C API, not a Cocoa ObjC API) is also wrapped by PyObjC. The documentation can be a bit tricky to understand, but basically, the idea is that you create an event of the appropriate type, then either post it to a specific application, an event tap, or a tap location. So, you can create and send a system-wide key-down Fn-key event like this:
evt = Quartz.CGEventCreateKeyboardEvent(None, 63, True)
Quartz.CGEventPost(Quartz.kCGSessionEventTap, evt)
To send a key-up event, just change that True to False.
I saw here a solution, but i don't want wait until the key is pressed. I want to get the last key pressed.
The related question may help you, as #S.Lott mentioned: Detect in python which keys are pressed
I am writting in, though to give yu advice: don't worry about that.
What kind of program are you trying to produce?
Programas running on a terminal usually don't have an interface in which getting "live" keystrokes is interesting. Not nowadays. For programs running in the terminal, you should worry about a usefull command line User Interfase, using the optparse or other modules.
For interative programs, you should use a GUI library and create a decent UI for your users, instead of reinventing the wheel.Which wouldb eb etter for what you ar trying to do? Theuser click on an icon,a window opens on the screen, witha couple of buttons on it, and half a dozen or so menu options packed under a "File" menu as all the otehr windws on the screen - or - a black terminal opens up, with an 80's looking text interface with some blue-highlighted menu options and so on?. You can use Tkinter for simple windowed applications, as it comes pre-installed with Python + Windows, so that yoru users don't have to worry about installign aditional libraries.
Rephrasing it just to be clear: Any program that requires a user interface should either se a GUI library, or have a WEB interface. It is a waste of your time, and that of your users, to try and create a UI operating over the terminal - we are not in 1989 any more.
If you absolutely need a text interface, you should look at the ncurses library then. Better than trying to reinvent the wheel.
http://code.activestate.com/recipes/134892/
i think it's what you need
ps ooops, i didn't see it's the same solution you rejected...why, btw?
edit:
do you know:
from msvcrt import getch
it works only in windows, however...
(and it is generalised in the above link)
from here: http://www.daniweb.com/forums/thread115282.html
I'm writing a simple OSX app using Python and PyObjC. I designed the settings dialog using Interface Builder and I use ibtool to compile it, then load it from Python. The problem is how to access the controls I have in this window from the Python code? I played around with iPhone development a bit before and I remember I need to have an IBOutlet in the controller class which will be connected to the UI control in the interface builder. It should look something like this in Python:
class MyClass(NSObject):
my_outlet = objc.IBOutlet('my_outlet')
But since I'm not working in XCode (all I have is a .py file and a .xib file), Interface Builder doesn't know about my outlets. How can I do the binding in this case? Or how else can I access the UI elements from the code?
First, the use of Xcode or not has nothing to do with NIB loading (beyond making it more convenient).
As Ole said, you can use IB to manually add the outlet's you need to file's owner or to the custom object instances that you have in the NIB file. By doing so, it will all "just work".
However, this statement is what prompted my relatively similar answer:
all I have is a .py file and a .xib
file
Are you trying to write a bit of UI code outside of a .app wrapper? If so, that is a wholly unsupported pattern, very difficult to get correct, and quite likely to break across software updates or major releases (as it has many times in the past).
The best way to solve your problem is to use an Xcode project and build a standard application. The templates are no longer shipped with the dev tools. Just download them separately.
If you need to run it from the command line, you can still do so.
I haven't tried this, but you can also define outlets directly in IB. Open the Library panel, select Classes in the segmented control at the top and select your custom class you want to define an outlet for. Let's say you have a NSWindow subclass called MyWindow. Select the NSWindow class in the list, click on the action button at the bottom left, select New Subclass... and name it MyWindow. Now switch to the Outlets tab and create a NSButton outlet for your window. Now you connect a button to the outlet.
I don't know how this will transfer to PyObjC but I'd love to see your results when you try it out.