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()
Related
I’m using PyQt5 on a Windows platform. I want to present a QFileDialog to the user with the suggested file highlighted in both the QListView and the QLineEdit widgets within the QFileDialog window. The selectFile() method adds the filename to the QLineEdit widget and highlightss it, but does not highlight the file in the QListView widget.
I tried the suggestion in How to setFocus() on QListView in QFileDialog in PyQt5?, but I could not see that the QListView had focus and could not highlight a file with selectFile().
In QFileDialog, is there a way to highlight the filename in the QistView and in the QLineEdit widgets? If not, is there a way to highlight the filename in just the QListView?
Here is a minimalized script that shows the filename highlighted in the QLineEdit widget.
import sys
from PyQt5.QtWidgets import QApplication, QFileDialog
from PyQt5.QtCore import QDir
class MyClass(QFileDialog):
def __init__(self):
super().__init__()
self.DontUseNativeDialog
self.openFile()
def openFile(self):
qdir = QDir()
qdir.setPath('C:\\Users\\Slalo\\Documents\\VideoGates\\PVRTop\\Folder')
qdir.setSorting(QDir.Name | QDir.Reversed)
qdirlist = qdir.entryList()
self.setWindowTitle('Open File')
self.setDirectory(qdir)
self.setNameFilter('All(*.*)')
self.selectFile(qdirlist[1])
if self.exec():
fname = self.selectedFiles()
print(fname)
if __name__ == '__main__':
app = QApplication(sys.argv)
dlg = MyClass()
sys.exit(app.exec())
After testing #musicamante 's patience, here is the solution. The QFileDialog window looks a little different than the native Windows dialog, but that's OK - it works as intended. Here is the corrected script.
import sys, os
from PyQt5.QtWidgets import QApplication, QFileDialog
class MyClass(QFileDialog):
def __init__(self):
super().__init__()
self.setOption(QFileDialog.DontUseNativeDialog)
self.openFile()
def openFile(self):
dirname = 'C:\\Users\\Slalo\\Documents\\VideoGates\\PVRTop\\Folder'
fileList = os.listdir(dirname)
self.setWindowTitle('Open File')
self.setDirectory(dirname)
self.setNameFilter('All(*.*)')
self.selectFile(fileList[1])
if self.exec():
fname = self.selectedFiles()
print(fname)
if __name__ == '__main__':
app = QApplication(sys.argv)
dlg = MyClass()
sys.exit(app.exec())
I'm trying to build an app here. I used QT Designer to build the main window (Ui_MainWindow) with buttons. I import this to a new file where I can structure the code a bit better.
Anyhow, I keep getting the error "TypeError: startfile: filepath should be string, bytes or os.PathLike, not Ui_MainWindow" whenever I try to get the filename via QFileDialog. This filename is used in the GetData -method to produce a dataframe. I'm sure I'm doing something horribly wrong here in my code. I understood that you can call methods within other methods
So I will have 3 buttons:
Open folder (which gets the filename)
Update data (which is connected to UpdateData method. This method updates the data as I want)
Calculate (a method that calculates something based on the output from updateData -method.)
So I am trying to get an output from step 1 to use as input in step 2, to get an output which then would be used as input in step 3 and then - voilá.
What am I doing wrong?
from myQTDesignerGUIfile import Ui_MainWindow
from PyQt5 import QtWidgets
from PyQt5.QtWidgets import (QApplication, QMainWindow, QPushButton, QLabel, QFileDialog, QMessageBox)
from PyQt5.QtCore import pyqtSlot, QFileInfo
class MyApp(QtWidgets.QMainWindow, Ui_MainWindow):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
#Build instance of setpUI in Ui_MainWindow -class
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
def GetFileName(self):
FileFilter = 'File (*.xlsx *.xlsm *.csv)'
FileName = QFileDialog.getOpenFileName(parent = self,
caption="Select File",
directory = 'Some Path',
filter = FileFilter)[0]
path = str(FileName)
if path:
print(path)
return path
def GetData(self):
path = self.GetFileName
return pd.read_csv(path)
def UpdateData(self):
## get data using the GetData -method
df = self.GetData()
## code to modify data is written here
return final_mod_data
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
w = MyApp()
w.show()
app.exec()
I read a lot of tutorials on how to get coordinates of the clicking position on an image in QLabel ("label_2" in the code below defined in "form.ui" by Qt Creator). Most of them refer to using mousePressEvent method. However, after implementing the method, it does not function when I click a point on the imported image. It seems that mousePressEvent is never called by anything. Wondering what is going wrong in it. Is there any trivial or non-trivial thing missed?
import sys
import os
from PySide2.QtWidgets import QApplication, QWidget
from PySide2.QtCore import QFile, Qt
from PySide2.QtUiTools import QUiLoader
from PySide2.QtGui import QPixmap
class qttest(QWidget):
def __init__(self):
super(qttest, self).__init__()
self.load_ui()
self.showImage()
def load_ui(self):
loader = QUiLoader()
path = os.path.join(os.path.dirname(__file__), "form.ui")
ui_file = QFile(path)
ui_file.open(QFile.ReadOnly)
self.ui = loader.load(ui_file, self)
ui_file.close()
def showImage(self,file='img.jpg'):
pixmap = QPixmap(file)
pixmap1 = pixmap.scaled(200, 200, Qt.KeepAspectRatio)
self.ui.label_2.setPixmap(pixmap1)
self.ui.label_2.mousePressEvent = self.getPos
def getPos(self,event):
x = event.pos().x()
y = event.pos().y()
print(x,y)
if __name__ == "__main__":
app = QApplication([])
widget = qttest()
widget.show()
sys.exit(app.exec_())
Figured out the problem by ourselves. self.ui = loader.load(ui_file, self) in the code is not a recommended way to take all items in "form.ui" into consideration. By using uic imported from PyQt5 package, this could be solved.
Straight to issue, when pdf loads with pdfjs into pyqt5, seems print button does not work correctly, also the same for download button.
How could this bug be fixed?
The code:
import sys
from PyQt5 import QtCore, QtWidgets, QtGui, QtWebEngineWidgets
PDFJS = 'file:///pdfjs/web/viewer.html'
PDF = 'file:///file0.pdf'
class PdfReport(QtWebEngineWidgets.QWebEngineView):
def __init__(self, parent=None):
super(PdfReport, self).__init__(parent)
self.load(QtCore.QUrl.fromUserInput('%s?file=%s' % (PDFJS, PDF)))
def sizeHint(self):
return QtCore.QSize(640, 480)
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
im = PdfReport()
im.show()
sys.exit(app.exec_())
Display:
Any idea how to fix that?
The print task is not enabled in Qt WebEngine so the fault is displayed (I'm still trying to get the data). But in the case of the download button of the PDF it is possible and for this you must use the downloadRequested signal of the QWebEngineProfile:
import os
import sys
from PyQt5 import QtCore, QtWidgets, QtWebEngineWidgets
CURRENT_DIR = os.path.dirname(os.path.realpath(__file__))
PDFJS = QtCore.QUrl.fromLocalFile(
os.path.join(CURRENT_DIR, "pdfjs/web/viewer.html")
).toString()
class PdfReport(QtWebEngineWidgets.QWebEngineView):
def __init__(self, parent=None):
super(PdfReport, self).__init__(parent)
QtWebEngineWidgets.QWebEngineProfile.defaultProfile().downloadRequested.connect(
self.on_downloadRequested
)
def load_pdf(self, filename):
url = QtCore.QUrl.fromLocalFile(filename).toString()
self.load(QtCore.QUrl.fromUserInput("%s?file=%s" % (PDFJS, url)))
def sizeHint(self):
return QtCore.QSize(640, 480)
#QtCore.pyqtSlot(QtWebEngineWidgets.QWebEngineDownloadItem)
def on_downloadRequested(self, download):
path, _ = QtWidgets.QFileDialog.getSaveFileName(
self, "Save File", "sample.pdf", "*.pdf"
)
if path:
download.setPath(path)
download.accept()
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
w = PdfReport()
path = os.path.join(CURRENT_DIR, "file0.pdf")
w.load_pdf(path)
w.show()
sys.exit(app.exec_())
That's not a PyQt5 button, that is a button from your web view. It may not work because of your webView object or because the web part of your code lacks functionality for the button.
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_())