在Pyside中为QtableWidget设置值时分段失败(核心转储)



当我尝试设置表中的项时,我的Qtablewidget遇到了这个特殊的问题,我还注意到,当我不设置值时不会发生错误,但当我添加代码来设置表中值时,我就会收到错误,奇怪的是,一开始当我点击设置表项及其值的按钮,然后显示窗口时,它可以打开,但当我关闭窗口并试图再次打开它时,应用程序崩溃了。我怀疑这种行为是因为一些小部件没有被正确删除,但我不确定这是我从gdb 的核心转储文件的回溯中得到的输出

#0  0x0000000000000041 in ?? ()
#1  0x00007fd8013972cf in ?? () from /usr/lib/x86_64-linux-gnu/libQtGui.so.4
#2  0x00007fd8013973ec in ?? () from /usr/lib/x86_64-linux-gnu/libQtGui.so.4
#3  0x00007fd8013974e9 in ?? () from /usr/lib/x86_64-linux-gnu/libQtGui.so.4
#4  0x00007fd8035dc168 in QObjectPrivate::deleteChildren() ()
   from /usr/lib/x86_64-linux-gnu/libQtCore.so.4
#5  0x00007fd800e82d47 in QWidget::~QWidget() ()
   from /usr/lib/x86_64-linux-gnu/libQtGui.so.4
#6  0x00007fd801f5f7d1 in ?? ()
   from /usr/lib/python3/dist-packages/PySide/QtGui.cpython-34m-x86_64-linux-gnu.so
#7  0x00007fd8035dc168 in QObjectPrivate::deleteChildren() ()
   from /usr/lib/x86_64-linux-gnu/libQtCore.so.4
#8  0x00007fd800e82d47 in QWidget::~QWidget() ()
   from /usr/lib/x86_64-linux-gnu/libQtGui.so.4
#9  0x00007fd802067331 in ?? ()
   from /usr/lib/python3/dist-packages/PySide/QtGui.cpython-34m-x86_64-linux-gnu.so
#10 0x00007fd8035dc168 in QObjectPrivate::deleteChildren() ()
   from /usr/lib/x86_64-linux-gnu/libQtCore.so.4
#11 0x00007fd800e82d47 in QWidget::~QWidget() ()
   from /usr/lib/x86_64-linux-gnu/libQtGui.so.4
#12 0x00007fd801d8efd1 in ?? ()

这是我认为有故障的代码

            activity_level = [i.level for i in self.all_objects]
            for row, activity in enumerate(activity_level):
                activity = self.format_est_and_lst(activity)
                while len(activity[0]) < self.project_duration:
                    activity[0].append('0')
                for column, value in enumerate(activity[0]):
                    item = QtGui.QTableWidgetItem(str(value))
                    item.setFlags(QtCore.Qt.ItemIsEnabled)
                    self.resourcelevel.level_ui.estTable.setItem(row, column, item)
            for column, value in enumerate(self.result[0]):
                item = QtGui.QTableWidgetItem(str(value))
                item.setFlags(QtCore.Qt.ItemIsEnabled)
                row = len(activity_level)
                self.resourcelevel.level_ui.estTable.setItem(row, column, item)

            for row, activity in enumerate(activity_level):
                while len(activity[1]) < self.project_duration:
                    activity[1].append('0')
                for column, value in enumerate(activity[1]):
                    item = QtGui.QTableWidgetItem(str(value))
                    item.setFlags(QtCore.Qt.ItemIsEnabled)
                    self.resourcelevel.level_ui.lstTable.setItem(row, column, item)
            for column, value in enumerate(self.result[1]):
                item = QtGui.QTableWidgetItem(str(value))
                item.setFlags(QtCore.Qt.ItemIsEnabled)
                row = len(activity_level)
                self.resourcelevel.level_ui.lstTable.setItem(row, column, item)

            self.resourcelevel.show()

我还想问,调试segfault以获得与gdb不同的确切错误的正确方法是什么,因为gdb没有指出导致segfault错误的特定小部件行,这也是在表中设置项目的正确方法吗?

从segfault获得更好信息的唯一方法是使用PySide和可能的Qt的DEBUG构建。这是可能的(很明显(,但根据我有限的经验,这是困难的:你必须从源代码构建这两个。

如果没有,最好的选择是将失败的代码剥离为一个更小、更简单的仍然失败的示例。把它减少到100行左右。到那时,你可能会自己发现问题所在。但是,如果您还没有,它将足够小,可以按照three_pineapples的要求发布在Stack Overflow上。

在这种情况下,当Qt代码回调已删除的Python对象时,问题可能会发生。例如,可能是QTableWidgetItem.data。当表的Qt模型与Python版本不同步时,可能会发生这种情况,例如行数错误。这意味着问题很可能不是因为代码立即触发了segfault(您已经发布了(,而是因为表正在设置和更改。

最新更新