Цель этой программы - показать tradeWindow как QWidget, а затем показать QDialog каждый раз, когда doStuff вызывается (через кнопку), если есть результаты. Код работает в первый раз, но второй раз я получаю сообщение об ошибке:Внутренний объект C++ уже удален (pyside)
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.
Кажется, мой макет будет удален, когда я закрыть QDialog в первый раз. Перемещение popLayout = QHBoxLayout()
в начало doStuff
, который я думал бы решить эту проблему, дает мне эту ошибку вместо того, чтобы:
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
Это не имеет большого смысла для меня вообще, так как она должна быть всегда получать определенные, прежде чем ссылаться? В любом случае, я не могу найти проблему. Я уверен, что многое из моего кода может быть улучшено, а также я очень новичок в классах и т. Д.
Если у вас есть какие-либо советы о том, как открыть QDialog каждый раз, когда это лучше, чем то, что я сейчас пытаюсь или другие полезные советы, пожалуйста, не стесняйтесь упоминать об этом. (Попытайтесь игнорировать запретительное соглашение об именах, я исправлю это в будущем.)
Благодарим за помощь!
#!/usr/bin/python
# -*- coding: utf-8 -*-
import sys
from PySide.QtCore import *
from PySide.QtGui import *
import webbrowser
class Window(QWidget):
def __init__(self, windowTitle, layout):
super().__init__()
self.resize(800,500)
self.setWindowTitle(windowTitle)
self.setLayout(layout)
class TextField(QTextEdit):
def __init__(self, tooltip, layout):
super().__init__()
self.setToolTip(tooltip)
layout.addWidget(self)
class Button(QPushButton):
def __init__(self, text, layout):
super().__init__()
self.setText(text)
layout.addWidget(self)
class Label(QLabel):
def __init__(self, text, layout):
super().__init__()
self.setText(text)
layout.addWidget(self)
class Table(QTableWidget):
def __init__(self, layout):
super().__init__()
self.cellDoubleClicked.connect(self.slotItemDoubleClicked)
layout.addWidget(self)
def slotItemDoubleClicked(self,row,col):
if col == 0 or col == 1:
webbrowser.open(self.item(row, 1).text())
class Dialog(QDialog):
def __init__(self, flags, layout):
super().__init__()
self.setWindowFlags(flags)
self.resize(800,500)
self.setLayout(popLayout)
#Layouts
mainLayout = QVBoxLayout()
subLayout = QHBoxLayout()
subLayout2 = QHBoxLayout()
mainLayout.addLayout(subLayout)
mainLayout.addLayout(subLayout2)
popLayout = QHBoxLayout()
#Main
tradeApp = QApplication(sys.argv)
textedit = TextField('bla',subLayout)
textedit2 = TextField('bla2',subLayout)
label = Label('Hover over input fields for instructions.', subLayout2)
button = Button('click me', subLayout2)
label2 = Label('Hover over input fields for instructions.', subLayout2)
def doStuff():
gameResults = {'doom' : '111232', 'quake' : '355324'}
if len(gameResults) > 0:
popup = Dialog((Qt.WindowSystemMenuHint | Qt.WindowTitleHint), 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()
popup.exec_()
else:
msgBox = QMessageBox()
msgBox.setText("No results.")
msgBox.exec_()
button.clicked.connect(doStuff)
tradeWindow = Window('Tradefinder', mainLayout)
tradeWindow.show()
tradeApp.exec_()
Спасибо :) Я был в процессе рефакторинга кода для более классного подхода, так как раньше у меня был «прототип», и я только что изучил основы классов вчера. Всегда находил, что это немного раздражает, но теперь я думаю, что предпочитаю классы на самом деле. Но все же новые, хотя так оценивают все входные данные. Я сейчас займусь этим сообщением и сделаю изменения, прежде чем принимать ответ, но спасибо за очень информативный пост :) – raecer
Прекрасно работает и кажется намного лучшим способом обойти все. Я также внес изменения в mainwindow. Спасибо за то, что я тоже обучил :) – raecer
Не уверен, где я должен рисовать линию, когда дело доходит до занятий. Теперь я размышляю, следует ли определять функцию doStuff в mainwindow, и я должен просто пройти в gameresults? – raecer