簡體   English   中英

在PyQt中動態添加和刪除小部件

[英]dynamically adding and removing widgets in PyQt

使用PyQt,我試圖創建一個接口,我可以動態添加或刪除小部件。 我想為要添加或刪除的窗口小部件定義一個單獨的類。 我似乎無法獲得我實例化在主界面內顯示的小部件。 這是我正在使用的代碼:

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

問題是,當我在'addWidget'方法中使用下面的代碼時,它完全按照我想要的方式執行,但是類方法似乎不起作用。

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

我想知道為什么z = Test()沒有產生任何結果? 有任何想法嗎? 謝謝!

實際上,它確實有效。 問題是,您的Test小部件有一個沒有任何布局管理的QPushButton 因此,考慮到按鈕,它無法計算其minimumSize 當你將這個小部件放在一個布局中時,它只會收縮到0 (因為QWidget沒有默認的minimumSize ),你什么都看不到。

您有兩種選擇,要么手動管理布局,要么輸入不必要的痛苦世界,要么依賴布局管理器。 一般來說,你應該更喜歡后者。

我會像這樣重寫你的腳本(雖然我不確定你為什么使用QFormLayout ,但我保持原樣。):

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

這是一個小改動,一旦點擊按鈕就會自動刪除:

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

這樣它就不應該在刪除時發生泄漏,並且按鈕實際上可以用於填充內容。 我按照這種模式進行數十次進度條的下載和塊監控,即使使用線程和多處理也能正常工作。 而不是簡單的QThreads ......

如果你想說,只要點擊一個按鈕就刪除一個小部件,或者在任何你的程序事件中,使用deleteLater()方法: self.yourwidget.deleteLater()

self.button.clicked.connect(delete_widget);

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

self.widget.deleteLater();

使用上述功能使該小部件從應用程序中消失

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM