• qtdesigner使用QTableWidget控件实现读取excel表



    前言

    之前学习QTableWidget的时候一直是捏造虚假数据加到表格里面,但是现实中数据来源多种多样,于是想尝试读取excel的数据到表格里面,还真的可以,于是记录下来,方便以后参考。


    一、构建界面

    页面布局如下:
    在这里插入图片描述

    1. 第一行由一个QLabel、和一个QLineEdit组成,其中QLineEdit的类名改成file_path_edt,水平布局
    2. 第二行由两个QButton和一个Horizontal Scaper组成,其中选择文件按钮类名改成choice_btn,打开按钮类名改成open_btn,水平布局
    3. 第三行由一个QTableWidget组成,类名改成data_table,因为只有一个控件,所以不需要布局
    4. 整个窗体设置成垂直布局

    不懂如何布局的请看这里qtdesigner页面布局

    页面设计完之后,输入命令将ui文件转换为py文件(我的ui文件名为table_demo)

    pyuic5 -o table_ui.py table_demo.ui
    
    • 1

    然后编写代码使得界面能够展示
    table_main.py

    from PyQt5.QtWidgets import QMainWindow, QApplication
    import sys
    
    from ui.table_ui import Ui_MainWindow
    
    
    class TableWin(QMainWindow, Ui_MainWindow):
        def __init__(self):
            super().__init__()
            self.setupUi(self)
            
    if __name__ == '__main__':
        app = QApplication(sys.argv)
        table_win = TableWin()
        table_win.show()
        sys.exit(app.exec_())
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    附上项目文件目录
    在这里插入图片描述

    二、逻辑代码编写

    完整代码在最后,现在先写代码编写思路

    2.1、拖曳文件获取文件路径

    这是个很常见的功能,就是将文件拖进窗口里面之后,读取文件内容。我这里只读取文件的绝对路径,之后再根据文件路径打开文件。

    首先,要设置一个参数保存文件路径,在初始化函数里面初始化该参数。同时因为要有拖曳动作,所以要设置窗口接受拖曳动作。

    class TableWin(QMainWindow, Ui_MainWindow):
        def __init__(self):
            super().__init__()
            self.setupUi(self)
            self.setAcceptDrops(True)   # 设置接受拖曳动作
            self.file_path = ''     # 定义文件路径
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    然后,需要重写拖曳方法,就是拖曳文件到窗口之后,保存文件文件路径,并且设置输入框文本为文件路径

    	'''重写拖曳方法'''
        def dragEnterEvent(self, event):
            if event.mimeData().hasUrls:
                event.accept()
            else:
                event.ignore()
    
        def dragMoveEvent(self, event):
            if event.mimeData().hasUrls:
                try:
                    event.setDropAction(Qt.CopyAction)
                except Exception as e:
                    print(e)
                event.accept()
            else:
                event.ignore()
    
        def dropEvent(self, event):
            if event.mimeData().hasUrls:
                event.setDropAction(Qt.CopyAction)
                event.accept()
                links = []
                for url in event.mimeData().urls():
                    links.append(str(url.toLocalFile()))
                self.file_path = links[0]   # 获取文件绝对路径
                self.set_file_path_edt(self.file_path)    # 设置文件绝对路径
            else:
                event.ignore()
                
        # 设置输入框里面内容
        def set_file_path_edt(self, file_path):
            self.file_path_edt.setText(file_path)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    现在拖曳文件到窗口里面就可以获取文件路径啦。

    2.2、选择文件获取文件路径

    虽然拖曳文件获取文件数据是个常见功能,但也会有部分人喜欢打开文件夹选择文件,因此这功能也要实现。
    首先,先实现打开文件夹选择文件的方法

        def choice_file(self):
            now_path = os.getcwd()  # 获取当前路径
            choice_file_path = QFileDialog.getOpenFileName(self, '选择文件', now_path, 'Excel files(*.xlsx , *.xls)')
    
            # 如果路径存在,设置文件路径和输入框内容
            if choice_file_path[0]:
                self.file_path = choice_file_path[0]
                self.set_file_path_edt(choice_file_path[0])
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    该方法在点击选择文件按钮之后实现,所以将按钮点击事件跟该方法关联起来,而且窗口初始化的时候就要关联,所以代码如下

    class TableWin(QMainWindow, Ui_MainWindow):
        def __init__(self):
            super().__init__()
            self.setupUi(self)
            self.setAcceptDrops(True)   # 设置接受拖曳动作
            self.file_path = ''     # 定义文件路径
            self.listener()     # 调用监听函数
    
        # 监听函数都写在里面
        def listener(self):
            self.choice_btn.clicked.connect(self.choice_file)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    2.3、打开文件读取数据

    1. 获取了文件路径之后,就可以根据路径打开文件了,我们这里使用的是pandas来打开excel文件。
    2. 打开的文件格式也要有限制,只打开excel文件,不是excel文件则警告。
    3. 该方法在点击打开按钮之后实现,所以要将打开按钮和该方法关联起来。

    具体代码如下:

    class TableWin(QMainWindow, Ui_MainWindow):
        def __init__(self):
            super().__init__()
            self.setupUi(self)
            self.setAcceptDrops(True)   # 设置接受拖曳动作
            self.file_path = ''     # 定义文件路径
            self.listener()     # 调用监听函数
    
        # 监听函数都写在里面
        def listener(self):
            self.choice_btn.clicked.connect(self.choice_file)
            self.open_btn.clicked.connect(self.open_file)
    	
    	# 打开文件
        def open_file(self):
            # 判断文件路径是否有值(就是有没有选择了文件)
            if self.file_path:
                # 获取文件后缀
                file_format = self.file_path.split('.')[-1]
                # 判断文件格式是否是'xls'或者'xlsx'
                if file_format == 'xls' or file_format == 'xlsx':
                    # 使用pandas提取excel数据
                    excel_data = pd.read_excel(self.file_path)
                    # 获取excel数据行数
                    rows = excel_data.shape[0]
                    # 获取excel数据列数
                    columns = excel_data.shape[1]
                    # print(rows, columns)
    
                    # 设置总列数
                    self.data_table.setColumnCount(columns)
                    # 设置总行数
                    self.data_table.setRowCount(rows)
                    # 设置表头(excel_data.columns可以获取表头列表,默认第一列为表头)
                    self.data_table.setHorizontalHeaderLabels(excel_data.columns)
    
                    '''遍历excel中的元素,添加到tableWidget里面'''
                    # 设置写数据的当前索引(excel中的第二行对应tableWidget中的第一行,索引并不一样,所以要设置新索引跟踪tableWidget中的索引)
                    data_table_current = 0
    
                    # 插入值
                    for i in range(0, rows):
                        for j in range(columns):
                            # 创建QTableWidgetItem对象,并设置值
                            new_item = QTableWidgetItem(str(excel_data.iloc[i, j]))
                            # 设置QTableWidgetItem对象启用、可以选中和可以编辑
                            new_item.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled | Qt.ItemIsEditable)
                            # 设置QTableWidgetItem对象里面的值水平,垂直居中
                            new_item.setTextAlignment(Qt.AlignHCenter | Qt.AlignVCenter)
                            # 将新建的QTableWidgetItem添加到tableWidget中,参数分别是(行索引,列索引,QTableWidgetItem对象)
                            self.data_table.setItem(data_table_current, j, new_item)
                        # 写数据的当前索引加1
                        data_table_current += 1
    
                else:
                    QMessageBox.warning(self, '警告', '请选择xlsx或者xls文件!')
            else:
                QMessageBox.warning(self, '警告', '请选择文件!')
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58

    综上所述,完整代码如下:
    table_main.py

    from PyQt5.QtWidgets import QMainWindow, QApplication, QFileDialog, QMessageBox, QTableWidgetItem
    from PyQt5.QtCore import Qt
    import sys
    import os
    import pandas as pd
    
    from ui.table_ui import Ui_MainWindow
    
    
    class TableWin(QMainWindow, Ui_MainWindow):
        def __init__(self):
            super().__init__()
            self.setupUi(self)
            self.setAcceptDrops(True)   # 设置接受拖曳动作
            self.file_path = ''     # 定义文件路径
            self.listener()     # 调用监听函数
    
        # 监听函数都写在里面
        def listener(self):
            self.choice_btn.clicked.connect(self.choice_file)
            self.open_btn.clicked.connect(self.open_file)
    
        def choice_file(self):
            now_path = os.getcwd()  # 获取当前路径
            choice_file_path = QFileDialog.getOpenFileName(self, '选择文件', now_path, 'Excel files(*.xlsx , *.xls)')
    
            # 如果路径存在,设置文件路径和输入框内容
            if choice_file_path[0]:
                self.file_path = choice_file_path[0]
                self.set_file_path_edt(choice_file_path[0])
    
        # 打开文件
        def open_file(self):
            # 判断文件路径是否有值(就是有没有选择了文件)
            if self.file_path:
                # 获取文件后缀
                file_format = self.file_path.split('.')[-1]
                # 判断文件格式是否是'xls'或者'xlsx'
                if file_format == 'xls' or file_format == 'xlsx':
                    # 使用pandas提取excel数据
                    excel_data = pd.read_excel(self.file_path)
                    # 获取excel数据行数
                    rows = excel_data.shape[0]
                    # 获取excel数据列数
                    columns = excel_data.shape[1]
                    # print(rows, columns)
    
                    # 设置总列数
                    self.data_table.setColumnCount(columns)
                    # 设置总行数
                    self.data_table.setRowCount(rows)
                    # 设置表头(excel_data.columns可以获取表头列表,默认第一列为表头)
                    self.data_table.setHorizontalHeaderLabels(excel_data.columns)
    
                    '''遍历excel中的元素,添加到tableWidget里面'''
                    # 设置写数据的当前索引(excel中的第二行对应tableWidget中的第一行,索引并不一样,所以要设置新索引跟踪tableWidget中的索引)
                    data_table_current = 0
    
                    # 插入值
                    for i in range(0, rows):
                        for j in range(columns):
                            # 创建QTableWidgetItem对象,并设置值
                            new_item = QTableWidgetItem(str(excel_data.iloc[i, j]))
                            # 设置QTableWidgetItem对象启用、可以选中和可以编辑
                            new_item.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled | Qt.ItemIsEditable)
                            # 设置QTableWidgetItem对象里面的值水平,垂直居中
                            new_item.setTextAlignment(Qt.AlignHCenter | Qt.AlignVCenter)
                            # 将新建的QTableWidgetItem添加到tableWidget中,参数分别是(行索引,列索引,QTableWidgetItem对象)
                            self.data_table.setItem(data_table_current, j, new_item)
                        # 写数据的当前索引加1
                        data_table_current += 1
    
                else:
                    QMessageBox.warning(self, '警告', '请选择xlsx或者xls文件!')
            else:
                QMessageBox.warning(self, '警告', '请选择文件!')
    
        # 设置输入框里面内容
        def set_file_path_edt(self, file_path):
            self.file_path_edt.setText(file_path)
    
        '''重写拖曳方法'''
        def dragEnterEvent(self, event):
            if event.mimeData().hasUrls:
                event.accept()
            else:
                event.ignore()
    
        def dragMoveEvent(self, event):
            if event.mimeData().hasUrls:
                try:
                    event.setDropAction(Qt.CopyAction)
                except Exception as e:
                    print(e)
                event.accept()
            else:
                event.ignore()
    
        def dropEvent(self, event):
            if event.mimeData().hasUrls:
                event.setDropAction(Qt.CopyAction)
                event.accept()
                links = []
                for url in event.mimeData().urls():
                    links.append(str(url.toLocalFile()))
                self.file_path = links[0]   # 获取文件绝对路径
                self.set_file_path_edt(self.file_path)    # 设置文件绝对路径
            else:
                event.ignore()
    
    
    if __name__ == '__main__':
        app = QApplication(sys.argv)
        table_win = TableWin()
        table_win.show()
        sys.exit(app.exec_())
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116

    运行结果:
    在这里插入图片描述

    在这里插入图片描述
    大功告成!有什么问题欢迎在评论区留言。

  • 相关阅读:
    CF1707C - DFS Trees (树上差分)
    LEADTOOLS 入门教程: 将注释刻录到 LEADDocument - C# .NET Core
    Mysql备份恢复、与日志管理
    uniapp通过功能性编码跳转到原生的app页面
    [算法刷题笔记]二叉树之左叶子之和
    python打开windows上的文本文件的注意事项
    用DIV+CSS技术设计的音乐主题网站(web前端网页制作课作业)
    mathtype在word内的简单使用
    (5)SpringMVC处理携带JSON格式(“key“:value)请求数据的Ajax请求
    05设计模式-建造型模式-建造者模式
  • 原文地址:https://blog.csdn.net/fresh_nam/article/details/126384640