dynamically adding and removing widgets in PyQt

前端 未结 3 667
无人及你
无人及你 2020-12-07 23:53

using PyQt, I am trying to create an interface for which I can add or remove widget dynamically. I want to define a separate class for the widget that will be added or remov

相关标签:
3条回答
  • 2020-12-08 00:12

    Here is a little change that will make the button delete itself once clicked:

    from PyQt4 import QtGui, QtCore
    import sys
    
    class Main(QtGui.QMainWindow):
        def __init__(self, parent = None):
            super(Main, self).__init__(parent)
    
            # main button
            self.addButton = QtGui.QPushButton('button to add other widgets')
            self.addButton.clicked.connect(self.addWidget)
    
            # scroll area widget contents - layout
            self.scrollLayout = QtGui.QFormLayout()
    
            # scroll area widget contents
            self.scrollWidget = QtGui.QWidget()
            self.scrollWidget.setLayout(self.scrollLayout)
    
            # scroll area
            self.scrollArea = QtGui.QScrollArea()
            self.scrollArea.setWidgetResizable(True)
            self.scrollArea.setWidget(self.scrollWidget)
    
            # main layout
            self.mainLayout = QtGui.QVBoxLayout()
    
            # add all main to the main vLayout
            self.mainLayout.addWidget(self.addButton)
            self.mainLayout.addWidget(self.scrollArea)
    
            # central widget
            self.centralWidget = QtGui.QWidget()
            self.centralWidget.setLayout(self.mainLayout)
    
            # set central widget
            self.setCentralWidget(self.centralWidget)
    
        def addWidget(self):
            self.scrollLayout.addRow(TestButton()) 
    
    
    class TestButton(QtGui.QPushButton):
      def __init__( self, parent=None):
          super(TestButton, self).__init__(parent)
          self.setText("I am in Test widget")
          self.clicked.connect(self.deleteLater)
    
    
    app = QtGui.QApplication(sys.argv)
    myWidget = Main()
    myWidget.show()
    app.exec_()
    

    This way it shouldn't mem leak when deleted and the button can actually be used for stuff. I follow this pattern for progress bars by the dozens for downloads and chunks monitoring and it works just fine even with threading and multi processing. And not the easy QThreads...

    0 讨论(0)
  • 2020-12-08 00:18

    Actually, it does work. Problem is, your Test widget has a QPushButton without any layout management. So it can't calculate its minimumSize with taking the button into consideration. When you put that widget in a layout, it just shrinks to 0 (since a QWidget has no default minimumSize) and you don't see anything.

    You have two choices, either you manually manage layout and enter a needless world of pain, or you rely on layout managers. In general, you should prefer the latter.

    I would re-write your script like this (Although I'm not sure why you use QFormLayout, I leave it as it is.):

    from PyQt4 import QtGui, QtCore
    import sys
    
    class Main(QtGui.QMainWindow):
        def __init__(self, parent = None):
            super(Main, self).__init__(parent)
    
            # main button
            self.addButton = QtGui.QPushButton('button to add other widgets')
            self.addButton.clicked.connect(self.addWidget)
    
            # scroll area widget contents - layout
            self.scrollLayout = QtGui.QFormLayout()
    
            # scroll area widget contents
            self.scrollWidget = QtGui.QWidget()
            self.scrollWidget.setLayout(self.scrollLayout)
    
            # scroll area
            self.scrollArea = QtGui.QScrollArea()
            self.scrollArea.setWidgetResizable(True)
            self.scrollArea.setWidget(self.scrollWidget)
    
            # main layout
            self.mainLayout = QtGui.QVBoxLayout()
    
            # add all main to the main vLayout
            self.mainLayout.addWidget(self.addButton)
            self.mainLayout.addWidget(self.scrollArea)
    
            # central widget
            self.centralWidget = QtGui.QWidget()
            self.centralWidget.setLayout(self.mainLayout)
    
            # set central widget
            self.setCentralWidget(self.centralWidget)
    
        def addWidget(self):
            self.scrollLayout.addRow(Test())
    
    
    class Test(QtGui.QWidget):
      def __init__( self, parent=None):
          super(Test, self).__init__(parent)
    
          self.pushButton = QtGui.QPushButton('I am in Test widget')
    
          layout = QtGui.QHBoxLayout()
          layout.addWidget(self.pushButton)
          self.setLayout(layout)
    
    
    
    app = QtGui.QApplication(sys.argv)
    myWidget = Main()
    myWidget.show()
    app.exec_()
    
    0 讨论(0)
  • 2020-12-08 00:21

    If u want to say , delete a widget whenever a button is clicked , or during any event of ur program , use the deleteLater() method :self.yourwidget.deleteLater()

    self.button.clicked.connect(delete_widget);
    
    def delete_widget(self):
         self.widget.deleteLater();
    

    self.widget.deleteLater();

    Using the above function makes that widget dissappear from the Application

    0 讨论(0)
提交回复
热议问题