qtpandas
一、qtpandas 是什么
- Pandas 是 Python 的一个很好用的数据分析包,为了将这个数据分析包很好地结合 PyQt,有开发者专门开发另一个模块库——qtpandas。
- 安装 qtpandas 之前应先安装 Pandas,安装的方法可以百度。
- 安装完 qtpandas 之后要做的是测试一下模块库能不能正常使用,可以使用如下代码:
# -*- coding:utf-8 -*- # Time : 2019/10/02 下午 3:35 # Author : 御承扬 # e-mail:2923616405@qq.com # project: PyQt5 # File : testing.py # @software: PyCharm from __future__ import unicode_literals from __future__ import print_function from __future__ import division from __future__ import absolute_import from PyQt5.QtGui import QIcon from future import standard_library standard_library.install_aliases() import pandas import numpy import sys from qtpandas.excepthook import excepthook # Use QtGui from the compat module to take care if correct sip version, etc. from qtpandas.compat import QtGui from qtpandas.models.DataFrameModel import DataFrameModel from qtpandas.views.DataTableView import DataTableWidget # from qtpandas.views._ui import icons_rc if __name__ == '__main__': standard_library.install_aliases() sys.excepthook = excepthook model = DataFrameModel() app = QtGui.QApplication([]) widget = DataTableWidget() widget.setWindowTitle("qtPandas Demo") widget.setWindowIcon(QIcon("./images/Python2.ico")) widget.resize(500, 300) widget.show() widget.setViewModel(model) data = { 'A': [10, 11, 12], 'B': [20, 21, 22], 'C': ['Peter Pan', 'Cpt. Hook', 'Tinkerbell'] } df = pandas.DataFrame(data) df['A'] = df['A'].astype(numpy.int8) df['B'] = df['B'].astype(numpy.float16) model.setDataFrame(df) app.exec_()
- 在运行之前,需要对 qtpandas 模块库中的某个方法进行适当修改以适应最新的 Pandas,根据 Pandas 的官方文档,从 v0.20 之后对 from pandas.tslib import NaTType 的使用应当更改为 type(pandas.NaT),使用了这个语法的方法是 qtpandas.view 中的 EditDialogs.py 里的 accept 方法,修改后如下:
import pandas def accept(self): super(AddAttributesDialog, self).accept() newColumn = self.columnNameLineEdit.text() dtype = SupportedDtypes.dtype(self.dataTypeComboBox.currentText()) defaultValue = self.defaultValueLineEdit.text() try: if dtype in SupportedDtypes.intTypes() + SupportedDtypes.uintTypes(): defaultValue = int(defaultValue) elif dtype in SupportedDtypes.floatTypes(): defaultValue = float(defaultValue) elif dtype in SupportedDtypes.boolTypes(): defaultValue = defaultValue.lower() in ['t', '1'] elif dtype in SupportedDtypes.datetimeTypes(): defaultValue = Timestamp(defaultValue) if isinstance(defaultValue, type(pandas.NaT)): defaultValue = Timestamp('') else: defaultValue = dtype.type() except ValueError as e: defaultValue = dtype.type() self.accepted.emit(newColumn, dtype, defaultValue)
- 运行效果如下:
二、qtpandas 的使用
1、准备 UI 界面
- 本步骤需要与 pyqt5_tools 的 designer 结合使用,在 Qt Designer 中不像写 python 脚本那么自由,要引入 qtpandas 的使用,必须使用所谓的提升窗口控件的功能,具体步骤如下:
- 1、创建一个 MainMidow
- 2、从 Container 中找到 widget 并托放到 MainWindow 中。
- 3、在 widget 中鼠标右键,打开 Promoted Widgets 命令,打开如下图窗口并填写如下图数据:
- 4、 点击 Add 命令后,在点击 Promote 按钮
- 5、拖动两个 pushButton 控件放置到 MainWindow 中,如下图布局:
- 6、保存 UI 文件为 pandastablewidget.ui,并且是保存到工程目录中,方便接下来的操作。
- 7、打开 Pycharm 到刚才的 UI 文件所在的工程目录,使用 .ui 转 .py 文件的命令,将 UI 文件转换为 PY 文件,转换之后如下:
# -*- coding: utf-8 -*- # Form implementation generated from reading ui file 'pandastablewidget.ui' # # Created by: PyQt5 UI code generator 5.11.3 # # WARNING! All changes made in this file will be lost! from PyQt5 import QtCore, QtGui, QtWidgets from qtpandas.views.DataTableView import DataTableWidget class Ui_MainWindow(object): def setupUi(self, MainWindow): MainWindow.setObjectName("MainWindow") MainWindow.resize(800, 600) self.centralwidget = QtWidgets.QWidget(MainWindow) self.centralwidget.setObjectName("centralwidget") self.pandastablewidget = DataTableWidget(self.centralwidget) self.pandastablewidget.setGeometry(QtCore.QRect(10, 60, 591, 451)) self.pandastablewidget.setObjectName("pandastablewidget") self.pushButton = QtWidgets.QPushButton(self.centralwidget) self.pushButton.setGeometry(QtCore.QRect(630, 90, 93, 28)) self.pushButton.setObjectName("pushButton") self.pushButton_2 = QtWidgets.QPushButton(self.centralwidget) self.pushButton_2.setGeometry(QtCore.QRect(640, 320, 93, 28)) self.pushButton_2.setObjectName("pushButton_2") MainWindow.setCentralWidget(self.centralwidget) self.menubar = QtWidgets.QMenuBar(MainWindow) self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 26)) self.menubar.setObjectName("menubar") MainWindow.setMenuBar(self.menubar) self.statusbar = QtWidgets.QStatusBar(MainWindow) self.statusbar.setObjectName("statusbar") MainWindow.setStatusBar(self.statusbar) self.retranslateUi(MainWindow) QtCore.QMetaObject.connectSlotsByName(MainWindow) def retranslateUi(self, MainWindow): _translate = QtCore.QCoreApplication.translate MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow")) self.pushButton.setText(_translate("MainWindow", "数据初始化")) self.pushButton_2.setText(_translate("MainWindow", "保存数据"))
2、使用 UI 界面
- 在 pandastablewidget.py 的同级目录里面新建一个 data 文件夹,将本文开头的资源下载并存放到 data 文件夹中,文件名为:fund_data.xlsx
- 接着在 pandastablewidget.py 同级目录新建一个 python 脚本,脚本代码如下:
# -*- coding:utf-8 -*- # Time : 2019/10/03 下午 2:42 # Author : 御承扬 # e-mail:2923616405@qq.com # project: PyQt5 # File : pandas_pyqt.py # @software: PyCharm import sys from PyQt5.QtCore import * from PyQt5.QtGui import * from PyQt5.QtWidgets import * from QtPandas的应用.pandastablewidget import Ui_MainWindow from qtpandas.models.DataFrameModel import DataFrameModel import pandas as pd class MainWindow(QMainWindow, Ui_MainWindow): def __init__(self, parent=None): super(MainWindow, self).__init__(parent) self.setWindowTitle("QtPandas") self.setWindowIcon(QIcon("./images/Python2.ico")) self.setupUi(self) widget = self.pandastablewidget widget.resize(600, 500) self.model = DataFrameModel() widget.setViewModel(self.model) self.df = pd.read_excel(r'./data/fund_data.xlsx', encoding='gbk') self.df_original = self.df.copy() self.model.setDataFrame(self.df) @pyqtSlot() def on_pushButton_clicked(self): self.model.setDataFrame(self.df_original) @pyqtSlot() def on_pushButton_2_clicked(self): self.df.to_excel(r'./data/fund_data_new1.xlsx') if __name__ == "__main__": app = QApplication(sys.argv) ui = MainWindow() ui.show() sys.exit(app.exec_())
- 运行效果如下: