這是VSCode的文件資源管理或者叫資源文件導航,這是一個樹形結構的,我們使用 QTreeWidget來實現一下,最終的結果如下:
我先把代碼貼出來,UI界面的編程,不可能把每一行代碼都講清楚,我只講一些思路和需要注意的細節吧:
第一個文件(fileopen.py),UI設計的文件,是QT Designer設計好的ui文件直接轉換爲的Python文件:
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'fileopen.ui'
#
# Created by: PyQt5 UI code generator 5.13.0
#
# WARNING! All changes made in this file will be lost!
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(800, 600)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 23))
self.menubar.setObjectName("menubar")
self.menufile = QtWidgets.QMenu(self.menubar)
self.menufile.setObjectName("menufile")
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.actionfileopen = QtWidgets.QAction(MainWindow)
self.actionfileopen.setObjectName("actionfileopen")
self.menufile.addAction(self.actionfileopen)
self.menubar.addAction(self.menufile.menuAction())
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.menufile.setTitle(_translate("MainWindow", "File"))
self.actionfileopen.setText(_translate("MainWindow", "Open Folder..."))
第二個文件(file_tree.py), 邏輯文件,主要內容的實現,在這裏:
import sys
from PyQt5.QtWidgets import *
from PyQt5 import Qt, QtGui
from filename import file_name as fn
from fileopen import Ui_MainWindow
from PyQt5 import QtWidgets
import threading
import os
class Tree(QMainWindow, Ui_MainWindow):
def __init__(self, parent = None):
super(Tree, self).__init__(parent)
self.setupUi(self)
self.setWindowTitle("File_Tree")
self.actionfileopen.triggered.connect(self.Open_Folder)
def Open_Folder(self):
path = QFileDialog.getExistingDirectory(self, "選取文件夾", "./")
self.tree = QTreeWidget()
self.tree.setColumnCount(1)
self.tree.setColumnWidth(0, 50)
self.tree.setHeaderLabels(["EXPLORER"])
self.tree.setIconSize(Qt.QSize(25, 25))
self.tree.setSelectionMode(QAbstractItemView.ExtendedSelection)
self.actionfileopen.triggered.connect(self.Open_Folder)
dirs = fn(path)
fileInfo = Qt.QFileInfo(path)
fileIcon = Qt.QFileIconProvider()
icon = QtGui.QIcon(fileIcon.icon(fileInfo))
root = QTreeWidgetItem(self.tree)
root.setText(0,path.split('/')[-1])
root.setIcon(0,QtGui.QIcon(icon))
self.CreateTree(dirs, root, path)
self.setCentralWidget(self.tree)
QApplication.processEvents()
def CreateTree(self, dirs, root, path):
for i in dirs:
path_new = path + '\\' + i
if os.path.isdir(path_new):
fileInfo = Qt.QFileInfo(path_new)
fileIcon = Qt.QFileIconProvider()
icon = QtGui.QIcon(fileIcon.icon(fileInfo))
child = QTreeWidgetItem(root)
child.setText(0,i)
child.setIcon(0,QtGui.QIcon(icon))
dirs_new = fn(path_new)
self.CreateTree(dirs_new, child, path_new)
else:
fileInfo = Qt.QFileInfo(path_new)
fileIcon = Qt.QFileIconProvider()
icon = QtGui.QIcon(fileIcon.icon(fileInfo))
child = QTreeWidgetItem(root)
child.setText(0,i)
child.setIcon(0,QtGui.QIcon(icon))
if __name__ == "__main__":
app = QApplication(sys.argv)
win = Tree()
win.show()
sys.exit(app.exec_())
第三個文件(filename.py)我用於測試的文件,但是其中 file_name函數用於讀取目錄下的文件名,要使用到:
import os
def file_name(path):
return os.listdir(path)
if __name__ == "__main__":
path = 'C:\\Users\\...\\Desktop\\SeeTheData'
dirs = file_name(path)
for i in dirs:
print(i)
菜單選項的事件函數如下:
def Open_Folder(self):
path = QFileDialog.getExistingDirectory(self, "選取文件夾", "./")
self.tree = QTreeWidget()
self.tree.setColumnCount(1)
self.tree.setColumnWidth(0, 50)
self.tree.setHeaderLabels(["EXPLORER"])
self.tree.setIconSize(Qt.QSize(25, 25))
self.tree.setSelectionMode(QAbstractItemView.ExtendedSelection)
self.actionfileopen.triggered.connect(self.Open_Folder)
dirs = fn(path)
fileInfo = Qt.QFileInfo(path)
fileIcon = Qt.QFileIconProvider()
icon = QtGui.QIcon(fileIcon.icon(fileInfo))
root = QTreeWidgetItem(self.tree)
root.setText(0,path.split('/')[-1])
root.setIcon(0,QtGui.QIcon(icon))
self.CreateTree(dirs, root, path)
self.setCentralWidget(self.tree)
QApplication.processEvents()
生成文件選擇對話框,並獲得目錄路徑:
path = QFileDialog.getExistingDirectory(self, "選取文件夾", "./")
創建QTreeWidget組件,並設置相關參數:
self.tree = QTreeWidget()
self.tree.setColumnCount(1)
self.tree.setColumnWidth(0, 50)
self.tree.setHeaderLabels(["EXPLORER"])
self.tree.setIconSize(Qt.QSize(25, 25))
self.tree.setSelectionMode(QAbstractItemView.ExtendedSelection)
獲取文件在系統下的圖標:
fileInfo = Qt.QFileInfo(path)
fileIcon = Qt.QFileIconProvider()
icon = QtGui.QIcon(fileIcon.icon(fileInfo))
創建根節點:
root = QTreeWidgetItem(self.tree)
root.setText(0,path.split('/')[-1])
root.setIcon(0,QtGui.QIcon(icon))
遞歸創建子節點的函數如下:
def CreateTree(self, dirs, root, path):
for i in dirs:
path_new = path + '\\' + i
if os.path.isdir(path_new):
fileInfo = Qt.QFileInfo(path_new)
fileIcon = Qt.QFileIconProvider()
icon = QtGui.QIcon(fileIcon.icon(fileInfo))
child = QTreeWidgetItem(root)
child.setText(0,i)
child.setIcon(0,QtGui.QIcon(icon))
dirs_new = fn(path_new)
self.CreateTree(dirs_new, child, path_new)
else:
fileInfo = Qt.QFileInfo(path_new)
fileIcon = Qt.QFileIconProvider()
icon = QtGui.QIcon(fileIcon.icon(fileInfo))
child = QTreeWidgetItem(root)
child.setText(0,i)
child.setIcon(0,QtGui.QIcon(icon))
os.path.isdir用於判斷路徑是文件還是文件夾。