it-swarm.com.de

widgets in PyQt dynamisch hinzufügen und entfernen

mit PyQt versuche ich, eine Schnittstelle zu erstellen, für die ich das Widget dynamisch hinzufügen oder entfernen kann. Ich möchte eine eigene Klasse für das Widget definieren, die hinzugefügt oder entfernt wird. Ich kann anscheinend nicht das Widget erhalten, das ich instanziiere, um es in der Hauptschnittstelle anzuzeigen. Hier ist der Code, den ich verwende: 

from PyQt4 import QtGui, QtCore
import sys

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

        # central widget
        self.centralWidget = QtGui.QWidget(self)

        # main layout
        self.vLayout = QtGui.QVBoxLayout(self.centralWidget)

        # main button
        self.pButton_add = QtGui.QPushButton(self.centralWidget)
        self.pButton_add.setText('button to add other widgets')

        # scroll area
        self.scrollArea = QtGui.QScrollArea(self.centralWidget)
        self.scrollArea.setWidgetResizable(True)

        # scroll area widget contents
        self.scrollAreaWidgetContents = QtGui.QWidget(self.scrollArea)

        # scroll area widget contents - layout
        self.formLayout = QtGui.QFormLayout(self.scrollAreaWidgetContents)

        self.scrollArea.setWidget(self.scrollAreaWidgetContents)

        # add all main to the main vLayout
        self.vLayout.addWidget(self.pButton_add)
        self.vLayout.addWidget(self.scrollArea)
        # set central widget
        self.setCentralWidget(self.centralWidget)
        # connections
        self.pButton_add.clicked.connect(self.addWidget)


    def addWidget(self):
        z = Test(self.scrollAreaWidgetContents)
        count = self.formLayout.rowCount()
        self.formLayout.setWidget(count, QtGui.QFormLayout.LabelRole, z)


class Test(QtGui.QWidget):
  def __init__( self, parent):
      super(Test, self).__init__(parent)

      self.pushButton = QtGui.QPushButton(self)


app = QtGui.QApplication(sys.argv)
myWidget = Main()
myWidget.show()
app.exec_()

die Sache ist, wenn ich den unten stehenden Code in meiner addWidget-Methode verwende, macht sie genau das, was ich will, aber die Klassenmethode scheint nicht zu funktionieren. 

z = QtGui.QPushButton(self.scrollAreaWidgetContents)
count = self.formLayout.rowCount())
self.formLayout.setWidget(count, QtGui.QFormLayout.LabelRole, z)

Ich frage mich, warum der Z = Test () keine Ergebnisse liefert? Irgendwelche Ideen? Vielen Dank!

12
boundless

Eigentlich funktioniert es. Das Problem ist, dass Ihr Test-Widget eine QPushButton ohne Layoutverwaltung hat. Es kann also nicht seine minimumSize unter Berücksichtigung der Schaltfläche berechnet werden. Wenn Sie das Widget in ein Layout einfügen, schrumpft es nur auf 0 (da eine QWidget keinen Standardwert minimumSize hat) und Sie nichts sehen.

Sie haben zwei Möglichkeiten: Entweder Sie verwalten das Layout manuell und betreten eine unnötige Schmerzwelt oder Sie verlassen sich auf Layout-Manager. Im Allgemeinen sollten Sie Letzteres vorziehen.

Ich würde Ihr Skript so umschreiben (obwohl ich nicht sicher bin, warum Sie QFormLayout verwenden, lasse ich es so wie es ist.):

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_()
13
Avaris

Hier ist eine kleine Änderung, durch die der Button nach dem Anklicken selbst gelöscht wird:

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_()

Auf diese Weise sollte es beim Löschen nicht ausbleiben, und die Schaltfläche kann tatsächlich für Dinge verwendet werden. Ich folge diesem Muster für Fortschrittsbalken durch die Dutzende für das Herunterladen und das Überwachen von Blöcken, und es funktioniert auch mit Threading und Multi-Processing einwandfrei. Und nicht die einfachen QThreads ...

4
ClearType3000

Wenn Sie sagen möchten, löschen Sie ein Widget, wenn Sie auf eine Schaltfläche klicken oder während eines Ereignisses Ihres Programms, die deleteLater () -Methode: self.yourwidget.deleteLater()

self.button.clicked.connect(delete_widget);

def delete_widget(self):
     self.widget.deleteLater();

self.widget.deleteLater ();

Wenn Sie die obige Funktion verwenden, verschwindet das Widget aus der Anwendung

0
Natesh bhat