【问题标题】:Delete last widget from gridlayout从 gridlayout 中删除最后一个小部件
【发布时间】:2020-07-09 00:43:53
【问题描述】:

我有一个网格布局,我在运行时添加 Qlineedits。
按下按钮时,我想从 gridlaout 中删除最后一个 qline 编辑
为什么这个函数会同时删除所有的qlinedits?

 def deleate_widgets(self):
        widgets = (self.main_layout.itemAt(i).widget() for i in range(self.main_layout.count()))
        for widget in widgets:
            if isinstance(widget, qtw.QLineEdit):
                print("linedit: %s  - %s" %(widget.objectName(), widget.text()))
                widget.deleteLater() # all objects

如何更改代码一次只删除一个小部件,最好是最后添加的小部件?

完整代码

#!/usr/bin/env python

"""
Interface to get the specific  weight of each of the 5 containers
start_measurment_button starts thread /thread_worker
transfer_data button start query and send data to database
"""

import sys
import sqlite3

from PyQt5 import QtWidgets as qtw
from PyQt5 import QtCore as qtc
from PyQt5 import QtGui as qtg
from PyQt5 import QtSql as qsql

from  PyQt5 import sip

class AddWidget(qtw.QWidget):
    '''
    Interface with embedded SQL functions
    '''

    # Attribut Signal

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        # your code will go here

        self.mylist = []
        # interface

        # position
        qtRectangle = self.frameGeometry()
        centerPoint = qtw.QDesktopWidget().availableGeometry().center()
        qtRectangle.moveCenter(centerPoint)
        self.move(qtRectangle.topLeft())
        # size
        self.resize(700, 410)
        # frame title
        self.setWindowTitle("add  Widget")
        # heading
        heading_label = qtw.QLabel('add Widget')
        heading_label.setAlignment(qtc.Qt.AlignHCenter | qtc.Qt.AlignTop)

        # add Button
        self.addwidget_button = qtw.QPushButton("add Widget")
        self.getlistof_button = qtw.QPushButton("deleate")

        self.main_layout = qtw.QGridLayout()
        self.main_layout.addWidget(self.getlistof_button,0,0)
        self.main_layout.addWidget(self.addwidget_button, 1, 0)

        self.setLayout(self.main_layout)

        self.show()

        # functionality
        self.addwidget_button.clicked.connect(self.add_widget)
        # self.getlistof_button.clicked.connect(self.deleate_widgets_try)


    def add_widget(self):
        self.my_lineedit = qtw.QLineEdit()
        self.mylist.append(self.my_lineedit)
        self.main_layout.addWidget(self.my_lineedit)


    def deleate_widgets(self):
        widgets = (self.main_layout.itemAt(i).widget() for i in range(self.main_layout.count()))
        for widget in widgets:
            if isinstance(widget, qtw.QLineEdit):
                print(widget)
                # print("linedit: %s  - %s" %(widget.objectName(), widget.text()))
                # widget.deleteLater() # alle objects


    # 
    # def deleate_widgets_try(self):
    #     widgets = (self.main_layout.itemAt(i).widget() for i in range(self.main_layout.count()))
    #     my_iter = iter(widgets)
    # 
    #     if isinstance(my_iter, qtw.QLineEdit):
    #         next(my_iter.deleteLater()) # alle objects)

if __name__ == '__main__':
    app = qtw.QApplication(sys.argv)
    w = AddWidget()
    sys.exit(app.exec_())

【问题讨论】:

    标签: python pyqt pyqt5


    【解决方案1】:

    您的函数会删除所有小部件,因为您正在循环浏览所有小部件,从第一个到最后一个。

    此外,实际上没有必要遍历整个布局,因为您已经保留了一个始终将最后一个附加到末尾的小部件列表。

    只需从列表中弹出最后一项。不需要从布局中删除它,因为deleteLater() 会处理它,但这只是为了演示目的。

    def deleate_widgets(self):
        # remove the last item from the list
        lastWidget = self.mylist.pop(-1)
        self.main_layout.removeWidget(lastWidget)
        lastWidget.deleteLater()
    

    为了完整起见,您的函数应该执行以下操作:

    1. 在布局中循环小部件向后
    2. 一旦找到第一个(如最后一个)项目,就打破循环;
    def deleate_widgets(self):
        widgets = [self.main_layout.itemAt(i).widget() for i in range(self.main_layout.count())]
        # use reversed() to cycle the list backwards
        for widget in reversed(widgets):
            if isinstance(widget, qtw.QLineEdit):
                print("linedit: %s  - %s" %(widget.objectName(), widget.text()))
                widget.deleteLater()
                # the line edit has been found, exit the cycle with break to avoid
                # deleting further widgets
                break
    

    此外,为不需要持久引用的对象创建实例属性 (self.someobject = ...) 确实没有用,特别是如果您重复创建这些对象(这将导致该属性的不断覆盖,使它没用)并且您已经将它们保存在持久数据模型对象(通常是列表、元组、字典)中,例如 self.mylist 在您的情况下(以及 那个必须是实例属性):

    def add_widget(self):
            # no need to create a "self.my_lineedit"
            my_lineedit = qtw.QLineEdit()
            self.mylist.append(my_lineedit)
            self.main_layout.addWidget(my_lineedit)
    

    看过你之前的问题和cmets,我强烈建议你更好地学习和试验Pythondata modelscontrol flowsclasses,因为它们是(Python和一般编程的)基本概念,必须在尝试做任何事情之前被理解和内化。

    【讨论】:

    • 感谢您的回答和解释非常感谢,通过项目学习这些概念对我来说效果更好,但是您的权利我缺乏一些基本概念
    • 我的脚本在for widget in reversed(widgets): 崩溃我得到一个 TypeError "generator" object is not reversible`知道如何在不使用列表的情况下从最后一个小部件开始吗?
    • @HoboCoder 我知道回到基础可能看起来既烦人又不令人兴奋,但请考虑一下:至少在过去几天里,您一直被几乎相同的代码所困扰,提出问题这些基础知识涵盖的内容。与此同时,您可能已经能够学习和理解它们,并可能在几个小时内自行解决问题。关于坠机,我的错;我会修复它,但在此之前我会提示您:reversed() 需要一个具有确定长度的序列对象,例如列表。
    • 你能再给我一个提示吗:)?
    猜你喜欢
    • 2014-02-08
    • 2020-04-09
    • 1970-01-01
    • 2016-12-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-11
    • 1970-01-01
    相关资源
    最近更新 更多