PyQt - QFileDialog - directly browse to a folder? - python

Is there any way to directly browse to a folder using QFileDialog?
Meaning, instead of double clicking on each folder while navigating to the destination folder, simply enter the path somewhere or use a hotkey like the one (Shift+Command+G) in Finder on Mac OS X.
Thanks!
EDIT: (my code)
filter = "Wav File (*.wav)"
self._audio_file = QtGui.QFileDialog.getOpenFileName(self, "Audio File",
"/myfolder/folder", filter)
self._audio_file = str(self._audio_file)

If you use the static QFileDialog functions, you'll get a native file-dialog, and so you'll be limited to the functionality provided by the platform. You can consult the documentation for your platform to see if the functionality you want is available.
If it's not available, you'll have to settle for Qt's built-in file-dialog, and add your own features. For your specific use-case, this should be easy, because the built-in dialog already seems to have what you want. It has a side-bar that shows a list of "Places" that the user can navigate to directly. You can set your own places like this:
dialog = QtGui.QFileDialog(self, 'Audio Files', directory, filter)
dialog.setFileMode(QtGui.QFileDialog.DirectoryOnly)
dialog.setSidebarUrls([QtCore.QUrl.fromLocalFile(place)])
if dialog.exec_() == QtGui.QDialog.Accepted:
self._audio_file = dialog.selectedFiles()[0]

Here's a convenience function for quickly making an open/save QFileDialog.
from PyQt5.QtWidgets import QFileDialog, QDialog
from definitions import ROOT_DIR
from PyQt5 import QtCore
def FileDialog(directory='', forOpen=True, fmt='', isFolder=False):
options = QFileDialog.Options()
options |= QFileDialog.DontUseNativeDialog
options |= QFileDialog.DontUseCustomDirectoryIcons
dialog = QFileDialog()
dialog.setOptions(options)
dialog.setFilter(dialog.filter() | QtCore.QDir.Hidden)
# ARE WE TALKING ABOUT FILES OR FOLDERS
if isFolder:
dialog.setFileMode(QFileDialog.DirectoryOnly)
else:
dialog.setFileMode(QFileDialog.AnyFile)
# OPENING OR SAVING
dialog.setAcceptMode(QFileDialog.AcceptOpen) if forOpen else dialog.setAcceptMode(QFileDialog.AcceptSave)
# SET FORMAT, IF SPECIFIED
if fmt != '' and isFolder is False:
dialog.setDefaultSuffix(fmt)
dialog.setNameFilters([f'{fmt} (*.{fmt})'])
# SET THE STARTING DIRECTORY
if directory != '':
dialog.setDirectory(str(directory))
else:
dialog.setDirectory(str(ROOT_DIR))
if dialog.exec_() == QDialog.Accepted:
path = dialog.selectedFiles()[0] # returns a list
return path
else:
return ''

Use getExistingDirectory method instead:
from PyQt5.QtWidgets import QFileDialog
dialog = QFileDialog()
foo_dir = dialog.getExistingDirectory(self, 'Select an awesome directory')
print(foo_dir)

In PyQt 4, you're able to just add a QFileDialog to construct a window that has a path textfield embedded inside of the dialog. You can paste your path in here.
QtGui.QFileDialog.getOpenFileName(self, 'Select file') # For file.
For selecting a directory:
QtGui.QFileDialog.getExistingDirectory(self, 'Select directory')
Each will feature a path textfield:

Below you'll find a simple test which opens directly the dialog at a certain path, in this case will be the current working directory. If you want to open directly another path you can just use python's directory functions included in os.path module:
import sys
import os
from PyQt4 import QtGui
def test():
filename = QtGui.QFileDialog.getOpenFileName(
None, 'Test Dialog', os.getcwd(), 'All Files(*.*)')
def main():
app = QtGui.QApplication(sys.argv)
test()
sys.exit(app.exec_())
if __name__ == "__main__":
main()

Related

python pyqt5 add file name to getSaveFileName

