内部C ++对象已被删除(pyside)

时间:2016-08-27 23:31:02

标签: python qt pyside

该程序的目的是将tradeWindow显示为QWidget,然后在每次调用doStuff时显示QDialog(通过按钮),如果有结果。代码第一次工作,但第二次收到错误消息:

    IEnumerable<DOC_TRACK_MAIN> data;
    Stopwatch st = new Stopwatch();
    st.Start();

    data = context.TABLE1.AsNoTracking().Include(x => x.TABLE2).AsNoTracking().Where(x => startDate <= DbFunctions.TruncateTime(x.LAST_UPDATED_DATE) && endDate >= DbFunctions.TruncateTime(x.LAST_UPDATED_DATE));            

    var result = data.Where(x => x.TABLE2.MAP_TYPE_CODE.Trim().ToUpper() == reportCode.Trim().ToString()).ToList();
    st.Stop();
    var cnt = result.Count();
    var tm = st.Elapsed;
    return result;

当我第一次关闭QDialog时,似乎我的布局被删除了。 移动Traceback (most recent call last): File "GUI.py", line 68, in doStuff popup = Dialog((Qt.WindowSystemMenuHint | Qt.WindowTitleHint), popLayout) File "GUI.py", line 47, in __init__ self.setLayout(popLayout) RuntimeError: Internal C++ object (PySide.QtGui.QHBoxLayout) already deleted. 开始popLayout = QHBoxLayout(),我认为可以解决问题,但却给了我这个错误:

doStuff

这对我来说没有多大意义,因为它应该在被引用之前始终被定义?无论如何我找不到问题。我确信我的很多代码都可以改进,而且我对课程等也很陌生。

如果您有任何关于如何打开QDialog的提示,每次比我正在尝试的更好或其他有用的提示,请不要犹豫,同时提及。 (尽量忽略糟糕的命名约定,我将来会修复它。)

感谢您的帮助!

GUI example

Traceback (most recent call last):
   File "GUI.py", line 69, in doStuff
     popup = Dialog((Qt.WindowSystemMenuHint | Qt.WindowTitleHint), popLayout)
   File "GUI.py", line 47, in __init__
     self.setLayout(popLayout)
NameError: name 'popLayout' is not defined

1 个答案:

答案 0 :(得分:1)

关闭Dialog后,引用它的popup变量超出范围,Python将对其进行垃圾收集。这会导致删除整个底层C ++对象,包括其所有子窗口小部件和布局。但是,您将保持对对话框使用的布局的引用,因此第二次尝试打开对话框时将删除布局。

我发现你在Dialog类之外的Dialog类的所有初始化都很奇怪。相反,我建议在popLayout课程中移动table的创建,以及Dialog的所有创建和设置。这样,每次打开对话框时都会创建布局。

您需要将gameResults作为参数添加到__init__的{​​{1}}方法中,您还可以删除此处的Dialog参数因为它没有被使用

执行此操作后,您的layout课程应如下所示:

Dialog

,您的class Dialog(QDialog): def __init__(self, flags, gameResults): super().__init__() self.setWindowFlags(flags) self.resize(800,500) popLayout = QHBoxLayout() self.setLayout(popLayout) table = Table(popLayout) table.setRowCount(len(gameResults)) table.setColumnCount(2); table.setHorizontalHeaderItem(0, QTableWidgetItem("Game")) table.setHorizontalHeaderItem(1, QTableWidgetItem("URL")) for index, game in enumerate(sorted(gameResults)): table.setItem(index,0,QTableWidgetItem(game)) table.item(index,0).setFlags( Qt.ItemIsSelectable | Qt.ItemIsEnabled ) table.setItem(index,1,QTableWidgetItem('http://store.steampowered.com/app/'+gameResults[game]+'/')) table.item(index,1).setFlags( Qt.ItemIsSelectable | Qt.ItemIsEnabled ) table.resizeColumnsToContents() 方法应如下所示:

doStuff()

我对您的代码进行了这些更改,并且我能够多次打开对话框。

我会让您以同样的方式将主窗口设置代码移到def doStuff(): gameResults = {'doom' : '111232', 'quake' : '355324'} if len(gameResults) > 0: popup = Dialog((Qt.WindowSystemMenuHint | Qt.WindowTitleHint), gameResults) popup.exec_() else: msgBox = QMessageBox() msgBox.setText("No results.") msgBox.exec_() 课程中。

最后,请注意我只使用PyQt对此进行了测试。但是,我希望我的更改也适用于PySide。