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_())
Related
First, I use Pyside2, I want the QListView to see icons in the default Windows, such as the QFilesystemModel.
The reason why QFilesystemModel is not available is because it wants to show items in folders across multiple paths.
We achieved the goal using the appendRow feature of QStandardItem.
However, Windows' default folders, files, and icons cannot be imported into seticon.
How to set the icon to look like it in Windows with QStandardItem
It's my code.
class CustomListView(QListView):
def __init__(self):
super().__init__()
def setup_model(self, paths):
self.model = QStandardItemModel()
for path in paths:
path = os.listdir(path)
for file in path:
item = QStandardItem(file)
self.model.appendRow(item)
self.setModel(self.model)
You have to use the QFileIconProvider that returns an icon based on the QFileInfo associated with the file or folder.
import os
from PySide2.QtCore import QFileInfo
from PySide2.QtGui import QStandardItem, QStandardItemModel
from PySide2.QtWidgets import QApplication, QFileIconProvider, QListView
class CustomListView(QListView):
def __init__(self):
super().__init__()
self.model = QStandardItemModel()
self.setModel(self.model)
self.icon_provider = QFileIconProvider()
def setup_model(self, paths):
self.model.clear()
for path in paths:
dirs = os.listdir(path)
for name in dirs:
filename = os.path.join(path, name)
icon = self.icon_provider.icon(QFileInfo(filename))
item = QStandardItem(name)
item.setIcon(icon)
self.model.appendRow(item)
def main():
app = QApplication()
view = CustomListView()
view.resize(640, 480)
view.show()
view.setup_model(["/home/user/", "/home/user/Pictures"])
app.exec_()
if __name__ == "__main__":
main()
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');
This is the code i have to display a tree view of a directory called "C:\Myfolder".
import sys
from PyQt4 import QtGui,QtCore
class Myview(QtGui.QMainWindow):
def __init__(self,parent=None):
QtGui.QMainWindow.__init__(self)
model = QtGui.QFileSystemModel()
model.setRootPath('C:\Myfolder')
view = QtGui.QTreeView()
view.setModel(model)
self.setCentralWidget(view)
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
myview = Myview()
myview.show()
sys.exit(app.exec_())
Even though i set the RootPath to "C:\Myfolder" , the tree view display all the drives and folder.
How can i limit the QFileSystemModel so that TreeView only display items inside "C:\Myfolder" directory?
You would need to add view.setRootIndex(model.index("C:\Myfolder")) according to the QFileSystemModel documentation.
It is extremely important that you write "C:/Myfolder" and NOT "C:\Myfolder". Otherwise, it thinks the directory does not exist and will always show you all drives and all folders.
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()
Here's my problem: I want to load a local html file into a QWebView in Python.
EDIT: I use PySide as a Qt package.
My code:
class myWindow(QWidget):
def __init__(self, parent=None):
self.view = QWebView(self)
filepath = "file://" + os.path.join(os.path.dirname(__file__), 'googlemap.html')
self.view.load(QUrl(filepath))
This is just showing me a blank widget.
If I change
self.view.load(QUrl(filepath)
by
self.view.load(QUrl("http://www.google.com/"))
It works fine.
However, the file is clearly in the good directory and I can open the same file directly with my browser.
EDIT 2:
The problem appears after an update on my Raspberry Pi 2 (which runs the code above)
Two observations:
path needs to be absolute (not relative)
use QUrl.fromLocalFile(path)
so something like this
file_path = os.path.abspath(os.path.join(os.path.dirname(__file__), "aa.html"))
local_url = QUrl.fromLocalFile(file_path)
browser.load(local_url)
should work.
Full example:
from PyQt4.QtWebKit import QWebView
from PyQt4.QtGui import QApplication
from PyQt4.QtCore import QUrl
import sys
import os
app = QApplication(sys.argv)
browser = QWebView()
file_path = os.path.abspath(os.path.join(os.path.dirname(__file__), "aa.html"))
local_url = QUrl.fromLocalFile(file_path)
browser.load(local_url)
browser.show()
app.exec_()