Проблемы с Pyside/PyQT при добавлении пользовательского виджета в главное окно

У меня есть рабочая программа, которая анализирует данные из Excel с помощью Pandas. Я попробовал несколько способов отобразить выходной фрейм данных в Qtextedit, но так и не смог правильно отобразить форматирование. Короче говоря, я нашел обходной путь в Интернете с помощью пользовательского виджета, который прекрасно работает. Проблема, с которой я столкнулся, заключается в том, что найденный мной пример обходного пути будет правильно отображать мои данные в своем собственном окне, но я не смог понять, как добавить виджет в свое приложение. Кажется, это проблема ООП. Я учусь, но не могу понять, в чем проблема.

Ниже приведен пример виджета, который я попытался добавить в свое основное приложение.

''' ps_QAbstractTableModel_solvents.py
use PySide's QTableView and QAbstractTableModel for tabular data
sort columns by clicking on the header title
here applied to solvents commonly used in Chemistry
PySide is the official LGPL-licensed version of PyQT
tested with PySide112 and Python27/Python33 by vegaseat  15feb2013
'''
import operator
from PySide.QtCore import *
from PySide.QtGui import *
class MyWindow(QWidget):
    def __init__(self, data_list, header, *args):
        QWidget.__init__(self, *args)
        # setGeometry(x_pos, y_pos, width, height)
        self.setGeometry(300, 200, 570, 450)
        self.setWindowTitle("Widget Title.")
        table_model = MyTableModel(self, data_list, header)
        table_view = QTableView()
        table_view.setModel(table_model)
        # set font
        font = QFont("Courier New", 14)
        table_view.setFont(font)
        # set column width to fit contents (set font first!)
        table_view.resizeColumnsToContents()
        # enable sorting
        table_view.setSortingEnabled(True)
        layout = QVBoxLayout(self)
        layout.addWidget(table_view)
        self.setLayout(layout)
class MyTableModel(QAbstractTableModel):
    def __init__(self, parent, mylist, header, *args):
        QAbstractTableModel.__init__(self, parent, *args)
        self.mylist = mylist
        self.header = header
    def rowCount(self, parent):
        return len(self.mylist)
    def columnCount(self, parent):
        return len(self.mylist[0])
    def data(self, index, role):
        if not index.isValid():
            return None
        elif role != Qt.DisplayRole:
            return None
        return self.mylist[index.row()][index.column()]
    def headerData(self, col, orientation, role):
        if orientation == Qt.Horizontal and role == Qt.DisplayRole:
            return self.header[col]
        return None
    def sort(self, col, order):
        """sort table by given column number col"""
        self.emit(SIGNAL("layoutAboutToBeChanged()"))
        self.mylist = sorted(self.mylist,
            key=operator.itemgetter(col))
        if order == Qt.DescendingOrder:
            self.mylist.reverse()
        self.emit(SIGNAL("layoutChanged()"))
# the solvent data ...
header = ['Solvent Name', ' BP (deg C)', ' MP (deg C)', ' Density (g/ml)']
# use numbers for numeric data to sort properly
data_list = [
('ACETIC ACID', 117.9, 16.7, 1.049),
('ACETIC ANHYDRIDE', 140.1, -73.1, 1.087),
('ACETONE', 56.3, -94.7, 0.791),
('ACETONITRILE', 81.6, -43.8, 0.786),
('ANISOLE', 154.2, -37.0, 0.995),
('BENZYL ALCOHOL', 205.4, -15.3, 1.045),
('BENZYL BENZOATE', 323.5, 19.4, 1.112),
('BUTYL ALCOHOL NORMAL', 117.7, -88.6, 0.81),
('BUTYL ALCOHOL SEC', 99.6, -114.7, 0.805),

]
app = QApplication([])
win = MyWindow(data_list, header)
win.show()
app.exec_()

Ниже показано, что я пытался добавить виджет в свое приложение PyQT.

#from PySide.QtCore import *
import sys
from PySide import QtCore, QtGui
import operator





