【问题标题】:Message says NonType object, but object is a QHBoxLayout消息说 NonType 对象,但对象是 QHBoxLayout
【发布时间】:2017-11-09 05:45:52
【问题描述】:

我是 PyQt 的新手,遇到了一个(对我来说)相当困难的问题。

我有一个 QVBoxLayout。我用几个 QHBoxLayout 动态填充它。 每个 QHBoxLayout 宿主,依次为 3 个 QLineEdit、1 个 QLabel 和 1 个 QPushButton。

右侧的按钮连接到函数 remove_malt,其代码如下:

def add_malt(self):#call when clicking on a push button
    maltT=self.s[str(self.malt_list_widget.currentItem().text())]
    self.listMalts.append(maltT)
    h_layout=QtGui.QHBoxLayout()#create an horizontal layout to host widgets for one malt line
    h_layout.addWidget(QtGui.QLineEdit(maltT.full_name))#for grain full name
    h_layout.addWidget(QtGui.QLineEdit())#for percentage
    h_layout.addWidget(QtGui.QLineEdit())#for calculated mass
    h_layout.addWidget(QtGui.QLabel('kg'))#for unit
    h_layout.addWidget(QtGui.QPushButton('X')) #for deletion
    h_layout.itemAt(0).widget().setMinimumSize(400,30)
    h_layout.itemAt(0).widget().setStyleSheet("font-size: 14px;background-color: rgb(230, 230, 230);")
    h_layout.itemAt(0).widget().setReadOnly(True)
    h_layout.itemAt(1).widget().setMaximumSize(50,30)
    h_layout.itemAt(1).widget().setStyleSheet("font-size: 14px;background-color: white;")
    h_layout.itemAt(1).widget().textEdited.connect(self.clean_results)         
    h_layout.itemAt(2).widget().setMaximumSize(70,30)
    h_layout.itemAt(2).widget().setStyleSheet("font-size: 14px;background-color: rgb(230,230,0) ;")
    h_layout.itemAt(2).widget().setReadOnly(True)       
    h_layout.itemAt(3).widget().setMaximumSize(50,30)
    h_layout.itemAt(3).widget().setStyleSheet("font-size: 14px;")       
    h_layout.itemAt(4).widget().setMaximumSize(30,30)
    h_layout.itemAt(4).widget().setStyleSheet("font-size: 14px;color: 'red';background-color: rgb(230,230,230);font-weight: bold; ")

    h_layout.itemAt(4).widget().clicked.connect(self.remove_malt)        
    self.grainLayout.addLayout(h_layout)

def remove_malt(self):
    s= self.sender()
    for i in range(self.grainLayout.count()):
        #if i==0:
         #   continue
        print('loop '+str(i))
        #pb=self.grainLayout.itemAt(i).layout().itemAt(4).widget()
        ly=self.grainLayout.itemAt(i).layout()
        print ('voici ly')
        print (ly)
        pb=ly.itemAt(4).widget()
        if s ==pb:
            print('delete '+str(i))
            self.clearLayout(self.grainLayout.itemAt(i).layout())
            del self.listMalts[i]
            return


def clearLayout(self,layout):
    print(layout)
    if layout is not None:
        while layout.count():
            item = layout.takeAt(0)
            widget = item.widget()
            if widget is not None:
                widget.deleteLater()
            else :
                self.clearLayout(item.layout())   

包装 QVBoxLayout 被称为 grainLayout 并且上面的文本不是它的一部分。 我自愿断线`#pb=self.grainLayout.itemAt(i).layout().itemAt(4).widget() 以便能够打印作为来源的ly(布局)的值铅。

我可以删除一些行(QHBoxLayout),但在某些时候,有时在最后一行,有时在随机位置,会发生错误。 这是控制台的内容

    loop 0
voici ly
<PyQt4.QtGui.QHBoxLayout object at 0x7faef91e06d8>
delete 0
<PyQt4.QtGui.QHBoxLayout object at 0x7faef91e06d8>
loop 0
voici ly
<PyQt4.QtGui.QHBoxLayout object at 0x7faef91e06d8>
Traceback (most recent call last):
  File "/home/jaaf/beer/MassCalculationWindow.py", line 122, in remove_malt
    pb=ly.itemAt(4).widget()
AttributeError: 'NoneType' object has no attribute 'widget'

第 122 行是计算 pb 的行

读到这里,似乎 pb 'NonType object has no attribute 'widget' ly 与之前的对象完全相同,我的意思是 QHBoxLayout。

拜托,我需要帮助。

【问题讨论】:

  • 您可以显示最小且可重现的代码
  • 你可以展示你如何创建grainLayout
  • grainLayout 由 QtDesigner 创建
  • 我编辑并添加了在布局中添加行的代码。
  • 您可以通过 github、drive、dropbox 或类似方式共享您的代码。

标签: python pyqt pyqt4


【解决方案1】:

在您的代码中,除了验证项目是否存在之外,除了删除小部件之外,您还必须删除项目。

备注:if obj is not None: 等于 if obj:

def remove_malt(self):
    s= self.sender()
    for i in range(self.grainLayout.count()):
        item =self.grainLayout.itemAt(i)
        if item:
            if s == item.layout().itemAt(4).widget():
                self.clearLayout(item.layout())
                self.grainLayout.removeItem(item)
                del self.listMalts[i]
                return


def clearLayout(self, layout):
    if layout:
        while layout.count():
            item = layout.takeAt(0)
            widget = item.widget()
            if widget:
                widget.deleteLater()
            else :
                self.clearLayout(item.layout())
            layout.removeItem(item)

【讨论】:

  • 对不起,我昨天晚上因紧急情况不得不离开。
  • 您的代码运行良好。非常感谢您的帮助。干杯。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-10-19
  • 2012-01-07
  • 1970-01-01
  • 1970-01-01
  • 2018-03-27
  • 2011-09-21
相关资源
最近更新 更多