I'm trying to add a default name to QFileDialog() the images below illustrate.
This is what I get (no filename)
and this is what I want to achieve without having to input it manually, I want to pass the file_name threw a function and have that name show up there.
This is the code im trying to make to work:
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5 import *
import sys
class mainwindowUI(QMainWindow):
def __init__(self):
super(mainwindowUI, self).__init__()
self.exportFiles('test.mp3')
def exportFiles(self,file_name):
filename, _ = QFileDialog.getSaveFileName(self, "Save audio file", "", "Audio Files (*.mp3)")
if filename:
print(filename)
if __name__ == '__main__':
app = QApplication(sys.argv)
window = mainwindowUI()
app.exec_()
I tried to add options:
filename, _ = QFileDialog.getSaveFileName(self, "Save audio file", "", "Audio Files (*.mp3)", options=QFileDialog.setLabelText(file_name))
But this is incorrect and i have no idea how to make it work...
Anyone know how to add a file name to save file dialog?
The third argument indicates the initial name:
def exportFiles(self, file_name):
default_dir ="/home/qt_user/Documents"
default_filename = os.path.join(default_dir, file_name)
filename, _ = QFileDialog.getSaveFileName(
self, "Save audio file", default_filename, "Audio Files (*.mp3)"
)
if filename:
print(filename)
First create a save-as action
self.saveas=QAction(QtGui.QIcon('saveas.png'),'save-as')
Add the save-as action to toolbar
toolbar=self.addToolbar('toolbar');
toolbar.addAction(self.saveas);
Sub this for your QFileDialog code
Fn, _=QFileDialog.getSaveFileName(self,'export pdf',file_name,'Pdf files(.pdf);;All files()');
when connecting the signal to the slot do this
Self.Saveas.toggled.connect(self.exportfiles('name of default file');

PyQt5 File open Dialog

is there any way to open a folder with pyqt5 file dialog
I tried taking the quotes, I want to open a folder or a directory with subdirectories or subfolders
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QFileDialog, QTextEdit, QPushButton, QLabel, QVBoxLayout
class MainWindow(QWidget):
def __init__(self):
super().__init__()
self.resize(800, 600)
self.button1 = QPushButton('Open Project Folder')
self.button1.clicked.connect(self.get_folder)
self.labelImage = QLabel()
self.textEditor = QTextEdit()
layout = QVBoxLayout()
layout.addWidget(self.button1)
layout.addWidget(self.labelImage)
layout.addWidget(self.button2)
layout.addWidget(self.textEditor)
self.setLayout(layout)
def get_folder(self):
file_name, _ = QFileDialog.getOpenFileName(
self, 'Project Data', r"", "")
print(file_name)
if __name__ == '__main__':
app = QApplication(sys.argv)
main = MainWindow()
main.show()
sys.exit(app.exec_())```
There are various static functions available for QFileDialog, if you need to open a directory, don't use getOpenFileName but getExistingDirectory().
As you can see from the documentation, the arguments are slightly different, and
if you run help(QtWidgets.QFileDialog.getExistingDirectory) from the python shell, you'll see the full argument signature and the returned value written in the python syntax.
getExistingDirectory(parent: QWidget = None, caption: str = '', directory: str = '', options: Union[QFileDialog.Options, QFileDialog.Option] = QFileDialog.ShowDirsOnly) -> str
The last part ( -> str) means that there is only one returned value, which is the string of the selected directory (which will be empty if the user cancels the dialog).
def get_folder(self):
folder = QFileDialog.getExistingDirectory(
self, 'Project Data', '')
if folder:
print(folder)
I suggest you to always study the documentation of each class you're using, and using the official documentation; even if it's C++ oriented, the functions have the same names on PyQt, and their arguments/returned values are the same in 99% of the cases. Whenever you've a doubt or you face a problem about wrong arguments or returned data, you can check the official PyQt documentation or just use help(class.function) in the python shell.

How to open another pyqt gui and retrieve value from it?

I am working on developing a file selection dialog using Python 3.6 and pyqt5. The basic idea of the dialog is that it has the option to preview files before selecting. It can preview any kinds of registered windows files. The design was done using QtDesigner MainWindow.
Now I can open this preview file browser from another pyqt/python3 file. But how can I retrieve the selected filename and file path from that script?
Here is the test file where I am opening the preview browser file:
class TestBrowser(QtWidgets.QMainWindow, design.Ui_MainWindow):
def __init__(self,browser):
super(self.__class__, self).__init__()
self.setupUi(self) # This is defined in design.py file automatically
# It sets up layout and widgets that are defined
self.browser=browser
self.pushButton.clicked.connect(self.dario)
def dario(self):
self.browser.exec_()
def main():
app = QApplication(sys.argv)
browser=bd.BrowserDialog()
main=TestBrowser(browser)
main.show()
sys.exit(app.exec_())
if __name__ == '__main__': # if we're running file directly and not importing it
main()
I personally use globals on a different .py file (for sanity purposes) for stuff like this when I get stuck on "how can I move a value from another class/function/something".
On new .py file:
file_name = None
file_path = None
# Save function
def save_filename(selected_file, selected_path):
global file_name, file_path
file_name = selected_file
file_path = selected_path
And on your browser when you select a file, add:
mynewpyfile.save_filename(file, path)
Then from your main window you can get the file data as:
self.pushTestbutton.clicked.connect(self.do_something)
def do_something(self):
print("the selected file is" + mynewpyfile.file_path + "/" + mynewpyfile.file_name)
Other alternatives: http://doc.qt.io/qt-5/qfiledialog.html
In this approach you just add a QlineEdit and... athough limited, it can't be easier than this.
self.lineTest.setText(QtWidgets.QFileDialog.getOpenFileName()[0])

Pressing button in QFileDialog popup exits application

I made the transition from PyQt4to PyQt5. My app (created with QtDesigner) has a checkbox which enables a "Save" button, in case you want to save your file. In PyQt4 the dialog would open, I'd choose my file, press OK, done. I implemented a check on the OK button of the main application that would prompt an error if the path was invalid, e.g. if you pressed cancel in the QFileDialog.
With PyQt5 my application exits completely if I close the QFileDialog in any way (OK, cancel, X). I want just the QFileDialog to close and not my main window. How do I do this? Thanks for your time and help.
Here's the relevant part of my code:
self.path = self.ui.savepathButton.pressed.connect(lambda: self.file_save())
def file_save(self):
path = QFileDialog.getSaveFileName(self, "Choose a path and filename", os.getcwd().replace("\\", "/") +
"/test.stl", filter="Stereolithography Files (*.stl)")
self.ui.savepath_label.setText(path) <------ NO ERROR WITHOUT THIS LINE
def OKButton_click(self):
if os.path.isdir(os.path.split(self.ui.savepath_label.text())[0]) is False:
# Warning if the filename is invalid.
file_error = QMessageBox()
file_error.setIcon(QMessageBox.Warning)
file_error.setText("Invalid path or filename.")
file_error.setInformativeText("Please choose a working path and filename.") file_error.setWindowTitle("File name error")
file_error.setStandardButtons(QMessageBox.Ok)
file_error.exec_()
else:
self.accept()
Edit:
I know where my error is located, but I still cannot fix it. I marked the line in the code. Why does self.ui.savepath_label.setText(path) terminate my application?
The PyQt4 provides two different APIs:
API v1 uses the Qt types for objects, so you have to pass things like QString to the setText method
API v2 instead uses python types and the methods of the Qt objects automatically convert those python types into their Qt variants, so you have to pass a python str to them.
This is mentioned in this page about PyQt4. PyQt5 only supports version 2 of the API (that page also mentions other differences).
Also note that according to the question pyqt5 - finding documentation the PyQt5 method getSaveFileName actually returns a pair of (filename, filter) so it's effectively equivalent to PyQt4's getSaveFileNameAndFilter method, which means that you could simply use:
self.ui.savepath_label.setText(path[0])
To set the text. Minimal complete example:
from PyQt5.QtWidgets import QFileDialog, QWidget, QApplication, QHBoxLayout, QPushButton
class Window(QWidget):
def __init__(self):
super(Window, self).__init__(None)
layout = QHBoxLayout()
self.button = QPushButton('click')
layout.addWidget(self.button)
self.setLayout(layout)
self.button.clicked.connect(self.ask_filename)
def ask_filename(self):
fname = QFileDialog.getSaveFileName(self, 'title')
print(fname)
self.button.setText(fname[0])
app = QApplication([])
window = Window()
window.show()
app.exec_()
By the way, if you change fname[0] to fname and try to launch this application from the terminal you get the following helpful error message:
Traceback (most recent call last):
File "test_qt.py", line 15, in ask_filename
self.button.setText(fname)
TypeError: QAbstractButton.setText(str): argument 1 has unexpected type 'tuple'
which tells you that the return type of getSaveFileName is a tuple and not a str.
I finally found the (very small) error:
While PyQt4 apparently writes the path automatically as string, PyQt5 does not.
I changed
self.ui.savepath_label.setText(path)
into
self.ui.savepath_label.setText(str(path))
and all is good now.

Building menu of files in folder hierarchy

I have a folder, and in that folder are files and other folders, with files and folders in it, etc. Now what I am trying to do is make a drop down menu and add each filename to the menu, and if it is a folder it creates a submenu and adds the filesname in that folder to that menu, etc. I kind of have some (incomplete) code:
def TemplatesSetup(self):
# add templates menu
template_menu = self.menubar.addMenu('&Templates')
#temp = template_menu.addMenu()
# check if templates folder exists
if os.path.exists('templates/') is False:
temp = QAction('Can not find templates folder...', self)
temp.setDisabled (1)
template_menu.addAction(temp)
return
for fulldir, folder, filename in os.walk('templates'):
for f in filename:
template_menu.addAction(QAction(f, self))
but I am still not sure how the best way to go about this would be. Any ideas?
I made a full example for you.
import sys
import os
import os.path
from PyQt4.QtCore import *
from PyQt4.QtGui import *
class MainWindow(QMainWindow):
def __init__(self):
QMainWindow.__init__(self)
template_menu = self.menuBar().addMenu('&Templates')
menus = {'templates': template_menu}
for dirpath, dirnames, filenames in os.walk('templates'):
current = menus[dirpath]
for dn in dirnames:
menus[os.path.join(dirpath, dn)] = current.addMenu(dn)
for fn in filenames:
current.addAction(fn)
if __name__=='__main__':
app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec_())

Categories

Resources