在任意目录下查找需要的文件如何操作呢?

其实很简单, WIN+E 【桌面计算机】- 右上角“搜索 计算机”

这个就是Windows自带的文件搜索功能。自己做一个文件搜索的应该应该也挺好玩的。

知识要点:

os.walk 函数方法用于通过在目录树种游走输出在目录中的文件名,向上或者向下深度遍历目录。
os.walk(top[, topdown=True[, οnerrοr=None[, followlinks=False]]])

参数

  • top -- 根目录下的每一个文件夹(包含它自己), 产生3-元组 (dirpath, dirnames, filenames)【文件夹路径, 文件夹名字, 文件名】。

  • topdown --可选,为True或者没有指定, 一个目录的的3-元组将比它的任何子文件夹的3-元组先产生 (目录自上而下)。如果topdown为 False, 一个目录的3-元组将比它的任何子文件夹的3-元组后产生 (目录自下而上)。

  • onerror -- 可选,是一个函数; 它调用时有一个参数, 一个OSError实例。报告这错误后,继续walk,或者抛出exception终止walk。

  • followlinks -- 设置为 true,则通过软链接访问目录。

 例子:

import os
for root, dirs, files in os.walk(".", topdown=False):for name in files:print(os.path.join(root, name))for name in dirs:print(os.path.join(root, name))

先从根目录进行遍历,读取跟目录的文件夹和文件。以根目录第一个子目录为新的根目录,读取其文件夹和文件。第一个子文件夹为根目录,读取文件夹和文件,直到结束。

下面,我们开始编写,新的应用

一.UI

对样式或审美不是很敏感(主要是功能),所以对于UI随心所遇的设计,一下为UI代码:

class MainWidgetUI(QDialog):def __init__(self, parent=None):super(MainWidgetUI, self).__init__(parent)self.setWindowIcon(QtGui.QIcon("favicon.ico"))self.setWindowOpacity(0.85)  # 透明度self.setWindowTitle('查询文件')self.directory = ''  # 跟目录self.mainLayout = QVBoxLayout()  # 水平布局# Find 文件布局self.topgroupBox = QGroupBox("任意右键选择查询目录")self.topLayout = QHBoxLayout(self.topgroupBox)self.lineEdit = QLineEdit('', self.topgroupBox)self.lineEdit.setPlaceholderText('如:chrome.exe, 多个 ; 分割')self.searchBtn = QPushButton(QtGui.QIcon("favicon.ico"), '查询', self.topgroupBox)self.topLayout.addWidget(self.lineEdit)self.topLayout.addWidget(self.searchBtn)# 输出文件路径布局self.bottgroupBox = QGroupBox('文件路径')self.bottLayout = QVBoxLayout(self.bottgroupBox)  # 水平布局self.ListWidget = QListWidget(self.bottgroupBox)self.bottLayout.addWidget(self.ListWidget)# mainLayout 布局
        self.mainLayout.addWidget(self.topgroupBox)self.mainLayout.addWidget(self.bottgroupBox)self.setLayout(self.mainLayout)
self.lineEdit.setFocus()  # 得到焦点# 搜索框样式
        self.lineEdit.setStyleSheet("QLineEdit{background-color:green;color:menubar;font-size:12px;background-image:url(search.png);}") if __name__ == "__main__":app = QApplication(sys.argv)main_widget = MainWidgetUI()main_widget.show()sys.exit(app.exec_())

UI效果:

当UI整完了后,发现个问题,如何选择要搜索目录呢,Windows自带的是整个硬盘搜索,这样目录太大,搜索时间太长,我们要的效果是将搜索的目录指定到某个盘或某个盘里面的某个文件夹。

想到了个办法,在UI中任意右键选择要搜索的目录:

    self.setContextMenuPolicy(Qt.CustomContextMenu)self.customContextMenuRequested.connect(self.rightHandButton)  # 任意地方右键 选择跟目录

# 任意地方右键def rightHandButton(self):self.directory = QFileDialog.getExistingDirectory(self, "请选择根目录", 'c:\\')self.topgroupBox.setTitle("查询根目录:" + str(self.directory))

