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;
Related
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.
I am trying to implement a dialog box in a GUI, and would like to have the selected extension appended to the end of the typed in file name:
and I have come across these following threads:
tkinter: How can I get the users choice of filetype in the asksaveasfilename-dialog?
https://mail.python.org/pipermail/python-list/2002-June/173039.html
Which seems to imply that the asksaveasfilename tool from tkinter does not currently have this function.
Does anyone have a good solution for this? For example something similar to:
filename = asksaveasfilename(
filetypes=[('XLS File', '*.xls'), ('CSV File', '*.csv')],
appendExt=True)
or do I have to write my own just for this little missing function?
Note: This was working perfectly when I ran the code in Ubuntu, but unfortunately not in Windows 10.
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
I want to store a selected file's location as a string in Python. I am trying to use QFileDialog to accomplish this, I have:
self.filedialog = QtGui.QFileDialog(self)
self.filedialog.show()
filepath = str(self.filedialog.getOpenFileName())
This opens two QFileDialog windows. Interestingly, one of the windows does not inherit the 'style' of my GUI, set my setStyle, but does return the filepath string. The other QFileDialog does inherit the style, but can not return the filepath string. I have found the QFileDialog documentation helpful, but have not been able to create a QFileDialog box that both produces the filepath string, and inherits the style of my GUI. What mistake am I making?
You actually created 2 windows.
The function QFileDialog.getOpenFileName is static, meaning that it creates its own QFileDialog object, shows the window, waits for the user to select a file and returns the choosen filename.
You should only need that line:
filepath = str(QFileDialog.getOpenFileName())
If you set the style at the application level (with QApplication.setStyle), it might be applied to the window if you use the non-native dialog:
filepath = str(QFileDialog.getOpenFileName(options=QFileDialog.DontUseNativeDialog)))
getOpenFileName is a convenience function that "creates a modal file dialog". That's why you're getting the second dialog.
Use filedialog.exec() to show the dialog and fileDialog.selectedFiles() to get the filename.
exec is a reserved word in python, you must use exec_().
dialog = QFileDialog(self)
dialog.exec_()
for file in dialog.selectedFiles():
print file
self.button = gtk.Button(stock=gtk.STOCK_DELETE)
Only Shows:
Delete
The Python equivalent for setting the property without having to change any system config files is:
settings = gtk.settings_get_default()
settings.props.gtk_button_images = True
This should follow a call to window.show() and, obviously, precede the gtk.main() loop.
This is a recent change in GTK - the developers wanted icons not to appear on buttons. On Linux, this can be changed by editing the gconf key
/desktop/gnome/interface/buttons_have_icons
On windows, I think (I haven't actually tried this) that you need to set a value in your gtkrc file (for me it's in C:\Program Files\Gtk+\etc\gtkrc) and use a theme that supports icons (I think the default one doesn't).
You can also add gtk-button-images = 1 to your ~/.gtkrc-2.0 file after setting the theme which may over ride the option from gconf.
EDIT in answer to your comment:
Just like this answer, but in Python: In Gtk, how do I make a Button with just a stock icon?
For python, it's just
image = gtk.Image()
# (from http://www.pygtk.org/docs/pygtk/gtk-stock-items.html)
image.set_from_stock(gtk.STOCK_**)
button = gtk.Button()
button.set_image(image)
button.set_label("")
I had to do this to get it to work from Python without changing my config file. When I called set_image(), no image was being displayed.
image = gtk.Image()
image.set_from_stock(gtk.STOCK_**, gtk.ICON_SIZE_BUTTON)
button = gtk.Button()
button.add(image)
button.show()
If you work with pygobject, the new syntax is:
image.set_from_stock(gtk.STOCK_**, Gtk.IconSize.BUTTON)
I had the same issue in GTKmm on Windows. The "MS-Windows" theme disables images on stock buttons and the theme has priority over settings in gtkrc (so putting gtk-button-images = true in gtkrc didn't help). What I did is to modify the GTK settings runtime, and the images appeared as expected. :) Here's the code in C++:
Glib::RefPtr<Gtk::Settings> settings = Gtk::Settings::get_default();
/* force using icons on stock buttons: */
settings->property_gtk_button_images() = true;
It should be placed after the first window is constructed.
in Gtk3 gtk.STOCK method has been deprecated from v3.10.
Deprecated since version 3.10: Use Gtk.Button.new_with_label ()
instead.
In the case it doesn't help since it points to the custom label solution (new_with_label) If you want to use STOCK stuff you still can do so with new methods Gtk.Button.new_from_icon_name(icon_name, size) and Gtk.Button.new_with_mnemonic(label) which will create new buttons with stock icon and label respectively.
Example new button with a "stock" icon:
button = Gtk.Button.new_from_icon_name ("edit-paste", Gtk.IconSize.SMALL_TOOLBAR)
Example new button with a "stock" label:
button = Gtk.Button.new_with_mnemonic("_Open")
NOTE: on serious code creating a constant variable instead of using the string straight is a better option :)
References:
Gtk.Button
static new_with_mnemonic(label)
new_from_icon_name(icon_name, size)
Freedesktops Naming Convention
You can show explicitly the button image, justly, Gtk+ developers do not recommend doing this because it's overrides the Gtk+ user configuration.
So...
button.get_image().show()