Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. Qt for Python
  4. PySide & QWT object disable/destroy
Forum Update on Monday, May 27th 2025

PySide & QWT object disable/destroy

Scheduled Pinned Locked Moved Unsolved Qt for Python
7 Posts 2 Posters 454 Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • D Offline
    D Offline
    DarB
    wrote on 21 Jan 2022, 10:37 last edited by
    #1

    I am just learning OOP and PySide. I have created a code as below. The application doesn't do anything much (it's a development project in learning stages).

    import numpy as np
    import sys
    
    from qtpy.QtWidgets import (
        QWidget,
        QMainWindow,
        QVBoxLayout,
        QAction,
        QMenu,
        QLabel,
        QApplication,
        QMessageBox,
        QDesktopWidget,
    )
    from qtpy.QtCore import Qt, Slot, QPoint, QObject
    from qwt import (
        QwtPlot,
        QwtPlotMarker,
        QwtPlotGrid,
        QwtLegend,
        QwtPlotCurve,
        QwtLegendData,
    )
    
    
    class contexMenuHelper(QObject):
        def __init__(self, plot, legend, legendItem):
            super(contexMenuHelper, self).__init__()
            self.plot = plot
            self.legend = legend
            self.legendItem = legendItem
            
    
        @Slot(QPoint)
        def contextMenuSlot(self, pos):       
            context = QMenu(self.legendItem)
            context.addAction(QAction("Delete", self))
            context.exec_(self.legendItem.mapToGlobal(pos))
    
    
    class Plot(QwtPlot, QMainWindow):
        def __init__(self):
            super().__init__()
            self.initUI()
    
        def initUI(self):
            self.setAxisTitle(QwtPlot.xBottom, "X-axis")
            self.setAxisTitle(QwtPlot.yLeft, "Y-axis")
            self.setCanvasBackground(Qt.white)
            self.setAxisScale(QwtPlot.yLeft, -2, 2)
            QwtPlotGrid.make(self, color=Qt.lightGray, width=0, style=Qt.DotLine)
    
            legend = QwtLegend()
            legend.setDefaultItemMode(QwtLegendData.Checkable)
            self.insertLegend(legend, QwtPlot.RightLegend)
    
            x = np.arange(-5.0, 5.0, 0.1)
            curves = []
            curves.append(
                QwtPlotCurve.make(
                    x, np.cos(x), "Cosinus", self, linecolor="red", antialiased=True
                )
            )
            curves.append(
                QwtPlotCurve.make(
                    x, np.sin(x), "Sinus", self, linecolor="blue", antialiased=True
                )
            )
            self.helpers = dict()
            for a in curves:
                legend.legendWidget(a).setContextMenuPolicy(Qt.CustomContextMenu)
                h = contexMenuHelper(self, legend, legend.legendWidget(a))
                self.helpers[a]  = h
                legend.legendWidget(a).customContextMenuRequested.connect(h.contextMenuSlot)
    
            QwtPlotMarker.make(
                align=Qt.AlignRight | Qt.AlignTop,
                linestyle=QwtPlotMarker.HLine,
                color="black",
                plot=self,
            )
            for keys, value in self.helpers.items():
                print(keys)
                print(value)    
            # insert a vertical marker at x = 0
            QwtPlotMarker.make(
                align=Qt.AlignRight | Qt.AlignTop,
                linestyle=QwtPlotMarker.VLine,
                color="black",
                plot=self,
            )
    
            legend.checked.connect(self.showCurve)
            self.replot()
    
        @Slot(object, bool, int)
        def showCurve(self, obj, condition, num):
            obj.setVisible(not condition)
            self.replot()
    
        @Slot(object, bool, int)
        def __del__(self,  obj, condition):
            print('Destructor called, vehicle deleted.')
    
    
    class SimplePlot(QWidget):
        def __init__(self, parent=None):
            super().__init__(parent)
            layout = QVBoxLayout()
            self.setLayout(layout)
            plot = Plot()
            plot.setTitle("Trigonometric")
            self.setWindowTitle("Trigonometric")
            layout.addWidget(plot)
            label = QLabel("Press the legend to en/disable a curve")
            layout.addWidget(label)
            self.center()
    
        def center(self):
            qr = self.frameGeometry()
            cp = QDesktopWidget().availableGeometry().center()
            qr.moveCenter(cp)
            self.move(qr.topLeft())
    
        def closeEvent(self, event):
            reply = QMessageBox.question(
                self,
                "Message",
                "Are you sure to quit?",
                QMessageBox.Yes | QMessageBox.No,
                QMessageBox.No,
            )
    
            if reply == QMessageBox.Yes:
                event.accept()
            else:
                event.ignore()
    
    
    if __name__ == "__main__":
    
        app = QApplication(sys.argv)
        window = SimplePlot()
        window.show()
        window.resize(800, 600)
        sys.exit(app.exec_())
    

    I made the active legend and the context menu.
    ContextMenu
    I want to make it so that when I select "Delete" from the context menu, the corresponding function waveform in the graph and the corresponding object in the legend will be deleted.

    1 Reply Last reply
    0
    • S Offline
      S Offline
      SGaist
      Lifetime Qt Champion
      wrote on 21 Jan 2022, 20:08 last edited by
      #2

      Hi and welcome to devnet,

      One way is to keep a map of legend and curve and in the slot connected to your delete action you remove both from the plot.

      Interested in AI ? www.idiap.ch
      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

      1 Reply Last reply
      0
      • D Offline
        D Offline
        DarB
        wrote on 26 Jan 2022, 10:25 last edited by
        #3

        Hello .
        Thank you for saying hello. :)

        Using : QwtPlotCurve.detach(curves[1])

        I am able to get what I need.

        However, I really don't know how to hook this up to "Deleate" in the context menu.

        Please help me with the code .

        1 Reply Last reply
        0
        • S Offline
          S Offline
          SGaist
          Lifetime Qt Champion
          wrote on 26 Jan 2022, 20:06 last edited by
          #4

          Did you build the map I suggested ?

          Interested in AI ? www.idiap.ch
          Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

          1 Reply Last reply
          0
          • D Offline
            D Offline
            DarB
            wrote on 26 Jan 2022, 20:43 last edited by
            #5

            Hi.
            @SGaist
            Unfortunately I don't understand what you are writing about, I am new to PySide :( . Please provide clear translations.

            I made it this way.
            Please write if it is correct ?
            And how else can it be done ?

            import numpy as np
            import sys
            
            from qtpy.QtWidgets import (
                QWidget,
                QMainWindow,
                QVBoxLayout,
                QAction,
                QMenu,
                QLabel,
                QApplication,
                QMessageBox,
                QDesktopWidget,
            )
            from qtpy.QtCore import Qt, Slot, QPoint, QObject
            from qwt import (
                QwtPlot,
                QwtPlotMarker,
                QwtPlotGrid,
                QwtLegend,
                QwtPlotCurve,
                QwtLegendData,
            )
            
            
            class contexMenuHelper(QObject):
                def __init__(self, plot, legend, legendItem):
                    super(contexMenuHelper, self).__init__()
                    self.plot = plot
                    self.legend = legend
                    self.legendItem = legendItem
                    self.emlSel = QAction("Delete")
            
            
                @Slot(QPoint)
                def contextMenuSlot(self, pos):       
                    context = QMenu(self.legendItem)
                    context.addAction(self.emlSel)        
                    context.exec_(self.legendItem.mapToGlobal(pos))
                    self.emlSel.triggered.connect(self.destroy())
                
                @Slot()
                def destroy(self):
                    QwtPlotCurve.detach(self.legend)
            
                 
                    
            
            class Plot(QwtPlot, QMainWindow):
                def __init__(self):
                    super().__init__()
                    self.initUI()
            
                def initUI(self):
                    self.setAxisTitle(QwtPlot.xBottom, "X-axis")
                    self.setAxisTitle(QwtPlot.yLeft, "Y-axis")
                    self.setCanvasBackground(Qt.white)
                    self.setAxisScale(QwtPlot.yLeft, -2, 2)
                    QwtPlotGrid.make(self, color=Qt.lightGray, width=0, style=Qt.DotLine)
            
                    legend = QwtLegend()
                    legend.setDefaultItemMode(QwtLegendData.Checkable)
                    legend.resize(100,100)
                    self.insertLegend(legend, QwtPlot.RightLegend)
                    
                    x = np.arange(-5.0, 5.0, 0.1)
                    curves = []
                    curves.append(
                        QwtPlotCurve.make(
                            x, np.cos(x), "Cosinus", self, linecolor="red", antialiased=True
                        )
                    )
                    curves.append(
                        QwtPlotCurve.make(
                            x, np.sin(x), "Sinus", self, linecolor="blue", antialiased=True
                        )
                    )
            
                    self.helpers = dict()
                    for a in curves:
                        legend.legendWidget(a).setContextMenuPolicy(Qt.CustomContextMenu)
                        h = contexMenuHelper(self, a, legend.legendWidget(a))
                        self.helpers[a]  = h
                        legend.legendWidget(a).customContextMenuRequested.connect(h.contextMenuSlot)
            
            
                    QwtPlotMarker.make(
                        align=Qt.AlignRight | Qt.AlignTop,
                        linestyle=QwtPlotMarker.HLine,
                        color="black",
                        plot=self,
                    )
            
                    QwtPlotMarker.make(
                        align=Qt.AlignRight | Qt.AlignTop,
                        linestyle=QwtPlotMarker.VLine,
                        color="black",
                        plot=self,
                    )
            
                    legend.checked.connect(self.showCurve)
                    self.replot()
            
                @Slot(object, bool, int)
                def showCurve(self, obj, condition, num):
                    obj.setVisible(not condition)
                    self.replot()
            
            
            class SimplePlot(QWidget):
                def __init__(self, parent=None):
                    super().__init__(parent)
                    layout = QVBoxLayout()
                    self.setLayout(layout)
                    plot = Plot()
                    plot.setTitle("Trigonometric")
                    self.setWindowTitle("Trigonometric")
                    layout.addWidget(plot)
                    label = QLabel("Press the legend to en/disable a curve")
                    layout.addWidget(label)
                    self.center()
            
                def center(self):
                    qr = self.frameGeometry()
                    cp = QDesktopWidget().availableGeometry().center()
                    qr.moveCenter(cp)
                    self.move(qr.topLeft())
            
                def closeEvent(self, event):
                    reply = QMessageBox.question(
                        self,
                        "Message",
                        "Are you sure to quit?",
                        QMessageBox.Yes | QMessageBox.No,
                        QMessageBox.No,
                    )
            
                    if reply == QMessageBox.Yes:
                        event.accept()
                    else:
                        event.ignore()
            
            
            if __name__ == "__main__":
            
                app = QApplication(sys.argv)
                window = SimplePlot()
                window.show()
                window.resize(850, 600)
                sys.exit(app.exec_())
            
            1 Reply Last reply
            0
            • S Offline
              S Offline
              SGaist
              Lifetime Qt Champion
              wrote on 30 Jan 2022, 13:29 last edited by
              #6

              Sorry, I think I have misunderstood your answer. You have it working so I am unsure what you were asking.

              Interested in AI ? www.idiap.ch
              Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

              1 Reply Last reply
              0
              • D Offline
                D Offline
                DarB
                wrote on 30 Jan 2022, 17:52 last edited by
                #7

                It works like this. It's only working now. Compare the two codes for yourself. However, thank you very much for your support. Thanks to you, it dazzled my brain :)

                Please also note the error I made :(

                1 Reply Last reply
                0

                1/7

                21 Jan 2022, 10:37

                • Login

                • Login or register to search.
                1 out of 7
                • First post
                  1/7
                  Last post
                0
                • Categories
                • Recent
                • Tags
                • Popular
                • Users
                • Groups
                • Search
                • Get Qt Extensions
                • Unsolved