二.SearchIndex

这一步就用os.walk查询文件,我们把这个功能封装正一个方法:

    def search_files(self, directory, patterns='*', single_level=False, yield_folders=False):# 将模式从字符串中取出放入列表中patterns = patterns.split(';')for path, subdirs, files in os.walk(directory):if yield_folders:files.extend(subdirs)files.sort()for name in files:for pattern in patterns:if fnmatch.fnmatch(name, pattern):yield os.path.join(path, name)breakif single_level:break

问题又来了,当点击查询按钮执行查找文件时,UI直接都卡死了

恍然也!查询文件的方法堵塞了UI主进程,所以我们用开启一个线程

# 线程查询类
class TheadingFindFile(QThread):resultSearchSignal = pyqtSignal(list)  # 声明一个带列表结果的参数信号def __init__(self, tuple):super(TheadingFindFile, self).__init__()self.searchTuple = tuple  # 元组?def run(self):result = []  # 列表files = self.search_files(self.searchTuple[0], self.searchTuple[1], False, False)for file in files:result.append(file)if not result:result = ['无查询结果']try:self.resultSearchSignal.emit(result)  # 发射信号except Exception as e:print(e)# 检查一个目录,后者某个包含子目录的目录树,并根据某种模式迭代所有文件# patterns如:*.html,若大小写敏感可写*.[Hh][Tt][Mm][Ll]# single_level 为True表示只检查第一层# yield_folders 表示是否显示子目录,为False只遍历子目录中的文件,# 但不返回字母名def search_files(self, directory, patterns='*', single_level=False, yield_folders=False):# 将模式从字符串中取出放入列表中patterns = patterns.split(';')for path, subdirs, files in os.walk(directory):if yield_folders:files.extend(subdirs)files.sort()for name in files:for pattern in patterns:if fnmatch.fnmatch(name, pattern):yield os.path.join(path, name)breakif single_level:break

三.完善应用

在上一步中,尽管堵塞了UI进程,但文件少的时候也是可以完成搜索呈现在QListWidget中,作为一个严谨的***, 我们要将产品做到尽量的完美!

所以我们要做提交验证、开启查询线程防止UI堵塞、查询中禁止再次点击查询按钮、QListWidget的中的数据要能打开改目录,所以第三步,就是完善应用。

在查询按钮点击后,我们判断数据是否填写

self.ListWidget.clear()  # 清空ListWidget数据inputs = self.lineEdit.text()if inputs == '':QMessageBox.warning(self, '查询提示', '输入的查询文件名关键字不能为空', QMessageBox.Yes)return Falseif self.directory == '':QMessageBox.warning(self, '查询提示', '请任意右键选择查询的跟目录', QMessageBox.Yes)return False

验证完成后,开启查询线程:

        try:# 在 实例化类与connect、start 直接不能打印任何东西,不然会报错senderData = (self.directory, self.lineEdit.text())self.Theading = TheadingFindFile(senderData)self.Theading.resultSearchSignal.connect(self.updateResult)  # 连接信号。 TheadingFindFile在线程状态结果后emit发射信号self.Theading.start()  # 线程开始except Exception as e:print(e)

别急!我们应该在加一个查询按钮按下后的特效,因为查询会堵塞UI进程,相同的我想做一个每秒显示一个点点点的效果也会堵塞进程。【不用问,我已经试过的】,所以也开启了一个点点点的效果进程:

# 线程查询效果类
class TheadingSearchBtnNet(QThread):resultSearchBtnNetSignal = pyqtSignal(str)  # 声明一个带列表结果的参数信号def __init__(self, str):super(TheadingSearchBtnNet, self).__init__()self.searchTuple = str# 设置status 的状态值, 1 为可执行,0:停止执行def setVal(self, st):self.st = stself.start()def run(self):i = 5while True:Dot = ''if i <= 5:for l in range(0, 5):time.sleep(1)Dot += str('.')if self.st == 1:  # 可执行self.resultSearchBtnNetSignal.emit(str(Dot))  # 发射信号i += 1else:i = 0

