File dialog in Mac to find app - python

I have some Python code which works well in Windows and Ubuntu Linux, but has a problem on Mac.
What I am doing is presenting a user (within my app) the ability to choose an application he wants opened whenever he presses a button on my app (so that he can invoke without having to search for it every time)
The setup code goes like this (simplified):
self.app_opt = options = {}
options['title'] = 'Please choose an app from your computer'
options['initialdir'] = '~/'
chosen_app = "~/"
chosen_app = askopenfilename(parent = self.parent, **self.app_opt)
self.chosen_app = chosen_app
Later on, the button is pressed and the code in the button looks like this:
subprocess.Popen(self.chosen_app)
As I said, it works fine in Windows (I go over to "Program Files", select an executable and all is fine), it runs when I push the button. Also in Ubuntu - (I select from say /usr/bin) and app runs fine when I push the button.
Tried to do this in Mac - just as an example we would like to open iTunes when pressing the button - Now the real app to run iTunes is found at e.g.
/Applications/iTunes.app/Contents/MacOS/iTunes
But I can't select deeper than
/Applications/iTunes.app
Is there some option/setting I need to put in the file dialog to make this work?

After asking a friend (thanks DJ!) It seems I was going about this the wrong way
In Mac I should not be calling
subprocess.Popen(self.chosen_app)
but something more like
subprocess.Popen('open -a \"' + self.chosen_app + '\"')
as explained here
Will report back on how this works

Related

PyQT5 QFileDialog window title not showing on mac

I made a PyQt5 application on Windows and now I want to use the application on a Mac. The app prompts the user to select a couple different files. I used the title of the QFileDialog window to let the user know which files like so:
instrument_file_raw=QFileDialog().getOpenFileName(self, "Select Instrument File","","Excel (*.xlsx)")
instrument_file_raw=str(instrument_file_raw[0])
if instrument_file_raw=="":
error_dialog = QErrorMessage(self)
error_dialog.showMessage('No filename entered')
return
run_list_file=QFileDialog().getOpenFileName(self, "Select Run List File","","Excel (*.xlsx)")
run_list_file=str(run_list_file[0])
if run_list_file=="":
error_dialog = QErrorMessage(self)
error_dialog.showMessage('No filename entered')
return
However when I run the same code on Mac there is no window title shown when the file explorer opens. Even if I manually set the window title by
instrument_file_window=QFileDialog()
instrument_file_window.setWindowTitle("Select Instrument File")
instrument_file_raw=instrument_file_window.getOpenFileName(self,"Select Instrument File","","Excel (*.xlsx)")
Is there a way to show the window title on Mac? How can I indicate to the user what to input?
This is a known problem that has not been fixed yet (see QTBUG-59805) and related to a change to macOS starting from version 10.11 (El Capitan).
If you do need to display the caption, the only solution is to use the non native file dialog option.
path, filter = QtWidgets.QFileDialog.getOpenFileName(
self, "Select Instrument File", "", "Excel (*.xlsx)",
options=QtWidgets.QFileDialog.DontUseNativeDialog
)
Note that getOpenFileName, like other similar functions, is a static function: it constructs and configure a new file dialog instance and then returns it. In fact, if you closely look at my code above, I didn't use any parentheses after QFileDialog.
Besides the options in the arguments, there's no way to access the created dialog if it's native, and there is only limited access for non native dialogs, but only by using complex systems (like a timer that checks for the top level widget) which are also not always reliable.
The above also means that:
you don't need to create a new instance, since it won't be used;
for the same reason, setting any property (like the window title) has absolutely no effect;

How to clear pycharm output terminal with code? [duplicate]

