viniciusHess
viniciusHess

Reputation: 5

How to dynamically add and delete plot widgets in a QScrollArea?

I have a GUI with a button; I add a new matplotlib plot to a scroll area in another tab of the interface. And I can do that multiple times. The problem is I want to add a function where the "remove" button removes only the widget he's in.

Here's an minimal reproducible example of what I have:

import sys

from PyQt5.QtWidgets import (
    QApplication,
    QMainWindow,
    QWidget,
    QPushButton,
    QVBoxLayout,
    QHBoxLayout,
    QTabWidget,
    QScrollArea,
)

from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.backends.backend_qt5agg import NavigationToolbar2QT as NavigationToolbar

from matplotlib.figure import Figure


class MainWindow(QMainWindow):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)

        # Window
        self.setWindowTitle("DataVisualizationPrototype")
        self.setGeometry(400, 200, 900, 800)
        self.activateWindow()
        self.raise_()

        self.tab_widget = TabWidget()
        self.setCentralWidget(self.tab_widget)


class TabWidget(QTabWidget):
    def __init__(self, parent=None):
        super(TabWidget, self).__init__(parent)

        self.tab1 = QWidget()
        self.plot_button = QPushButton("Add plot")
        lay = QVBoxLayout(self.tab1)
        lay.addWidget(self.plot_button)

        self.tab2 = QWidget()
        self.scroll_area = QScrollArea()
        self.scroll_container = QWidget()
        self.scroll_area.setWidgetResizable(True)
        self.scroll_area.setWidget(self.scroll_container)
        self.scroll_layout = QHBoxLayout(self.scroll_container)
        lay = QVBoxLayout(self.tab2)
        lay.addWidget(self.scroll_area)

        self.addTab(self.tab1, "Home")
        self.addTab(self.tab2, "Comparison")

        self.plot_button.clicked.connect(self.plot)

    def plot(self):
        canvas = FigureCanvas(Figure())
        ax = canvas.figure.add_subplot(111)
        toolbar = NavigationToolbar(canvas, self)
        dltbtn = QPushButton("Remove")

        container = QWidget()
        lay = QVBoxLayout(container)
        lay.addWidget(canvas)
        lay.addWidget(toolbar)
        lay.addWidget(dltbtn)

        self.scroll_layout.addWidget(container)
        container.setMinimumWidth(400)

        ax.plot([1, 2, 3, 4])
        ax.set_ylabel("some numbers")


def main():

    app = QApplication(sys.argv)
    view = MainWindow()
    view.show()

    sys.exit(app.exec())


if __name__ == "__main__":
    main()

Can anybody help write a command to delete the 'container' which the remove button is in?

Upvotes: 0

Views: 401

Answers (1)

eyllanesc
eyllanesc

Reputation: 243993

The logic is to eliminate the widget container since if it is eliminated then its children as well, and for this it is enough to invoke the deleteLater method when the clicked signal is emitted.

dltbtn.clicked.connect(container.deleteLater)

Upvotes: 1

Related Questions