我正在尝试在PyQt5中创建一个qTableWidget,这将允许我使用一个复选框进行选择,该复选框过滤Pandas DataFrame,然后在GUI中显示该数据。
我可以让它第一次运行代码,并且它可以像我期望的那样显示数据。 但是,当您尝试对其进行刷新时,它不会将新数据加载到qTableWidget中。 没有任何错误消息,并且如果您打印DataFrame,它将按我的期望加载新数据,只是它没有显示在GUI中。
我在这里搜索了类似的问题,但是找不到遇到相同问题的人。
我需要它来刷新表在同一个界面中我的真实数据,数据帧是从选择一个新的组时会拉最新的数据,可能是跑的无限次的API调用产生的。
这是我要干的事,我试图添加评论以尽我所能解释
import sys
from PyQt5 import QtWidgets, QtGui, QtCore
import pandas as pd
class TableWidget(QtWidgets.QTableWidget):
def __init__(self, tab2_df, parent=None):
QtWidgets.QTableWidget.__init__(self,parent)
tab2_df = tab2_df
nRows = len(tab2_df.index)
nColumns = len(tab2_df.columns)
self.setRowCount(nRows)
self.setColumnCount(nColumns)
for i in range(self.rowCount()):
for j in range(self.columnCount()):
x = "{}".format(tab2_df.iloc[i, j])
self.setItem(i, j, QtWidgets.QTableWidgetItem(x))
print(tab2_df) #validating that the new df is received
class Window(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super().__init__()
self.title = "Reporting Test"
self.left = 400
self.top = 50
self.width = 1300
self.height = 700
self.setWindowTitle(self.title)
self.setGeometry(self.left, self.top, self.width, self.height)
#initialize window with tabs
self.table_widget = MyTableWidget(self)
self.setCentralWidget(self.table_widget)
self.show()
class MyTableWidget(QtWidgets.QWidget):
def __init__(self, parent):
super(QtWidgets.QWidget, self).__init__(parent)
self.layout = QtWidgets.QVBoxLayout(self)
self.tabs = QtWidgets.QTabWidget()
self.tab1 = QtWidgets.QWidget() #Group select Tab
self.tab2 = QtWidgets.QWidget() #DataFrame Tab
# Name and add first Tab to Layout
self.tabs.addTab(self.tab1,"Group Select")
self.layout.addWidget(self.tabs)
self.setLayout(self.layout)
# Sample DataFrame for demonstation
self.tab1.df = pd.DataFrame({'Name':['Tom', 'Jack', 'Steve', 'Ricky'],'Age':[28,34,29,42]})
# Filter dataframe into a list to show as checkboxes
self.tab1.group = self.tab1.df[["Name"]]
self.tab1.groupList = self.tab1.group['Name'].tolist()
self.tab1.listLabel = ["",] * len(self.tab1.groupList)
self.tab1.grid = QtWidgets.QGridLayout()
self.tab1.setLayout(self.tab1.grid)
# Populate the checkboxes with the list
for i, v in enumerate(self.tab1.groupList):
self.tab1.groupList[i] = QtWidgets.QCheckBox(v)
self.tab1.listLabel[i] = QtWidgets.QLabel()
self.tab1.grid.addWidget(self.tab1.groupList[i], i, 0)
# Add the checkboxes into the tab
self.tab1.button = QtWidgets.QPushButton("Select Group")
self.tab1.button.clicked.connect(self.checkboxChanged)
self.tab1.labelResult = QtWidgets.QLabel()
self.tab1.grid.addWidget(self.tab1.button, i+1, 0, 1,2)
self.tab1.setLayout(self.tab1.grid)
def checkboxChanged(self):
# Clear the previous tab
self.tabs.clear()
# Add a new tab for the loaded data
self.tabs.addTab(self.tab2,"Loaded Data")
# Match the ticked checkbox to the DataFrame and filter to a new DataFrame
self.tab1.labelResult.setText("")
for i, v in enumerate(self.tab1.groupList):
self.tab1.listLabel[i].setText("True" if v.checkState() else "False")
self.tab1.labelResult.setText("{}, {}".format(self.tab1.labelResult.text(),
self.tab1.listLabel[i].text()))
self.tab1.groupList2 = self.tab1.group['Name'].tolist()
checked2 = str(self.tab1.labelResult.text()).split(',')
result = list(filter(None, checked2))
checked_list = {"Name":self.tab1.groupList2, "checked":result}
checked_list_df = pd.DataFrame(checked_list)
checked_list_filtered_df = checked_list_df[checked_list_df.checked.str.contains("true", case=False)]
self.tab1.filteredGroup_df = checked_list_filtered_df
group_select_df = pd.merge(self.tab1.group, self.tab1.filteredGroup_df, on="Name", how="inner")
group_select_list = group_select_df["Name"].tolist()
tab2_df = self.tab1.df[self.tab1.df["Name"].isin(group_select_list)]
# Populate the filtered DataFrame onto a TableWidget and populate this into the tab
self.tab2.tableWidget = TableWidget(tab2_df, self)
# Set headings and style for TableWidget
self.tab2.tableWidget.setHorizontalHeaderLabels(("Name", "Age"))
stylesheet3 = "::section{font: bold 18px}"
self.tab2.tableWidget.horizontalHeader().setStyleSheet(stylesheet3)
# Add button to refresh the data with a new group filter
self.tab2.button = QtWidgets.QPushButton("Refresh", self.tab2)
self.tab2.button.clicked.connect(self.refresh_button)
self.tab2.layout = QtWidgets.QVBoxLayout()
self.tab2.layout.addWidget(self.tab2.tableWidget)
self.tab2.layout.addWidget(self.tab2.button)
self.tab2.setLayout(self.tab2.layout)
# Refresh button that will clear the previous TableWidget and load the Group Select Tab to generate new data
def refresh_button(self):
# Clear the previous tab
self.tabs.clear()
# Clear the TableWidget
self.tab2.tableWidget.setRowCount(0)
# Load the Group Select Tab to select the new group
self.tabs.addTab(self.tab1,"Group Select")
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
window = Window()
window.show()
sys.exit(app.exec_())
我敢肯定,很多事情都可以做得更好,我正在尝试学习,但是我只是想不通。