0

I'm looking for help regarding how to add a QTableView inside a QGroupBox (this is because i need to create 4 QTableView each displaying one of each possible Status 'In QC','Ready for QC','In Progress','Pending').

The following code currently generates a program that displays a Single QTableView, that refreshes every 5 seconds with new data, the only one that matters is the Status (currently represented as column F) as the rest of the data is displayed for identification purposes. (Please note that in this example i use a code that generates automatically data to display in the QTableView, as this Table actually feeds from an Excel file, going to attach the code that reads the excel file at the end of this post):

import sys
import pandas as pd

from PyQt5.QtCore import pyqtSignal, pyqtSlot, QAbstractTableModel, QObject, Qt
from PyQt5.QtGui import QBrush
from PyQt5.QtWidgets import QApplication, QTableView

import threading


class PandasManager(QObject):
    dataFrameChanged = pyqtSignal(pd.DataFrame)

    def start(self):
        self.t = threading.Timer(0, self.load)
        self.t.start()

    def load(self):
        import random

        headers = list("ABCDEFG")
        data = [random.sample(range(255), len(headers)) for _ in headers]

        for d in data:
            d[5] = random.choice(["Ready for QC", "In Progress", "Pending", "In QC"])

        df = pd.DataFrame(data, columns=headers,)

        self.dataFrameChanged.emit(df)
        self.t = threading.Timer(5.0, self.load)
        self.t.start()

    def stop(self):
        self.t.cancel()


class PandasModel(QAbstractTableModel):
    def __init__(self, df=pd.DataFrame()):
        QAbstractTableModel.__init__(self)
        self._df = df

    @pyqtSlot(pd.DataFrame)
    def setDataFrame(self, df):
        self.beginResetModel()
        self._df = df
        self.endResetModel()

    def rowCount(self, parent=None):
        return self._df.shape[0]

    def columnCount(self, parent=None):
        return self._df.shape[1]

    def data(self, index, role=Qt.DisplayRole):
        if index.isValid():
            if role == Qt.BackgroundRole:
                if self.columnCount() >= 6:
                    it = self._df.iloc[index.row(), 5]
                    if it == "Ready for QC":
                        return QBrush(Qt.yellow)
                    if it == "In Progress":
                        return QBrush(Qt.green)
            if role == Qt.DisplayRole:
                return str(self._df.iloc[index.row(), index.column()])

    def headerData(self, col, orientation, role):
        if orientation == Qt.Horizontal and role == Qt.DisplayRole:
            return self._df.columns[col]
        return None


if __name__ == "__main__":
    app = QApplication(sys.argv)
    w = QTableView()
    model = PandasModel()
    w.setModel(model)
    w.show()

    manager = PandasManager()
    manager.dataFrameChanged.connect(model.setDataFrame)
    manager.start()

    ret = app.exec_()

    manager.stop()

    sys.exit(ret)

How the program currently looks

Hopefully this explains my question, as i have been struggling on how to use QGroupBox and how to add the QTableView as I'm using it this way.

Kind Regards,

PS: Attaching code that reads from an excel file

def load(self):
    weekNumber = date.today().isocalendar()[1]
    aux = pd.read_excel("PCS tasks 2020.xlsm", sheet_name="W" + str(weekNumber))
    today = datetime.today()
    df = aux[aux["Date Received"] == today.strftime("%Y-%d-%m")]
    df = df[
        [
            "Requestor",
            "Subject",
            "Task type",
            "Created by",
            "QC Executive",
            "Status",
        ]
    ].fillna("")
    df = df[df["Status"] != "Completed"]
    self.dataFrameChanged.emit(df)
    self.t = threading.Timer(5.0, self.load)
    self.t.start()
Magthuzad
  • 160
  • 1
  • 1
  • 10

1 Answers1

0

As the example of the QGroupBox docs shows, you must use a layout that allows you to distribute the widgets (QGridLayout, QHBoxLayout, QVBoxLayout, etc.) and set it in the QGroupBox:

if __name__ == "__main__":
    app = QApplication(sys.argv)

    w = QTableView()
    model = PandasModel()
    w.setModel(model)

    groupbox = QGroupBox()
    lay = QVBoxLayout()
    lay.addWidget(w)
    groupbox.setLayout(lay)
    groupbox.show()

    manager = PandasManager()
    manager.dataFrameChanged.connect(model.setDataFrame)
    manager.start()

    ret = app.exec_()

    manager.stop()

    sys.exit(ret)
eyllanesc
  • 235,170
  • 19
  • 170
  • 241