使用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()没有产生任何结果?有任何想法吗?谢谢!
答案 0 :(得分:14)
实际上,它确实有效。问题是,您的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_()
答案 1 :(得分:4)
这是一个小小的更改,一旦点击按钮就会自动删除:
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 ......
答案 2 :(得分:0)
如果你想说,只要点击一个按钮,或在任何你的程序事件中删除一个小部件,请使用deleteLater()方法:self.yourwidget.deleteLater()
self.button.clicked.connect(delete_widget);
def delete_widget(self):
self.widget.deleteLater();
self.widget.deleteLater();
使用上述功能可使该小部件从Application
中消失