pythonpyqtpyqt5qgroupbox

Create Groupboxes conditionally from lists


I have the following lists that are automatically generated with which I want to create groupboxes with PyQt5:

Country = ['France', 'France', 'Germany', 'Austria', 'Austria','Spain', 'Portugal','Portugal','Portugal','Spain']
Date = ['26.04', '14.05', '25.02', '18.04','15.06','18.09', '15.05', '28.03', '09.09', '10.10']
Lines = ['Line1', 'Line2', 'Line3', 'Line4', 'Line5', 'Line6', 'Line7', 'Line8', 'Line9', 'Line10']

I know that I can get this type of Groupbox that would look like a table with the following code:

Unified_groupbox

import sys
from PyQt5 import QtGui, QtCore, QtWidgets
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *

class MainWindow(QMainWindow):

    def __init__(self):
        super().__init__()

        Country = ['France', 'France', 'Germany', 'Austria', 'Austria','Spain', 'Portugal','Portugal','Portugal','Spain']
        Date = ['26.04', '14.05', '25.02', '18.04','15.06','18.09', '15.05', '28.03', '09.09', '10.10']
        Lines = ['Line1', 'Line2', 'Line3', 'Line4', 'Line5', 'Line6', 'Line7', 'Line8', 'Line9', 'Line10']


        self.setGeometry(100, 100, 800, 600)
        self.setWindowTitle('Window')
        self.centralWidget = QWidget()
        self.setCentralWidget(self.centralWidget)
        self.mainB  = QHBoxLayout()


        self.GB1 = QGroupBox("")
        self.GB1.setStyleSheet('QGroupBox {'
                 'border: 0px solid gray; }')
        self.GB1.setFixedHeight(250)
        self.GB1.setFixedWidth(250)

        self.mainB.addWidget(self.GB1)

        grid1 = QGridLayout()
        for i in range(0,len(Country)):
           grid1.addWidget(QLabel(Country[i]), i, 0)
           grid1.addWidget(QLabel(Date[i]), i, 1)
           grid1.addWidget(QLabel(Lines[i]), i, 2)


        self.GB1.setLayout(grid1)

        self.centralWidget.setLayout(self.mainB)


def main():
    app = QApplication([])
    mainWin = MainWindow()
    mainWin.show()
    app.exec_()

if __name__ == '__main__':
   main()

However, I would like to create Groupboxes that would combine elements that correspond to a same 'Country' in the first list when that country occurs successively.

It might be better to visualize it by seeing an example of what I intend to do below:

Separated_groupboxes

Is there a way to generate those groupboxes automatically to achieve the intended result?


Solution

  • The key to the solution is to group the data, in this case I use a dictionary where each key is the country, and its value is a list of date and line tuples.

    import sys
    from PyQt5 import QtGui, QtCore, QtWidgets
    
    
    class MainWindow(QtWidgets.QMainWindow):
        def __init__(self):
            super().__init__()
    
            Country = ['France', 'France', 'Germany', 'Austria', 'Austria','Spain', 'Portugal','Portugal','Portugal','Spain']
            Date = ['26.04', '14.05', '25.02', '18.04','15.06','18.09', '15.05', '28.03', '09.09', '10.10']
            Lines = ['Line1', 'Line2', 'Line3', 'Line4', 'Line5', 'Line6', 'Line7', 'Line8', 'Line9', 'Line10']
    
            central_widget = QtWidgets.QWidget()
            self.setCentralWidget(central_widget)
    
            lay = QtWidgets.QVBoxLayout(central_widget)
    
            d = {}
            for country, date, line in zip(Country, Date, Lines):
                if country in d:
                    d[country].append((date, line))
                else:
                    d[country] = [(date, line)]
    
            for country, content in d.items():
                groub_box = QtWidgets.QGroupBox(country)
                grid_layout = QtWidgets.QGridLayout()
                groub_box.setLayout(grid_layout)
                lay.addWidget(groub_box)
    
                for row, (date, line) in enumerate(content):
                    grid_layout.addWidget(QtWidgets.QLabel(date), row, 0)
                    grid_layout.addWidget(QtWidgets.QLabel(line), row, 1)
    
    
    def main():
        import sys
    
        app = QtWidgets.QApplication(sys.argv)
        mainWin = MainWindow()
        mainWin.show()
        sys.exit(app.exec_())
    
    
    if __name__ == "__main__":
        main()