查询中点点点效果:

还有一个就是在ListWidget中呈现的路径,做了一个双击打开文件所在目录的功能,

    # List路径列表双击事件def doubleClickListPath(self):text = self.ListWidget.currentItem().text()  # 获取当前Item的texttext = text.replace('/', '\\')if text != '无查询结果':os.system(r'explorer /select,' + str(text))  # 打开文件并选中文件

使用subprocess.Popen(file) 只能打开文件,使用explorer /select , file  可以用Windows自带的文件管理器打开文件的所在目录,并选中该文件。其实这个explorer直接可以在命令行CMD直接打开。

四.完整代码及效果

完整代码:

# -*- coding: utf-8 -*-
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5 import QtGui
import os, sys, fnmatch
import timeclass MainWidgetUI(QDialog):def __init__(self, parent=None):super(MainWidgetUI, self).__init__(parent)self.setWindowIcon(QtGui.QIcon("favicon.ico"))self.setWindowOpacity(0.85)  # 透明度self.setWindowTitle('查询文件')self.directory = ''  # 跟目录self.mainLayout = QVBoxLayout()  # 水平布局# Find 文件布局self.topgroupBox = QGroupBox("任意右键选择查询目录")self.topLayout = QHBoxLayout(self.topgroupBox)self.lineEdit = QLineEdit('', self.topgroupBox)self.lineEdit.setPlaceholderText('如:chrome.exe, 多个 ; 分割')self.searchBtn = QPushButton(QtGui.QIcon("favicon.ico"), '查询', self.topgroupBox)self.topLayout.addWidget(self.lineEdit)self.topLayout.addWidget(self.searchBtn)# 输出文件路径布局self.bottgroupBox = QGroupBox('文件路径')self.bottLayout = QVBoxLayout(self.bottgroupBox)  # 水平布局self.ListWidget = QListWidget(self.bottgroupBox)self.bottLayout.addWidget(self.ListWidget)# mainLayout 布局
        self.mainLayout.addWidget(self.topgroupBox)self.mainLayout.addWidget(self.bottgroupBox)self.setLayout(self.mainLayout)self.searchBtn.clicked.connect(self.searchDef)  # 查询事件
        self.setContextMenuPolicy(Qt.CustomContextMenu)self.customContextMenuRequested.connect(self.rightHandButton)  # 任意地方右键 选择跟目录self.ListWidget.itemDoubleClicked.connect(self.doubleClickListPath)  # List路径列表双击事件self.lineEdit.setFocus()  # 得到焦点# 搜索框样式
        self.lineEdit.setStyleSheet("QLineEdit{background-color:green;color:menubar;font-size:12px;background-image:url(search.png);}")self.Theading2 = TheadingSearchBtnNet("查询")self.Theading2.resultSearchBtnNetSignal.connect(self.searchBtnText)  # 连接信号。 TheadingFindFile在线程状态结果后emit发射信号# self.lineEdit.setText('chrome.exe;readme.txt')# self.ListWidget.addItem("C:\\Program Files\\7-Zip/7z.exe")# self.ListWidget.addItem("bb")# self.ListWidget.addItem("E:\\Program Files/java")# 显示查询按钮点点点效果def searchBtnText(self, strings):self.searchBtn.setText("查询" + str(strings))# List路径列表双击事件def doubleClickListPath(self):text = self.ListWidget.currentItem().text()  # 获取当前Item的texttext = text.replace('/', '\\')if text != '无查询结果':os.system(r'explorer /select,' + str(text))  # 打开文件并选中文件# 任意地方右键def rightHandButton(self):self.directory = QFileDialog.getExistingDirectory(self, "请选择根目录", 'c:\\')self.topgroupBox.setTitle("查询根目录:" + str(self.directory))# 查询BTN 按钮def searchDef(self):self.ListWidget.clear()  # 清空ListWidget数据inputs = self.lineEdit.text()if inputs == '':QMessageBox.warning(self, '查询提示', '输入的查询文件名关键字不能为空', QMessageBox.Yes)return Falseif self.directory == '':QMessageBox.warning(self, '查询提示', '请任意右键选择查询的跟目录', QMessageBox.Yes)return Falseself.searchBtn.setDisabled(True)self.Theading2.setVal(1)  # 查询点点点效果线程开始try:# 在 实例化类与connect、start 直接不能打印任何东西,不然会报错senderData = (self.directory, self.lineEdit.text())self.Theading = TheadingFindFile(senderData)self.Theading.resultSearchSignal.connect(self.updateResult)  # 连接信号。 TheadingFindFile在线程状态结果后emit发射信号self.Theading.start()  # 线程开始except Exception as e:print(e)# 返回响应的参数def updateResult(self, resultData):self.searchBtn.setDisabled(False)self.searchBtn.setText('查询')self.Theading2.setVal(0)  # 停止执行for data in resultData:self.ListWidget.addItem(data)# 线程查询类
