I recently built an app in PyQt5, and I was using a QTreeView to display all the items inside a folder. Today a switched to PySide6 and for some reason the TreeView is not showing the icons of the files/folders. I am going to toss in some images as examples.
Did something change between the two releases? I tried looking for something online but nothing pops up. This is the code I am using (I don't know if it helps)
from PySide6 import QtWidgets as qtw
from PySide6 import QtCore as qtc
from PySide6 import QtGui as qtg
import sys
import logic
class MainWindow(qtw.QWidget):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
# Init UI
self.width = 540
self.height = 380
self.setGeometry(
qtw.QStyle.alignedRect(
qtc.Qt.LeftToRight,
qtc.Qt.AlignCenter,
self.size(),
qtg.QGuiApplication.primaryScreen().availableGeometry(),
),
)
self.tree = qtw.QTreeView()
self.model = qtw.QFileSystemModel()
# Items
self.path_input = qtw.QLineEdit()
path_label = qtw.QLabel("Enter a path to begin: ")
check_btn = qtw.QPushButton("Check") # To display the items
clear_btn = qtw.QPushButton("Clear") # To clear the TreeView
self.start_btn = qtw.QPushButton("Start") # To start the process
self.start_btn.setEnabled(False)
# Layouts
top_h_layout = qtw.QHBoxLayout()
top_h_layout.addWidget(path_label)
top_h_layout.addWidget(self.path_input)
top_h_layout.addWidget(check_btn)
bot_h_layout = qtw.QHBoxLayout()
bot_h_layout.addWidget(clear_btn)
bot_h_layout.addWidget(self.start_btn)
main_v_layout = qtw.QVBoxLayout()
main_v_layout.addLayout(top_h_layout)
main_v_layout.addWidget(self.tree)
main_v_layout.addLayout(bot_h_layout)
self.setLayout(main_v_layout)
check_btn.clicked.connect(self.init_model)
clear_btn.clicked.connect(self.clear_model)
self.start_btn.clicked.connect(self.start)
self.show()
def init_model(self):
if logic.check(self.path_input.text()):
self.model.setRootPath(self.path_input.text())
self.tree.setModel(self.model)
self.tree.setRootIndex(self.model.index(self.path_input.text()))
self.tree.setColumnWidth(0, 205)
self.tree.setAlternatingRowColors(True)
self.path_input.clear()
self.start_btn.setEnabled(True)
else:
qtw.QMessageBox.warning(self, "Error", "Path not found.")
self.path_input.clear()
def clear_model(self):
self.tree.setModel(None)
self.path_input.clear()
def start(self):
logic.start(self.path_input.text())
qtw.QMessageBox.information(self, "Done", "Process completed")
if __name__ == "__main__":
app = qtw.QApplication(sys.argv)
w = MainWindow()
sys.exit(app.exec_())
This is the logic.py file:
import os
import shutil
def check(path):
if os.path.isdir(path):
return True
else:
return False
def start(path):
os.chdir(path)
for root, dirs, files in os.walk(path):
for filename in files:
movie_name = filename
strip_name = filename[:-4]
print(f"Creating directory for {movie_name}")
os.mkdir(strip_name)
print("Moving item to new directory.")
shutil.move(f"{path}\\{movie_name}", f"{path}\\{strip_name}\\{movie_name}")
print("\n")
print("Done.")
# For testing
if __name__ == "__main__":
usr_input = input("Path: ")
It seems a bug: the icons are invalid (maybe a plugin is missing, or is not correctly installed or does not have all its dependencies).
A workaround is to implement a custom QFileIconProvider:
class FileIconProvider(qtw.QFileIconProvider):
def icon(self, _input):
if isinstance(_input, qtc.QFileInfo):
if _input.isDir():
return qtw.QApplication.style().standardIcon(qtw.QStyle.SP_DirIcon)
elif _input.isFile():
return qtw.QApplication.style().standardIcon(qtw.QStyle.SP_FileIcon)
else:
if _input == qtg.QAbstractFileIconProvider.Folder:
return qtw.QApplication.style().standardIcon(qtw.QStyle.SP_DirIcon)
elif _input == qtg.QAbstractFileIconProvider.File:
return qtw.QApplication.style().standardIcon(qtw.QStyle.SP_FileIcon)
return super().icon(_input)
self.model.setIconProvider(FileIconProvider())