Is there a way to clear the "Run" console in PyCharm?
I want a code that delete/hide all the print() made previously.
Like the "clear_all" button, but without having to press it manually.
I have read that there is a way to do it in a terminal with os.system("cls"), but in PyCharm, it only adds a small square without clearing anything.
Also, I don't want to use print("\n" *100) since I don't want to be able to scroll back and see the previous prints.
In Pycharm:
CMD + , (or Pycharm preferences);
Search: "clear all";
Double click -> Add keyboard shortcut (set it to CTRL + L or anything)
Enjoy this new hot key in your Pycharm console!
Pycharm Community Edition 2020.1.3
You can right click anywhere above the current line on the console, and choose the "Clear All" option. It'll clear the console
How to
Download this package https://github.com/asweigart/pyautogui. It allows python to send key strokes.
You may have to install some other packages first
If you are installing PyAutoGUI from PyPI using pip:
Windows has no dependencies. The Win32 extensions do not need to be
installed.
OS X needs the pyobjc-core and pyobjc module installed (in that
order).
Linux needs the python3-xlib (or python-xlib for Python 2) module
installed.
Pillow needs to be installed, and on Linux you may need to install additional libraries to make sure Pillow's PNG/JPEG works correctly. See:
Set a keyboard shortcut for clearing the run window in pycharm as explained by Taylan Aydinli
CMD + , (or Pycharm preferences);
Search: "clear all"; Double click ->
Add keyboard shortcut (set it to CTRL + L or anything)
Enjoy this new hot key in your Pycharm console!
Then if you set the keyboard shortcut for 'clear all' to Command + L use this in your python script
import pyautogui
pyautogui.hotkey('command', 'l')
Example program
This will clear the screen after the user types an input.
If you aren't focused on the tool window then your clear hot-key won't work, you can see this for yourself if you try pressing your hot-key while focused on, say, the editor, you won't clear the embedded terminals contents.
PyAutoGUI has no way of focusing on windows directly, to solve this you can try to find the coordinate where the run terminal is located and then send a left click to focus, if you don't already know the coordinates where you can click your mouse you can find it out with the following code:
import pyautogui
from time import sleep
sleep(2)
print(pyautogui.position())
An example of output:
(2799, 575)
and now the actual code:
import pyautogui
while True:
input_1 = input("?")
print(input_1)
pyautogui.click(x=2799, y=575)
pyautogui.hotkey('command', 'l')
Easy Method:
Shortcut: Control K,
Right click on terminal and clear Buffer
There's also another way of doing it using the system class from os. All you need to do is have this code:
from os import system, name
# define our clear function
def clear():
# for windows the name is 'nt'
if name == 'nt':
_ = system('cls')
# and for mac and linux, the os.name is 'posix'
else:
_ = system('clear')
# Then, whenever you want to clear the screen, just use this clear function as:
clear()
However, in order for this functionality to work in pycharm, you need to enable "Emulate terminal in output console". You can find this under edit configuration of the file where you want to use the clear function, then it's under Execution option. Here's a screenshot: pycharm screensho
You could just do a ("\n" * 100000000), so it'll be impossible to scroll back.
In PyCharm terminal you can type 'cls' just like in linux terminal.
For Python Console (where you see the output) assign a shortkey for "clear all" in File -> Settings -> Keymap -> Other -> "Clear all"
You can also click somewhere on the PythonConsole -> Right button -> clear.
Hope it helps
I just relised that instead of going to the trouble of setting up a shortcut, you could just set up a command using PyAutoGUI to click on the trash bin on the side of the window e.g
note, to install pyautogui click on the end of the import pyautogui line, then press alt+enter and click install pyautogui.
import pyautogui
# to find the coordinates of the bin...
from time import sleep
sleep(2) # hover your mouse over bin in this time
mousepos = pyautogui.position() gets current pos of mouse
x,y = mousepos # storing mouse position
print(mousepos) # prints current pos of mouse
# then to clear it;
pyautogui.click(x, y) # and just put this line of code wherever you want to clear it
(this isn't perfect thanks to the time it takes to run the code and using the mouse, but it is reasonable solution depending on what you are using it for.)
I hope this answer is helpful even though this is an old question.
Just click the trash can icon to the left of the command window and it clears the command history!
In PyCharm 2019.3.3 you can right click and select "Clear All" button.This is deleting all written data inside of the console and unfortunately this is manual.
Sorry to say this, here the main question is how to do it programmatically means while my code is running I want my code to clear previous data and at some stage and then continue running the code. It should work like reset button.
After spending some time on research I solved my problem using Mahak Khurmi's solution https://stackoverflow.com/a/67543234/16878188.
If you edit the run configuration you can enable "emulate terminal in output console" and you can use the os.system("cls") line and it will work normally.
Iconman had the easiest answer.
But simply printing "\n" * 20 (or whatever your terminal height is) will clear the screen, and the only difference is that the cursor is at the bottom.
I came here because I wanted to visually see how long each step of a complex process was taking (I'm implementing a progress bar), and the terminal is already full of scrolling logging information.
I ended up printing ("A" * 40) * 20, and then "B" and "C" etc., and then filming it. Reviewing the video made it easy to see how many seconds each step took. Yes I know I could use time-stamps, but this was fun!

pywinauto with a popup window

Im working through pywinauto, not a great developer but I can write some of the basics in python. Im getting hung up though. I have a popup that is causing me to not be able to press ok on and really not sure what direction I need to look
Really a two part question:
How can I move over to this popup IF it occurs, this wont always be the case as sometimes those files may not exist.
I tried using app.Confirm.Ok.click() and also app.Confirm.type('{ENTER}') neither worked.
How can I add in variables that I could call from an external .txt file for things like the "localhost" I included there in my code?
Code here:
from pywinauto import application
import time
app = application.Application()
app.start("Install.exe")
app.SelectLanguage.Ok.click()
app.Platform.Iacceptthetermsinthelicenseagreement.click()
app.Platform.Next.click()
app.Platform.Next.click()
app.PlatformInstallationOptions.Next.click()
app.PlatformSpecifyCertifcate.comboBox.select(0)
app.PlatformSpecifyCertifcate.Next.click()
app.PlatformConfigurationDatabaseOptions.type_keys('{TAB}')
app.PlatformConfigurationDatabaseOptions.type_keys('{TAB}')
app.PlatformConfigurationDatabaseOptions.type_keys('localhost')
app.PlatformConfigurationDatabaseOptions.type_keys('{TAB}')
app.PlatformConfigurationDatabaseOptions.type_keys('{SPACE}')
app.PlatformConfigurationDatabaseOptions.type_keys('{TAB}')
app.PlatformConfigurationDatabaseOptions.type_keys('Config')
app.PlatformConfigurationDatabaseOptions.Next.click()
app.PlatformSpecifyHTTPSBindingCertifcate.type_keys('{TAB}')
app.PlatformSpecifyHTTPSBindingCertifcate.type_keys('{TAB}')
app.PlatformSpecifyHTTPSBindingCertifcate.type_keys('{RIGHT}')
app.PlatformSpecifyHTTPSBindingCertifcate.type_keys('{SPACE}')
app.PlatformSpecifyHTTPSBindingCertifcate.Next.click()
app.PlatformAdvancedWorkflowSettings.Next.click()
app.PlatformPlatformLanguage.Next.click()
app.PlatformInstanceDatabaseOptions.type_keys('{TAB}')
app.PlatformInstanceDatabaseOptions.type_keys('{TAB}')
app.PlatformInstanceDatabaseOptions.type_keys('localhost')
app.PlatformInstanceDatabaseOptions.type_keys('{TAB}')
app.PlatformInstanceDatabaseOptions.type_keys('{SPACE}')
app.PlatformInstanceDatabaseOptions.type_keys('{TAB}')
app.PlatformInstanceDatabaseOptions.type_keys('Instance')
app.PlatformInstanceDatabaseOptions.Next.click()
app.PlatformTimeZone.Next.click()
app.WebApplicationOptions.type_keys('{TAB}')
app.WebApplicationOptions.type_keys('{TAB}')
app.WebApplicationOptions.type_keys('{TAB}')
app.WebApplicationOptions.type_keys('{TAB}')
app.WebApplicationOptions.type_keys('{UP}')
app.WebApplicationOptions.Next.click()
app.WebApplicationOptions.type_keys('{ENTER}')
confirmWin = .app.window(title_re = u'Confirm') #Check your window header object name.
# Use timeout based on average pop up time in your application.
if confirmWin.exists(timeout=10, retry_interval=1):
confirmWin.set_focus()
yesBtn = confirmWin[u'&Yes']
# Check the object name of the Yes button. You can use Swapy tool(It is deprecated but it works, else you can use inspect.exe)
yesBtn.click()
else:
print('Confirmation pop up did not appear')
This should work :)

GUI automation using pywinauto python. Attribute error , menu_select() missing error in uaicontrols.py

I'm tring to automate a windows gui mouse click of a check box in properties of a printer.
I get to this by starting print management mmc, right clicking on "G23XnQ2E (local)" from "Print Servers" drop down in the left pane and selecting properties, switching to "security tab" and i finally want to select the checkbox against manage printer option. This can also be achieved by directly clicking on the action menu and selecting properties, provided that i have selected "G23XnQ2E (local)" from the printer servers.
I have tried all the possible ways that I can thing of but always end up getting the many errors like "raise AttributeError", "menu_select", "select()", "click()" - "missing".
my code is like say:
from pywinauto import Application
Application().start(r'mmc printmanagement.msc')
app = Application(backend="uia").connect(path='mmc.exe')
app.PrintManagement.dump_tree()
app.dialog.pane1.pane5.pane6.menu.menu_select("Action -> Properties")
#app.dialog.menu_select("Action -> Properties")
#app.dialog.pane1.pane5.pane6.menu.ActionMentuitem.select()
#app.dialog.pane1.pane5.pane6.menu.ActionMentuitem.click()
How to fix the problem?
menu_select is good for main menu like "File->Open". It doesn't work for popup/context menus. This is my code working on my PC (name of print server has been changed to yours):
from pywinauto import Application
Application().start(r'mmc printmanagement.msc')
app = Application(backend="uia").connect(path='mmc.exe')
#app.PrintManagement.dump_tree()
print_servers = app.PrintManagement.child_window(title="Print Servers", control_type="TreeItem")
print_servers.select() # it expands the subtree
# call popup menu
print_servers.child_window(title="G23XZNQ2E (local)", control_type="TreeItem").right_click_input()
# alternative way to call popup menu
#print_servers.child_window(title_re=".*\(local\)$", control_type="TreeItem").right_click_input()
# select "Properties..." menu item
app.ContextMenu.child_window(title="Properties...", control_type="MenuItem").select()
#app.PrintManagement.Print_Server_Properties.dump_tree()
app.PrintManagement.Print_Server_Properties.TabControl.select('Security')
app.PrintManagement.Print_Server_Properties.child_window(title="Allow Manage Printers", control_type="CheckBox").toggle()
All child_window specifications have been copied from dump_tree() outputs. Some windows are children of main window, but context menu is a top level one. This is not a documented experience, but we're working on a recorder feature planned this year as Beta. So it will be much easier to generate a script without thinking about hierarchy structure so much.

wxPython DirDialog does not scroll to selected folder

I'm using wxPython DirDialog and it seems to have a bug.
When launching the dialog I specify a default path (defaultPath).
That path is being selected by the dialog but the dialog is not scrolled to the selected path.
Instead the dialog is scrolled to the top of the dialog.
This leaves the user to scroll A LOT down to reach the default path.
Very inconvenient.
Any way to correct this?
Using:
Python 2.6.5
wxPython 2.8.12.1
Windows 8.1
It may not be any consolation but with Python 2.7.12 Wx '3.0.2.0 gtk2 (classic)' on Linux, the following works as it should. Check if you are doing something different.
def OnSelect_dir(self,event):
dialog = wx.DirDialog (None,defaultPath=self.client_dir.GetValue(), message = 'Pick a directory.' )
if dialog.ShowModal() == wx.ID_OK:
self.client_dir.SetValue(dialog.GetPath())
else:
pass
dialog.Destroy()
It works is I hard code defaultPath='/home/rolf' as well.
Well apparently if I exclude the style "wx.DD_DEFAULT_STYLE" then it works just fine.
So this works:
style = wx.DD_DIR_MUST_EXIST
But this doesn't focus the dialog properly on the defaultPath:
style = wx.DD_DEFAULT_STYLE | wx.DD_DIR_MUST_EXIST
I guess it must be a bug somewhere

Categories

Resources