Search code examples
pythonpyqtpyqt5qgroupbox

Group buttons aesthetically in PyQt5


I want to do something like this:

enter image description here

I'm not being able to find any way to group the buttons like that. Namely, to enclose them in rectangles and put a 'title' to that 'button section'.

Is it possible to do this in PyQt5?


Solution

  • You can use a QGroupBox next to a QToolButton and a QLabel:

    import sys
    from PyQt5 import QtCore, QtGui, QtWidgets
    
    data = [{
            "title": " Y Axis Variables",
            "buttons": [{
                    "text": "Add/Quit/Modify",
                    "path_icon": "Add.png"
                },
                {
                    "text": "Calculate Var",
                    "path_icon": "calculate.png"
                },
                {
                    "text": "Delete Cal Var",
                    "path_icon": "delete.png"
                }
            ]
        },
        {
            "title": "Project",
            "buttons": [{
                    "text": "Save",
                    "path_icon": "save.png"
                },
                {
                    "text": "Add Tab",
                    "path_icon": "add.png"
                }
            ]
        }
    ]
    
    
    class ToolButton(QtWidgets.QWidget):
        def __init__(self, text, path_icon, parent=None):
            super(ToolButton, self).__init__(parent)
            lay = QtWidgets.QVBoxLayout(self)
            toolButton = QtWidgets.QToolButton()
            toolButton.setIcon(QtGui.QIcon(path_icon))
            toolButton.setIconSize(QtCore.QSize(64, 64))
            label = QtWidgets.QLabel(text)
            lay.addWidget(toolButton, 0, QtCore.Qt.AlignCenter)
            lay.addWidget(label, 0, QtCore.Qt.AlignCenter)
            lay.setContentsMargins(0, 0, 0, 0)
    
    
    class GroupButton(QtWidgets.QGroupBox):
        def __init__(self, info, parent=None):
            super(GroupButton, self).__init__(parent)
            title = info["title"]
            self.setTitle(title)
            hlay = QtWidgets.QHBoxLayout(self)
            for info_button in info["buttons"]:
                text = info_button["text"]
                path_icon = info_button["path_icon"]
                btn = ToolButton(text, path_icon)
                hlay.addWidget(btn)
            hlay.setContentsMargins(5, 5, 5, 5)
            self.setFixedSize(self.sizeHint())
    
    class Widget(QtWidgets.QWidget):
        def __init__(self, parent=None):
            super(Widget, self).__init__(parent)
            vlay = QtWidgets.QVBoxLayout(self)
            hlay = QtWidgets.QHBoxLayout()
            for val in data:
                gb = GroupButton(val)
                hlay.addWidget(gb)
            hlay.addStretch()
            vlay.addLayout(hlay)
            vlay.addStretch()
    
    if __name__ == '__main__':
        app = QtWidgets.QApplication(sys.argv)
        w = Widget()
        w.resize(640, 480)
        w.show()
        sys.exit(app.exec_())
    

    enter image description here