gpt4 book ai didi

python - 在 QML 中显示 pandas 数据框

转载 作者:行者123 更新时间:2023-12-01 01:06:22 25 4
gpt4 key购买 nike

我有 2 个 pandas dataframes,一个有 6 行7 列,另一个有 21 行12 列,我想使用 QML 显示它们,同时谷歌搜索我了解了 TableView TableView QML Type 。在该示例中,数据已输入到 ListElement 中并且正在显示。但就我而言,数据来自 python pandas dataframe,我如何从 pandas 直接获取列和行到 QML 中,我应该在 listelement 下创建这些列吗?任何帮助将不胜感激

注意:我使用QtWidgets来显示数据框,它只是一个拖放表格 View ,并使用创建的模型并使用tableView.setModel设置它们(模型)。但我对 QML 有点一无所知

最佳答案

您可以创建一个继承自 QAbstractTableModel 的类,如 this old answer 中实现的那样。并使用 QTableView QtQuick 2.12 是在 Qt 5.12 中发布的,因为它支持 QAbstractTableModel 类型模型,因此您必须使用最新版本的 PyQt5。

ma​​in.py

from PyQt5 import QtCore, QtGui, QtQml
import numpy as np
import pandas as pd

class DataFrameModel(QtCore.QAbstractTableModel):
DtypeRole = QtCore.Qt.UserRole + 1000
ValueRole = QtCore.Qt.UserRole + 1001

def __init__(self, df=pd.DataFrame(), parent=None):
super(DataFrameModel, self).__init__(parent)
self._dataframe = df

def setDataFrame(self, dataframe):
self.beginResetModel()
self._dataframe = dataframe.copy()
self.endResetModel()

def dataFrame(self):
return self._dataframe

dataFrame = QtCore.pyqtProperty(pd.DataFrame, fget=dataFrame, fset=setDataFrame)

@QtCore.pyqtSlot(int, QtCore.Qt.Orientation, result=str)
def headerData(self, section: int, orientation: QtCore.Qt.Orientation, role: int = QtCore.Qt.DisplayRole):
if role == QtCore.Qt.DisplayRole:
if orientation == QtCore.Qt.Horizontal:
return self._dataframe.columns[section]
else:
return str(self._dataframe.index[section])
return QtCore.QVariant()

def rowCount(self, parent=QtCore.QModelIndex()):
if parent.isValid():
return 0
return len(self._dataframe.index)

def columnCount(self, parent=QtCore.QModelIndex()):
if parent.isValid():
return 0
return self._dataframe.columns.size

def data(self, index, role=QtCore.Qt.DisplayRole):
if not index.isValid() or not (0 <= index.row() < self.rowCount() \
and 0 <= index.column() < self.columnCount()):
return QtCore.QVariant()
row = self._dataframe.index[index.row()]
col = self._dataframe.columns[index.column()]
dt = self._dataframe[col].dtype

val = self._dataframe.iloc[row][col]
if role == QtCore.Qt.DisplayRole:
return str(val)
elif role == DataFrameModel.ValueRole:
return val
if role == DataFrameModel.DtypeRole:
return dt
return QtCore.QVariant()

def roleNames(self):
roles = {
QtCore.Qt.DisplayRole: b'display',
DataFrameModel.DtypeRole: b'dtype',
DataFrameModel.ValueRole: b'value'
}
return roles

if __name__ == "__main__":
import os
import sys

app = QtGui.QGuiApplication(sys.argv)
df = pd.DataFrame(np.random.randint(0, 100, size=(6, 7)), columns=list('ABCDEFG'))
print(df)
model = DataFrameModel(df)
engine = QtQml.QQmlApplicationEngine()
engine.rootContext().setContextProperty("table_model", model)
qml_path = os.path.join(os.path.dirname(__file__), "main.qml")
engine.load(QtCore.QUrl.fromLocalFile(qml_path))
if not engine.rootObjects():
sys.exit(-1)
engine.quit.connect(app.quit)
sys.exit(app.exec_())

ma​​in.qml

import QtQuick 2.12
import QtQuick.Controls 2.4
import QtQuick.Window 2.11

Window {
visible: true
width: 640
height: 480
title: qsTr("Hello World")
color: '#222222'

TableView {
id: tableView

columnWidthProvider: function (column) { return 100; }
rowHeightProvider: function (column) { return 60; }
anchors.fill: parent
leftMargin: rowsHeader.implicitWidth
topMargin: columnsHeader.implicitHeight
model: table_model
delegate: Rectangle {
color: parseFloat(display) > 50 ? 'green' : 'red'
Text {
text: display
anchors.fill: parent
anchors.margins: 10
color: 'white'
font.pixelSize: 15
verticalAlignment: Text.AlignVCenter
}
}
Rectangle { // mask the headers
z: 3
color: "#222222"
y: tableView.contentY
x: tableView.contentX
width: tableView.leftMargin
height: tableView.topMargin
}

Row {
id: columnsHeader
y: tableView.contentY
z: 2
Repeater {
model: tableView.columns > 0 ? tableView.columns : 1
Label {
width: tableView.columnWidthProvider(modelData)
height: 35
text: table_model.headerData(modelData, Qt.Horizontal)
color: '#aaaaaa'
font.pixelSize: 15
padding: 10
verticalAlignment: Text.AlignVCenter

background: Rectangle { color: "#333333" }
}
}
}
Column {
id: rowsHeader
x: tableView.contentX
z: 2
Repeater {
model: tableView.rows > 0 ? tableView.rows : 1
Label {
width: 40
height: tableView.rowHeightProvider(modelData)
text: table_model.headerData(modelData, Qt.Vertical)
color: '#aaaaaa'
font.pixelSize: 15
padding: 10
verticalAlignment: Text.AlignVCenter

background: Rectangle { color: "#333333" }
}
}
}

ScrollIndicator.horizontal: ScrollIndicator { }
ScrollIndicator.vertical: ScrollIndicator { }
}
}

enter image description here

我用过:

  • Python 3.7.2
  • PyQt5 5.12.1
  • Qt 5.12.2
  • Pandas 0.24.1

注意:如果您想在 PySide2 中使用该示例,您只需将 pyqtProperty 更改为 PropertypyqtSlotSlotPyQt5PySide2

关于python - 在 QML 中显示 pandas 数据框,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55310051/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com