替换QFormLayout中的行时PySide崩溃

时间:2014-02-19 15:17:04

标签: qt python-2.7 pyside

使用以下代码示例PySide在推送“添加”,“添加”,“删除”,“添加”以及其他一些交互序列时会出现段错误。

  • Python:2.7.6
  • PySide:1.2.1
  • QtCore:4.8.5

代码:

from PySide.QtGui import *
from PySide.QtCore import *

class MainWindow(QMainWindow):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
        self.setObjectName('MainWindow')
        self.baseLayout = QWidget(self)
        self.v_layout = QVBoxLayout(self.baseLayout)
        self.setCentralWidget(self.baseLayout)
        self.form_layout = QFormLayout(self.baseLayout)
        self.v_layout.addLayout(self.form_layout)
        self.button_add = QPushButton(self.baseLayout)
        self.button_add.setText("Add")
        self.v_layout.addWidget(self.button_add)
        self.button_del = QPushButton(self.baseLayout)
        self.button_del.setText("Remove")
        self.v_layout.addWidget(self.button_del)
        self.button_add.clicked.connect(self.add)
        self.button_del.clicked.connect(self.remove)

        self.fields = []

    def add_item(self):
        layout = QHBoxLayout(self.parent())
        line = QLineEdit(self.parent())
        slider = QSlider(self.parent())
        layout.addWidget(line)
        layout.addWidget(slider)
        self.fields.append((layout, line, slider))
        self.form_layout.addRow("Test", layout)

    def add(self):
        for i in range(15):
            self.add_item()

    def remove(self):
        for (layout, line, slider) in self.fields:
            line.deleteLater()
            slider.deleteLater()
        while self.form_layout.itemAt(0):
            child = self.form_layout.takeAt(0)
            if child.widget():
                child.widget().deleteLater()
        self.form_layout.update()
        self.fields = []


def main():
    import sys
    app = QApplication(sys.argv)
    frame = MainWindow()
    frame.show()
    app.exec_()

if __name__ == '__main__':
    main()

这是将复合窗口小部件(在本例中为QLineEdit中的QSliderQVBoxLayout)添加到窗体布局的正确方法吗?我做错了什么?

2 个答案:

答案 0 :(得分:0)

QFormLayout添加“复合小部件”的正确方法是创建一个QWidget,它将成为该布局的父级。

add_item()应该看起来像这样:

def add_item(self):
    widget = QWidget(self.parent())
    layout = QHBoxLayout(widget)
    line = QLineEdit(widget)
    slider = QSlider(widget)
    layout.addWidget(line)
    layout.addWidget(slider)
    self.fields.append((layout, widget, line, slider))
    self.form_layout.addRow("Test", widget)

(删除字段时也必须删除小部件)。

答案 1 :(得分:0)

我认为你没有以正确的方式创建布局,例如你试图将base_layout的布局设置两次。您也可以在count()上查看QLayout,看看它是否有孩子:

from PySide.QtGui import *
from PySide.QtCore import *

class MainWindow(QMainWindow):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)

        self.baseLayout = QWidget(self)
        self.v_layout = QVBoxLayout(self.baseLayout)
        self.setCentralWidget(self.baseLayout)

        self.form_layout = QFormLayout()
        self.v_layout.addLayout(self.form_layout)

        self.button_add = QPushButton()
        self.button_add.setText("Add")
        self.v_layout.addWidget(self.button_add)

        self.button_del = QPushButton()
        self.button_del.setText("Remove")
        self.v_layout.addWidget(self.button_del)

        self.button_add.clicked.connect(self.add)
        self.button_del.clicked.connect(self.remove)

        self.fields = []

    def add_item(self):
        layout = QHBoxLayout()
        line = QLineEdit()
        slider = QSlider()
        layout.addWidget(line)
        layout.addWidget(slider)
        self.fields.append((layout, line, slider))
        self.form_layout.addRow("Test", layout)

    def add(self):
        for i in range(15):
            self.add_item()

    def remove(self):

        while self.form_layout.count() > 0:
            child = self.form_layout.takeAt(0)
            widget = child.widget()
            if widget:
                widget.deleteLater()

        self.form_layout.update()
        self.fields = []


def main():
    import sys
    app = QApplication(sys.argv)
    frame = MainWindow()
    frame.show()
    app.exec_()

if __name__ == '__main__':
    main()