Displaying icon in mac statusbar with python - python

I have a script that just returns true/false depending on some conditions, and I need to display this status in the status bar/some topmost window, the script is written in python.
I tried to find a way to display a status bar icon with python but seems all existing wrappers are outdated. I feel that it is not very good solution to create a native app just for displaying an icon and control it with my script.
I thought about using GeekTool for mac, but it can display stuff only on the desktop. Since the desktop is hidden with some windows all the time, that's not very good solution.
Any ideas?

Have found out that
import objc, from Foundation import *
from AppKit import *
from PyObjCTools import AppHelper
solves my problem

Related

Is it possible to close a window in macOS with Python?

Actually, I wanna do some automated operations on macOS, like closing a specific window.
I have read some threads, and I got know about Appkit and Quartz from How can I minimize/maximize windows in macOS with the Cocoa API from a Python script?.
Here below is my current progress:
import AppKit
for app in AppKit.NSWorkspace.sharedWorkspace().runningApplications():
if app.localizedName() == 'Google Chrome':
app.hide()
With AppKit, I can hide a specific application successfully. But there are two issues for me with this method: first, it seems that AppKit can only manage Applications, but not Windows (i.e., the above code hides all Google Chrome windows at once); besides, AppKit seems to be only able to Hide an application, but not Quitting it or Closing it.
I also tried Quartz. With the below code, I can successfully find the specific windows that I wanna control, especially with the characteristic kCGWindowNumber. But I would like to ask, is there any module that can allow me to close (or hide) the window, maybe like with the kCGWindowNumber?
import Quartz
for window in Quartz.CGWindowListCopyWindowInfo(Quartz.kCGWindowListOptionOnScreenOnly, Quartz.kCGNullWindowID):
if window['kCGWindowOwnerName'] == "Google Chrome" and window['kCGWindowLayer'] == 0:
print(window)

Automate clicks in WPF window from external script

Is it possible to create a script in Python or IronPython that automatically clicks on some widgets of an open WPF (C#) window? It would be a task that would solve my life but I have no idea where to start.
Thanks in advance.
Autoit, pyautogui, pywinauto and clicknium, all these libraries support automating WPF applications.
You may need to use tools like uispy and inspect to help you locate the control if you are using pyautogui and pywinauto.
Sample code for pywinauto looks like below:
from pywinauto.application import Application
app = Application(backend='uia').start("notepad.exe")
main = app.window(title='*Untitled - Notepad', control_type='Window')
closeBtn=main.child_window(title="Close", control_type='Button')
closeBtn.click_input()
You can install clicknium vscode extension to help you locate the control if you are using clicknium.
Sample code looks like below:
from clicknium import locator, ui
ui(locator.notepad.button_close).click()
Quick Google search revealed the following tutorial:
https://www.geeksforgeeks.org/mouse-keyboard-automation-using-python/
If you are dead set on using python or any code for that matter, a simple macro recorder may give you more faster:
https://www.macrorecorder.com/
This does not account for any deviation in the application or OS. If another popup or window is open, the script/macro will just continue happily. If you are after UI testing, you may want to look at professional UI test tools.
you can see this example, demonstrate one automation case for both desktop application and web application.

Window contents not loaded when opening from another window PyQt5 (2 classes in one .py) [duplicate]

I'm working with PyQt (as a Python beginner).
I need to be able to take screenshots of a website on a headless system.
I was using PhantomJS earlier for another project, but they dropped Flash support in 1.5 and I don't want to rely on a deprecated 1.4 version for my new project.
So I'm using PyQt to do my stuff on my own.
I'm able to take a screenshot of a website with a given url, no problem.
But I keep having the "blue dice" flash plugin icon on flash placeholder (yes, javascript and plugins are activated)
self.settings.setAttribute(QtWebKit.QWebSettings.PluginsEnabled,True)
self.settings.setAttribute(QtWebKit.QWebSettings.JavascriptEnabled,True)
I'm making some test on a Youtube video page, here is an example of my issues:
The second part, that may be related to the first one:
How can I tell PyQt to wait few seconds before taking the screenshot ?
As you can see on the example, images on the right are still unloaded, because they are loaded using javascript and data attribute and in my script, I take the screenshot on the loadFinished signal (onLoad() javascript equivalent)).
My first guess was simply to
time.sleep(2)
Before calling my capture method, but it's not working. I'm assuming that the Webkit loading is also asleep during this sleep time, preventing anything to load on the page.
I tried to create a custom signal, but then I still don't know how to trigger it without sleeping.
My last guess is that I need to thread my application. Am I right?
If you have any hint/script to help me displaying flash content and/or to add a setTimeout like signal, I would be really grateful!
Thanks in advance for you help.
EDIT:
Just a quick edit to add my solution:
timeoutTimer = QTimer()
timeoutTimer.setInterval(3000) # wait for 3secs
timeoutTimer.setSingleShot(True)
timeoutTimer.timeout.connect(theMethodToCallOnTimeout)
About the flash thing: it looks like the flash player is broken on OSX (maybe related to a 32/64 bits issue).
If you time.sleep you are freezing the whole application, instead, you can use a QTimer, QEventLoop, QThread, etc. Here is the PyQt4 version:
#!/usr/bin/env python
#-*- coding:utf-8 -*-
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from PyQt4.QtWebKit import *
class browser(QWebView):
def __init__(self, parent=None):
super(browser, self).__init__(parent)
self.timerScreen = QTimer()
self.timerScreen.setInterval(2000)
self.timerScreen.setSingleShot(True)
self.timerScreen.timeout.connect(self.takeScreenshot)
self.loadFinished.connect(self.timerScreen.start)
self.load(QUrl("http://www.google.com/ncr"))
def takeScreenshot(self):
image = QImage(self.page().mainFrame().contentsSize(), QImage.Format_ARGB32)
painter = QPainter(image)
self.page().mainFrame().render(painter)
painter.end()
image.save(self.title() + ".png")
sys.exit()
if __name__ == "__main__":
import sys
app = QApplication(sys.argv)
main = browser()
app.exec_()
I recommend using selenium. It is made for doing web automation, screenshots, and testing. Because it uses firefox it is very easy to have full flash support. It can also be run in a headless mode. The code below works at taking a screenshot of a web page with flash like the youtube video you had. You can see the screenshot it took below. A few things to keep in mind. selenium has a save_screenshot method which you can see is commented out in the code. I didn't use it because it wasn't taking proper screenshot of flash components, you can correct this by using the technique in Taking screenshot of flash object using Selenium with Webdriver. I chose though to just take a screenshot of the screen using the imagemagic import command. This is a screenshot tool that works in Linux. You can check out Take a screenshot via a python script. [Linux] and Get screenshot on Windows with Python? for other approaches of taking screenshots.
code
import time, selenium.webdriver, subprocess
browser = selenium.webdriver.Firefox()
browser.get('http://www.youtube.com/watch?v=bFEoMO0pc7k')
time.sleep(6)
#browser.save_screenshot('test.png')
subprocess.check_output('import -window root screen.png', shell=True)
browser.quit()
screenshot