##############################THIS IS THE EXAMPLE###############
# from PySide.QtCore import *
# from PySide.QtGui import *
class MyWindow(QtGui.QWidget): #changed from QWidget to QtGui.QWidget because of import difference.
    def __init__(self, data_list, header, *args):
        QtGui.QWidget.__init__(self, *args) #added QtGui. to QWidget..
        # setGeometry(x_pos, y_pos, width, height)
        self.setGeometry(300, 200, 570, 450)
        self.setWindowTitle("Widget Title.")
        table_model = MyTableModel(self, data_list, header)
        table_view = QtGui.QTableView() #Added QtGui. to QTableView..
        table_view.setModel(table_model)
        # set font
        font = QtGui.QFont("Courier New", 14)   #Added QtGui. to QFont..
        table_view.setFont(font)
        # set column width to fit contents (set font first!)
        table_view.resizeColumnsToContents()
        # enable sorting
        table_view.setSortingEnabled(True)
        layout = QtGui.QVBoxLayout(self)    #Added QtGui. to QVBox..
        layout.addWidget(table_view)
        self.setLayout(layout)
class MyTableModel(QtCore.QAbstractTableModel):  #changed from QAbstractTableModel to QtCore.QAbstractTableModel
    def __init__(self, parent, mylist, header, *args):
        QtCore.QAbstractTableModel.__init__(self, parent, *args)    #changed from QAbstract to QtCore.QAbstract
        self.mylist = mylist
        self.header = header
    def rowCount(self, parent):
        return len(self.mylist)
    def columnCount(self, parent):
        return len(self.mylist[0])
    def data(self, index, role):
        if not index.isValid():
            return None
        elif role != QtCore.Qt.DisplayRole: #Added QtCore. to Qt.Display..
            return None
        return self.mylist[index.row()][index.column()]
    def headerData(self, col, orientation, role):
        if orientation == QtCore.Qt.Horizontal and role == QtCore.Qt.DisplayRole:   #Added QtCore. to Qt.Horiz.. and Qt.Display..
            return self.header[col]
        return None
    def sort(self, col, order):
        """sort table by given column number col"""
        self.emit(QtCore.SIGNAL("layoutAboutToBeChanged()"))    #Added QtCore. to SIGNAL..
        self.mylist = sorted(self.mylist,
            key=operator.itemgetter(col))
        if order == QtCore.Qt.DescendingOrder:  #added QtCore. to Qt.Descending...
            self.mylist.reverse()
        self.emit(QtCore.SIGNAL("layoutChanged()"))
# the solvent data ...
header = ['Solvent Name', ' BP (deg C)', ' MP (deg C)', ' Density (g/ml)']
# use numbers for numeric data to sort properly
data_list = [
('ACETIC ACID', 117.9, 16.7, 1.049),
('ACETIC ANHYDRIDE', 140.1, -73.1, 1.087),
('ACETONE', 56.3, -94.7, 0.791),
('ACETONITRILE', 81.6, -43.8, 0.786),
('ANISOLE', 154.2, -37.0, 0.995),
('BENZYL ALCOHOL', 205.4, -15.3, 1.045),
('BENZYL BENZOATE', 323.5, 19.4, 1.112),
('BUTYL ALCOHOL NORMAL', 117.7, -88.6, 0.81),
('BUTYL ALCOHOL SEC', 99.6, -114.7, 0.805),

]
# app = QApplication([])
# win = MyWindow(data_list, header)
# win.show()
# app.exec_()

###############################END EXAMPLE############################













######################THIS IS THE GUI FILE######################


class Ui_mainForm(object):
    def setupUi(self, mainForm):
        mainForm.setObjectName("mainForm")
        mainForm.resize(1075, 643)
        self.pushButton = QtGui.QPushButton(mainForm)
        self.pushButton.setGeometry(QtCore.QRect(510, 40, 93, 31))
        self.pushButton.setObjectName("pushButton")
        self.lineEdit = QtGui.QLineEdit(mainForm)
        self.lineEdit.setGeometry(QtCore.QRect(40, 40, 451, 31))
        self.lineEdit.setObjectName("lineEdit")
        self.lineEdit_2 = QtGui.QLineEdit(mainForm)
        self.lineEdit_2.setGeometry(QtCore.QRect(40, 90, 451, 31))
        self.lineEdit_2.setObjectName("lineEdit_2")
        self.pushButton_2 = QtGui.QPushButton(mainForm)
        self.pushButton_2.setGeometry(QtCore.QRect(510, 90, 93, 31))
        self.pushButton_2.setObjectName("pushButton_2")
        self.procButton = QtGui.QPushButton(mainForm)
        self.procButton.setGeometry(QtCore.QRect(260, 130, 93, 28))
        self.procButton.setObjectName("procButton")
        self.placeholderWidget = QtGui.QWidget (MyWindow(data_list, header))    ############Trying to activate the custom class in gui.. was mainForm
        self.placeholderWidget.setGeometry(QtCore.QRect(20, 179, 1011, 451))
        self.placeholderWidget.setObjectName("placeholderWidget")
        self.placeholderWidget.setAutoFillBackground(True)


        self.retranslateUi(mainForm)
        QtCore.QMetaObject.connectSlotsByName(mainForm)

    def retranslateUi(self, mainForm):
        mainForm.setWindowTitle(QtGui.QApplication.translate("mainForm", "Parser", None, QtGui.QApplication.UnicodeUTF8))
        self.pushButton.setText(QtGui.QApplication.translate("mainForm", "Browse", None, QtGui.QApplication.UnicodeUTF8))
        self.lineEdit.setPlaceholderText(QtGui.QApplication.translate("mainForm", "Select report", None, QtGui.QApplication.UnicodeUTF8))
        self.lineEdit_2.setPlaceholderText(QtGui.QApplication.translate("mainForm", "Select log file", None, QtGui.QApplication.UnicodeUTF8))
        self.pushButton_2.setText(QtGui.QApplication.translate("mainForm", "Browse", None, QtGui.QApplication.UnicodeUTF8))
        self.procButton.setText(QtGui.QApplication.translate("mainForm", "Process files", None, QtGui.QApplication.UnicodeUTF8))
        self.placeholderWidget.setToolTip(QtGui.QApplication.translate("mainForm", "THIS IS TOOLTIP", None, QtGui.QApplication.UnicodeUTF8))


