Saya memiliki program kerja yang mem-parsing data dari excel dengan Pandas. Saya mencoba beberapa cara untuk menampilkan kerangka data keluaran di Qtextedit, tetapi formatnya tidak pernah muncul dengan benar. Singkat cerita, saya menemukan solusi online dengan widget khusus yang berfungsi dengan baik. Masalah yang saya hadapi adalah contoh solusi yang saya temukan akan menampilkan data saya dengan benar di jendelanya sendiri, namun saya belum dapat menemukan cara untuk menambahkan widget ke aplikasi saya. Sepertinya ini masalah OOP. Saya sedang belajar, tetapi tidak dapat memahami apa masalahnya.
Di bawah ini adalah contoh widget yang saya coba tambahkan ke aplikasi utama saya.
''' 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_()
Di bawah ini adalah apa yang saya coba saat mencoba menambahkan widget ke aplikasi PyQT saya.
#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_()
Saya belum bisa menampilkan widget khusus di aplikasi utama. Selain itu saya mendapatkan pesan kesalahan saat eksekusi. Di bawah ini adalah pesan kesalahan lengkapnya.
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
placeholderWidget
dihapus tidak jelas. Saya akan mencatat versi PySide dan mencoba dengan PyQt4. - person anatoly techtonik   schedule 11.03.2017