Cannot find .exe with Pywinauto's find_window(title="program.exe")

Does anyone know the trick to pywinauto's find_window function? I am building an application with kivy, and trying to use pywinauto to bring an .exe to the foreground, using the following code:
SetForegroundWindow(find_window(title='program.exe'))
I simply want to identify a currently open .exe, and bring it to the foreground. I have looked here https://pywinauto.github.io/docs/code/pywinauto.findwindows.html and it seems "title=" is what I want.
Does anyone know how to point to the .exe with pywinauto?
I think title is for window title (i.e. "python - Cannot find..." in case of this tab), are you sure it not more like "process='program.exe'" ?
if it needs to be and int then its pid (process id) and you can use this to get process id by title:
import win32gui,win32process
def get_window_pid(title):
hwnd = win32gui.FindWindow(None, title)
threadid,pid = win32process.GetWindowThreadProcessId(hwnd)
return pid
Eventually have at this answer as it contains really nice class for getting windows Python Window Activation, i dont want to copy paste, but use it and then you can do:
w = WindowMgr()
w.find_window_wildcard(".*Hello.*")
w.set_foreground()
find_window is low level function I wouldn’t recommend to use.
The right thing is Application object connected to the target process. It can be used so:
from pywinauto import Application
app = Application(backend=“uia”).connect(path=“program.exe”)
app.WindowTitle.set_focus()
If you have several app instances, there is a Desktop object to walk all the windows in the system:
from pywinauto import Desktop
Desktop(backend=“win32”).window(title=“Window Title”, found_index=0).set_focus()
You referred to the old docs for version 0.5.4, the latest one is 0.6.4 with two backends available and many bug fixes. The Getting Started Guide link on the main page is a good source to learn the main concept.

System theme icons and PyQt4

I'm writing a basic program in python using the PyQt4 module. I'd like to be able to use my system theme's icons for things like the preference dialog's icon, but i have no idea how to do this. So my question is, how do you get the location of an icon, but make sure it changes with the system's icon theme? If it matters, i'm developing this under ubuntu 9.04, so i am using the gnome desktop.
Unfortunately, It appears that Qt does not support getting icons for a specific theme. There are ways to do this for both KDE and Gnome.
The KDE way is quite elegant, which makes sense considering that Qt is KDE's toolkit. Instead of using the PyQt4.QtGui class QIcon, you instead use the PyKDE4.kdeui class KIcon. An example of this is:
from PyKDE4.kdeui import *
icon = KIcon("*The Icon Name*")
see the PyKDE documentation for this class, here.
One way to gain support for this for gnome is to use the python gtk package. It is not as nice as the kde way, but it works none the less. It can be used like this:
from PyQt4 import QtGui
from gtk import icon_theme_get_default
iconTheme = icon_theme_get_default()
iconInfo = iconTheme.lookup_icon("*The Icon Name*", *Int of the icon size*, 0)
icon = QtGui.QIcon(iconInfo.get_filename())
See the documentation for the Icon Theme class and Icon Info class.
EDIT: thanks for the correction CesarB
Use the PyKDE4 KIcon class:
http://api.kde.org/pykde-4.2-api/kdeui/KIcon.html
I spent a decent amount of researching this myself not long ago, and my conclusion was that, unfortunately, Qt doesn't provide this functionality in a cross-platform fashion. Ideally the QIcon class would have defaults for file open, save, '+', '-', preferences, etc, but considering it doesn't you'll have to grab the appropriate icon for your desktop environment.

Categories

Resources