有没有一种方法可以多次写入qTableWidget?

时间:2020-04-29 13:49:49

标签: python-3.x pandas pyqt5

我正在尝试在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_())

我敢肯定,很多事情都可以做得更好,我正在尝试学习,但是我只是想不通。

0 个答案:

没有答案