###############THIS IS THE MAIN PROGRAM####################

class MainDialog(QtGui.QDialog, Ui_mainForm, MyWindow, MyTableModel):   #Attempting to add custom widget to main window. getting error "Internal C++ object (PySide.QtGui.QWidget) already deleted."
    def __init__(self, parent=None):
        super(MainDialog, self).__init__(parent)
        self.setupUi(self)


app = QtGui.QApplication(sys.argv)  #Changed from QApplication to QtGui.QApplication because of different import method from seperate gui file.
mainForm = MainDialog()
mainForm.show()
# win = MyWindow(data_list, header)     #These two lines display the custom example widget outside of the main window.
# win.show()                              #These two lines display the custom example widget outside of the main window.

app.exec_()

##########END MAIN PROGRAM##########


# app = QtGui.QApplication([])   #Added QtGui. to QApplication
# win = MyWindow(data_list, header)     #Now to somehow add this to main window............
# win.show()
# app.exec_()

Мне не удалось сделать так, чтобы пользовательский виджет отображался в основном приложении. Кроме того, я получаю сообщение об ошибке при выполнении. Ниже приведено полное сообщение об ошибке.

C:\Python27\python.exe C:/Users/Dirk/PycharmProjects/QwidgetTest_fromExample/Attempt-incorporate-example2.py
Traceback (most recent call last):
  File "C:/Users/Dirk/PycharmProjects/QwidgetTest_fromExample/Attempt-incorporate-example2.py", line 143, in <module>
    mainForm = MainDialog()
  File "C:/Users/Dirk/PycharmProjects/QwidgetTest_fromExample/Attempt-incorporate-example2.py", line 139, in __init__
    self.setupUi(self)
  File "C:/Users/Dirk/PycharmProjects/QwidgetTest_fromExample/Attempt-incorporate-example2.py", line 116, in setupUi
    self.placeholderWidget.setGeometry(QtCore.QRect(20, 179, 1011, 451))
RuntimeError: Internal C++ object (PySide.QtGui.QWidget) already deleted.

Process finished with exit code 1

person Dirk    schedule 09.02.2017    source источник
comment
Не редактируйте модуль графического интерфейса, сгенерированный pyside-uic/pyuic, используйте продвижение виджета.   -  person ekhumoro    schedule 10.02.2017
comment
Что вы пытаетесь сделать с этим `self.placeholderWidget = QtGui.QWidget(MyWindow (data_list, header))`?   -  person eyllanesc    schedule 10.02.2017
comment
и это: класс MainDialog (QtGui.QDialog, Ui_mainForm, MyWindow, MyTableModel)   -  person eyllanesc    schedule 10.02.2017
comment
Раньше я импортировал модуль графического интерфейса, сгенерированный pyside-uic, но для краткости включил его в пост. В self.placeholderWidget я намеревался включить пример кода с пользовательским графическим интерфейсом.   -  person Dirk    schedule 10.02.2017
comment
PySide автоматически удаляет все объекты, если вы не сохраняете ссылку на них, но почему placeholderWidget удаляется, непонятно. Я бы отметил версию PySide и попробовал с PyQt4.   -  person anatoly techtonik    schedule 11.03.2017