class TheadingFindFile(QThread):resultSearchSignal = pyqtSignal(list)  # 声明一个带列表结果的参数信号def __init__(self, tuple):super(TheadingFindFile, self).__init__()self.searchTuple = tuple  # 元组?def run(self):result = []  # 列表files = self.search_files(self.searchTuple[0], self.searchTuple[1], False, False)for file in files:result.append(file)if not result:result = ['无查询结果']try:self.resultSearchSignal.emit(result)  # 发射信号except Exception as e:print(e)# 检查一个目录,后者某个包含子目录的目录树,并根据某种模式迭代所有文件# patterns如:*.html,若大小写敏感可写*.[Hh][Tt][Mm][Ll]# single_level 为True表示只检查第一层# yield_folders 表示是否显示子目录,为False只遍历子目录中的文件,# 但不返回字母名def search_files(self, directory, patterns='*', single_level=False, yield_folders=False):# 将模式从字符串中取出放入列表中patterns = patterns.split(';')for path, subdirs, files in os.walk(directory):if yield_folders:files.extend(subdirs)files.sort()for name in files:for pattern in patterns:if fnmatch.fnmatch(name, pattern):yield os.path.join(path, name)breakif single_level:break# 线程查询效果类
class TheadingSearchBtnNet(QThread):resultSearchBtnNetSignal = pyqtSignal(str)  # 声明一个带列表结果的参数信号def __init__(self, str):super(TheadingSearchBtnNet, self).__init__()self.searchTuple = str# 设置status 的状态值, 1 为可执行,0:停止执行def setVal(self, st):self.st = stself.start()def run(self):i = 5while True:Dot = ''if i <= 5:for l in range(0, 5):time.sleep(1)Dot += str('.')if self.st == 1:  # 可执行self.resultSearchBtnNetSignal.emit(str(Dot))  # 发射信号i += 1else:i = 0if __name__ == "__main__":app = QApplication(sys.argv)main_widget = MainWidgetUI()main_widget.show()sys.exit(app.exec_())

打包程序为exe:

if __name__ == '__main__':from PyInstaller import __main__params = ['-F','-w',  '--icon=favicon.ico','--noupx', 'mainFindFiles.py']__main__.run(params)

效果:

转载于:https://www.cnblogs.com/dcb3688/p/4608031.html

