如何解决在 PyQt5 中删除小部件时如何删除黑色空间
我有一个代码可以用 PyQt5 生成一个 GUI,它使用户能够基于条目 (QLineEdit) 创建多个按钮 (QPushButton),并在按下“X”按钮 (deleteLater()) 时删除这些按钮。
我的问题是,当通过按下关联的 X 按钮删除其中一些按钮时,这会在按钮最初所在的位置留下一个小的空白空间,因此我想知道如何删除这些空间?
空白区域的图像
from PyQt5.QtWidgets import QApplication,QMainWindow,QPushButton,QLineEdit,QWidget,QVBoxLayout,QHBoxLayout,QGridLayout,QGroupBox,QScrollArea,QLabel
from PyQt5.QtCore import Qt
import sys
class MyWindow(QMainWindow):
def __init__(self):
super(MyWindow,self).__init__()
self.setWindowTitle("My Program")
self.setGeometry(100,100,1500,1500)
self.initUI()
def initUI(self):
widgets = MainWidgets()
self.setCentralWidget(widgets)
class MainWidgets(QWidget):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
self.grid = QGridLayout()
self.grid.setColumnStretch(0,1)
self.grid.setColumnStretch(1,1)
self.grid.setColumnStretch(2,1)
self.grid.setColumnStretch(3,1)
self.grid.setColumnStretch(4,1)
self.groupBox = QGroupBox("Labels")
self.groupBox.setStyleSheet('''
QGroupBox::title {
subcontrol-position: top center;
}
''')
right_column_layout = QVBoxLayout(self.groupBox)
scrollArea = QScrollArea()
scrollArea.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
scrollArea.setWidgetResizable(True)
right_column_layout.addWidget(scrollArea)
scrollArea.setWidget(RightColWidgets())
self.grid.addWidget(self.groupBox,5,1,5)
self.setLayout(self.grid)
class RightColWidgets(QWidget):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
self.layout = QVBoxLayout(self)
self.labelEntry = QLineEdit(self)
self.addLabelButton = QPushButton(self)
self.addLabelButton.setText("Add Label")
self.addLabelButton.clicked.connect(self.addNewLabel)
self.emptyspace = QLabel(self)
self.layout.addWidget(self.labelEntry,stretch=0)
self.layout.addWidget(self.addLabelButton,stretch=0)
self.layout.addWidget(self.emptyspace,stretch=1)
def addNewLabel(self):
labelname = self.labelEntry.text()
newLabelItems = Labels(self,labelname)
self.layout.insertWidget(2,newLabelItems)
class Labels(QWidget):
def __init__(self,parent,labelname,*args,**kwargs):
super().__init__(parent,**kwargs)
self.mylabelname = labelname
self.initUI()
def initUI(self):
self.labelButton = QPushButton(self)
self.labelButton.setText(str(self.mylabelname))
self.labelButton.setStyleSheet("""
QPushButton {border: 1px solid back; background: rgba(103,186,181,0.5); padding-top: 10px; padding-bottom: 10px}
""")
self.labelButton.clicked.connect(self.printbutton)
self.buttonErase = QPushButton(self)
self.buttonErase.setText("X")
self.buttonErase.setStyleSheet("""
QPushButton {border: 1px solid back; padding-right: 5 px; padding-left: 5 px; padding-top: 10px; padding-bottom: 10px}
""")
self.buttonErase.clicked.connect(self.erasebutton)
layout = QHBoxLayout(self)
layout.setContentsMargins(0,0)
layout.addWidget(self.labelButton,stretch=1)
layout.addWidget(self.buttonErase,stretch=0)
def printbutton(self):
print('clicked:',self.labelButton.text())
def erasebutton(self):
self.labelButton.deleteLater()
self.buttonErase.deleteLater()
if __name__ == '__main__':
app = QApplication(sys.argv)
# app.setStyle('Fusion')
window = MyWindow()
window.showMaximized()
sys.exit(app.exec_())
解决方法
删除子项不会删除容器,因此您看到的是空的 Labels
小部件,其布局间距为 contentsMargins()
。
一个简单的解决方案可能是将按钮与其自己的 deleteLeter()
直接连接,这会自动删除其子项:
self.buttonErase.clicked.connect(self.deleteLater)
一个更好的解决方案是将信号连接到父,让它以更干净的方式做所有必要的事情,就像你可能需要跟踪现有的小部件(例如,将它们从当前现有的标签列表中删除):
class RightColWidgets(QWidget):
# ...
def addNewLabel(self):
labelname = self.labelEntry.text()
newLabelItems = Labels(self,labelname)
self.layout.insertWidget(2,newLabelItems)
newLabelItems.buttonErase.clicked.connect(
lambda: self.deleteLabel(newLabelItems))
def deleteLabel(self,widget):
self.layout.removeWidget(widget)
widget.deleteLater()
显然,在这种情况下,您不需要再连接 clicked
类的 initUi
中的 Label
信号。
请注意,layout()
是任何 QWidget 的现有(和动态)属性,因此您不应覆盖它。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。