实战 | 如何用Python实现一个图形界面的文件内容搜索程序?

一、前言

电脑里的文件积累得越来越多,想要快速找一个文件就是一个麻烦事儿。

一个麻烦在于不知道文件在什么地方,这可以通过系统自带的文件管理器或者第三方的文件搜索软件进行搜索。

这解决了不知道文件在哪里的问题,却不能文件内容在哪个文件里面的问题。

望着一堆陌生的文件名,难道只能一个一个点开搜索才能找到自己想要的那个文件?

今天我们(州的先生,zmister.com)抛砖引玉,通过Python和PyQt5实现一个简单的文本文件内容搜索助手。

二、创建一个基础图形界面

在我们(州的先生,zmister.com)创建的文本文件内容搜索助手中,包含三个基础部件,它们是:

  • 搜索框,用于输入搜索内容;
  • 按钮,用于点击开始搜索查询;
  • 搜索结果框,用于显示搜索出来的结果;

下面我们就通过PyQt5中的小部件搭建起这个程序的基础图形界面,搜索框使用QLineEdit()小部件、按钮使用QPushButton()小部件、搜索结果框使用QListWidget()小部件,整体的布局使用QGridLayout()网格布局,代码如下所示:

class MainUi(QtWidgets.QMainWindow):
    # 州的先生
    # https://zmister.com
    def __init__(self):
        super().__init__()
        self.setWindowTitle("州的先生-本地文件搜索测试-zmister.com")
        self.main_widget = QtWidgets.QWidget()
        self.main_widget_layout = QtWidgets.QGridLayout()
        self.main_widget.setLayout(self.main_widget_layout)

        self.search_input = QtWidgets.QLineEdit()
        self.search_btn = QtWidgets.QPushButton("搜索")
        self.search_result = QtWidgets.QListWidget()

        self.main_widget_layout.addWidget(self.search_input,0,0,1,2)
        self.main_widget_layout.addWidget(self.search_btn, 0, 2, 1, 1)
        self.main_widget_layout.addWidget(self.search_result, 1, 0, 3, 3)

        self.setCentralWidget(self.main_widget)

def main():
    app = QtWidgets.QApplication(sys.argv)
    gui = MainUi()
    gui.show()
    sys.exit(app.exec_())


if __name__ == '__main__':
    main()

运行上述代码,我们将会得到一个如下图所示的图形界面窗口:

可以看到,这个图形界面窗口得结构还是很紧凑合理的。我们继续对其功能的实现。

三、搜索文件

我们的目的是实现对文件内容的搜索,所以我们首先需要获取到文件名,然后再打开文件搜索其中的内容。

在这里,我们仅以当前目录下的TXT文本文件作为示例演示,借助python的内置库os获取当前目录下的所有文件,接着挑选出后缀名为txt的文件,并对其进行读取操作。代码如下所示:

for root,dirs,files in os.walk("."):
    print(root,dirs)
    for file in files: # 遍历目录下的文件
        if os.path.splitext(file)[1] == '.txt': # 匹配txt格式的文件
            with open(file, encoding='utf-8') as files:
                content = files.read()
            if kw in content:
                a = "{0}/{1}".format(root,file) # 获取文件的路径
                print(a)

这段代码会将符合要求的文件名打印出来。我们新建一个MainUi()的方法search_slot(),将其作为按钮点击信号的槽函数。

def search_slot(self):
    # 州的先生 https://zmister.com
    kw = self.search_input.text() # 获取搜索词
    self.search_result.clear() # 清空搜索结果列表
    for root,dirs,files in os.walk("."):
        print(root,dirs)
        for file in files: # 遍历目录下的文件
            if os.path.splitext(file)[1] == '.txt': # 匹配txt格式的文件
                with open(file, encoding='utf-8') as files:
                    content = files.read()
                if kw in content:
                    a = "{0}/{1}".format(root,file) # 获取文件的路径
                    f = QtWidgets.QListWidgetItem(a) # 创建一个搜索结果项
                    self.search_result.addItem(f) # 将搜索结果添加到搜索部件中

接着将按钮的点击信号进行绑定:

……
self.search_btn.clicked.connect(self.search_slot)
……

这样,我们就实现了这个程序的文本文件搜索功能。

准备3个测试文本文件,里面分别输入文本内容,如下图所示:

我们就用这三个测试文件来进行演示,运行代码,在搜索框中输入关键词,点击搜索按钮,可以发现,出现了匹配内容的文件结果,如下图所示:

文件可以搜索出来,似乎可以告一段落了,在此我们再对程序加上双击结果显示文本文件内容的功能。

四、显示文件内容

我们想要直接看到搜索出来的结果文件的内容,这个功能可以通过QListWidget()部件子项的双击信号绑定槽函数来实现。

我们先来新建一个继承自QDialog的类,用于在另一个窗口中显示文本的内容:

class TextRead(QtWidgets.QDialog):
    # 州的先生 https://zmister.com
    def __init__(self,file=None):
        super().__init__()
        self.setWindowTitle("文本内容-{}".format(file))
        self.layout = QtWidgets.QGridLayout()
        self.setLayout(self.layout)
        text = QtWidgets.QTextEdit()
        text.setReadOnly(True)
        self.layout.addWidget(text)
        try:
            with open(file,encoding='utf-8') as files:
                content = files.read()
            text.setText(content)
        except Exception as e:
            print(e)

这个类接受一个文件路径参数file,会读取文件并将内容显示在QTextEdit()部件中。

创建好这个具体的功能实现类之后,我们在MainUi类中新建一个方法view_item_slot(),在其中实例化调用TextRead类,以作为QListWidget()部件子项双击信号的响应,代码如下所示:

def view_item_slot(self,event):
    # 州的先生 https://zmister.com
    file_name = event.text()
    content = TextRead(file=file_name)
    content.show()
    content.exec_()

与之配套的将其绑定到QListWidget()的itemDoubleClicked信号上:

……
self.search_result.itemDoubleClicked.connect(self.view_item_slot)
……

这样,我们就可以实现双击搜索结果显示文件内容的效果了,如下图所示:

五、最后

这样,我们就借助Python和PyQt5完成了一个文本文件内容搜索助手的开发,文章源码路径为:

这里作为演示功能很简单,其实还有很多可以扩展的地方,比如:

  • 文件目录的选择;
  • 更多类型的文件读取实现;
  • 跳转到文件所在目录;

像州的先生就将上面的代码改造成了Python文件的内容搜索器,有时候代码结构没组织好,一堆.py文件分散在多个目录下,想找一个具体调用了某个数据库表的Py文件,真是麻烦得不得了,所以就有了下面这样的Python文件内容搜索小助手:

大家有什么好的想法,欢迎留言讨论~

猜你也喜欢

  1. akai说道:

    very nice! 非常棒

  2. 小邱说道:

    :cry: 不知道哪里错了,运行不了。

    1. 州的先生说道:

      报什么错?

发表评论

邮箱地址不会被公开。