Pyqt walk 在Windows查找文件相关推荐

  1. python查找关键字所属行_Python查找文件有多牛?男默女泪!!!

    某天,隔壁大神正在看一份内核技术文档,我想研读下文档向大神"偷师",恰好我的虚拟XP桌面无法使用搜索功能,而且项目组一般是一起使用共享目录的,这就导致大量资料杂糅在一起,我要找到大 ...

  2. path与classpath区别 path是Windows查找.exe文件的路径;classpath是jvm查找.class文件的路径

    CLASSPATH环境变量.作用是指定类搜索路径,要使用已经编写好的类,前提当然是能够找到它们了,JVM就是通过CLASSPATH来寻找类的.class文件 总而言之,path是Windows查找.e ...

  3. win2003服务器记录文件夹,在Windows Server 2003里快速查找文件

    用Windows Server 2003的Agent Ransack??专业文件定位器(File Locator Pro)应用程序快速查找文件. 随着各种规模的组织的数据存储需求不断增加,同时法规监管 ...

  4. Windows下用命令行查找文件for命令的运用

    <Windows下for命令查找文件> 可以在cmd下敲入如下命令了解for用法: for   /? 如要查找 "d:\下的jpg文件,命令如下: for /r d:\ %i i ...

  5. windows系统查找文件-通配符的使用

    在windows中可以使用通配符"* "."? "查找文件. 对于相同字符开头的单词和相同字符结尾的单词可以用"<"和" & ...

  6. win怎么在计算机里按日期搜索文件,Windows下怎么按时间查找文件

    Windows下如何按时间查找文件 比方说我想某个文件夹下所有最后修改时间大于2014/1/12 13:39:40以后的所有文件,应该如何做?用编程.软件方法都可以,应该如何做呢?大家多多支持啊 分享 ...

  7. windows 查找目录下文件中包含某个字符的文件

    一.可以使用windows自带的findstr来实现. 例子(1) findstr /s /i "string" . 上面的命令表示,当前目录以及当前目录的所有子目录下的所有文件中 ...

  8. macos 查找文件_如何在Windows和macOS上查找和安装颜色配置文件以获取更准确的显示器...

    macos 查找文件 Color profiles, also known as ICC or ICM files, contain a collection of settings that hel ...

  9. Windows·查找某路径下所有的Office文件及压缩文件

    阅文时长 | 0.17分钟 字数统计 | 285.6字符 主要内容 | 1.引言&背景 2.声明与参考资料 『Windows·查找某路径下所有的Office文件及压缩文件』 编写人 | SCs ...

  10. Windows如何 cmd 查找文件路径 开机启动 CMD语音播放 CMD切换到管理员!

    1,语音播放: CreateObject("SAPI.SpVoice").Speak"崭新的开始,你好!" 单词别拼写错误啦! 把这个拖到开机启动项里就可以开后 ...

最新文章

  1. 使用 IntraWeb (36) - TIWServerControllerBase
  2. java process started_Java HistoricProcessInstanceQuery.startedBy方法代碼示例
  3. AndroidManifest.xml文件详解(activity)(三)四种工作模式
  4. 25个吸引眼球的广告设计
  5. App.vue文件報錯
  6. mysql游标遍历数据库_MySQL数据库中,使用游标循环遍历_MySQL
  7. 这该死的高度,height,clientHeight,scrollHeight,offsetHeight
  8. java 函数签名,Java签名getAlgorithm()方法
  9. 美国影视演员协会选择了Windows Azure
  10. __FILE__,__LINE__,FUNCTION__实现代码跟踪调试(linux下c语言编程 )(转自IT博客)
  11. java 变量 类之间调用_java内部类与其他类变量之间的调用方式
  12. Dism++管理优化windows
  13. 阿里代码规范插件安装和使用技巧
  14. 计算机应用基础题库及答案
  15. Denoise_bayerdomain
  16. 触控笔有必要买吗?苹果平板触控笔排行榜
  17. Fairplay之 generating FairPlay content key request on iOS after 14.6
  18. 巧配交换机防止同网段ARP***典型实例
  19. kafka维护工具使用指南
  20. 科学计算机可以带上飞机吗,笔记本电脑可以随身带上飞机吗

热门文章

  1. wireshark中筛选中文内容
  2. 一个命令清理电脑垃圾,不用再安装任何管家软件,节省电脑资源,让电脑运行更快更流畅
  3. 从维密天使到编程大拿,她的彪悍人生不需要解释!
  4. c# .net对接企业微信小助手 接口请求时长预警
  5. events_statements_history_long,events_statements_history mysql语句存储
  6. numpy_10 思维导图
  7. android英语阅读识别库,基于Android的大学英语阅读学习平台研究
  8. 手提电脑亮度不能调节,亮度调节按钮变灰,找不到调节亮度按钮
  9. 戴尔通过F12一次性引导菜单刷新BIOS
  10. Information:java: Errors occurred while compiling module