如何用QSqlRelationalTableModel在PyQt5上实现setData



我是Pyqt的新手,需要帮助使用QSqlRelationalTableModel表模型在QAbstractTableModel上设置setData

我有这个简单的代码,现在我不知道如何实现setData函数。我无法将值设置为字段。我正在获取TypeError:"QSqlRelationalTableModel"对象不是可下标的错误。

另外,如何对列(如合计列(进行计算?

from pyexpat import model
import sys
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import (QApplication, QGridLayout, QHeaderView, QMessageBox,
QTableView, QMainWindow, QWidget)
from PyQt5.QtSql import QSqlDatabase, QSqlRelationalTableModel, QSqlTableModel
from PyQt5.QtSql import QSqlRelation, QSqlRelationalDelegate
from PyQt5 import QtCore

from PyQt5.QtCore import QAbstractTableModel, QModelIndex, QRect, Qt
from datetime import date
from time import strftime

from numpy import record

class MyTableModel(QtCore.QAbstractTableModel):
def __init__(self, model):
super().__init__()
self._model = model

# Create the data method
def data(self, index, role):
value = self._model.record(index.row()).value(index.column())

if role == Qt.ItemDataRole.DisplayRole:
if isinstance(value, int) and index.column() == 0:
return f'# {value}'
if isinstance(value, int) and index.column() == 1:
# Format the currency value
return "${: ,.2f}".format(value)

if role == Qt.EditRole:
return self._model[index.row()][index.column()]

return value


if role == Qt.ItemDataRole.DecorationRole:
if isinstance(value, int) and index.column() == 0:
return QtGui.QIcon('data/icons/hashtag_icon.png')
if isinstance(value, str) and index.column() == 9:
return QtGui.QIcon('data/icons/calendar.png')

# Create the headerData method
def headerData(self, section: int, orientation: Qt.Orientation, role: int):
if role == Qt.ItemDataRole.DisplayRole and orientation == Qt.Orientation.Horizontal:
return self._model.headerData(section, orientation, role=role)

# Create the rowCount method
def rowCount(self, parent: QModelIndex) -> int:
return self._model.rowCount()

# Create the columnCount method
def columnCount(self, parent: QModelIndex) -> int:
return self._model.columnCount()

def setData(self, index, value, role):
if not index.isValid():
return False
if role == Qt.EditRole: 
self._model[index.row()][index.column()]=value
self.dataChanged.emit(index, index,)
return True
return False

def flags(self, index):
return Qt.ItemFlag.ItemIsSelectable | Qt.ItemFlag.ItemIsEnabled | Qt.ItemFlag.ItemIsEditable


# Inherit from QMainWindow
class MainWindow(QMainWindow):
def __init__(self, parent=None):
super().__init__(parent)
# Set the window title

self.setWindowTitle('QTable Example')
self.window_width, self.window_height = 1000, 700
self.setMinimumSize(self.window_width, self.window_height)
# Create the model
model = QSqlRelationalTableModel(self)

# Set the table to display

model.setTable('obracundetails')
model.setEditStrategy(QSqlRelationalTableModel.EditStrategy.OnFieldChange)
# Set relations for related columns to be displayed
#model.setRelation(1, QSqlRelation('products', 'ProductID', 'Price'))  
model.setRelation(8, QSqlRelation('asortiman', 'asortiman_id', 'naziv'))
model.setRelation(9, QSqlRelation('obracunmain', 'obracunmain_id', 'datum'))
#model.setHeaderData(0, Qt.Horizontal, "ID")
model.select()
# Setup the view

# Create the view = a table widget
presentation_model = MyTableModel(model)
view = QTableView(self)

# Set the data model for table widget

#view.setModel(model)
view.setModel(presentation_model)

# Adjust column widths to their content
view.resizeColumnsToContents()
# Add the widget to main window
self.setCentralWidget(view)


# Type hint for return value
def createConnection() -> bool:
# SQLite type database connection instance
con = QSqlDatabase.addDatabase('QSQLITE')
# Connect to the database file
con.setDatabaseName('havana.sqlite3')
# Show message box when there is a connection issue
if not con.open():
QMessageBox.critical(
None,
'QTableView Example - Error!',
'Database Error: %s' % con.lastError().databaseText(),
)
return False
return True


if __name__ == "__main__":
app = QApplication(sys.argv)
if not createConnection():
sys.exit(1)
form = MainWindow()
form.show()
app.exec()

提前感谢

;对象不可下标";错误表示您试图访问一个并没有提供此类接口的对象的项或索引。

>>> obj = 100
>>> print(obj[2])
TypeError: 'int' object is not subscriptable

self._model[index.row()][index.column()]无法工作,因为Qt模型不是列表或数组,您无法使用方括号获取其内容。

同样,您不能像使用相同符号的列表那样编写值。您必须以在实现中看到的相同方式使用setData():为模型的提供索引和值。

def setData(self, index, value, role):
if not index.isValid():
return False
if role == Qt.EditRole:
targetIndex = self._model.index(index.row(), index.column())
if self._model.setData(targetIndex, value, role):
self.dataChanged.emit(index, index)
return True
return False

我找到了解决方案,但我不确定它是否完全正确,但它运行良好。

self._model.setData(index, value, role)

对于计算列,我有第3列的工作代码

row = index.row()
# getting value from column4 
value_col4 = self._model.index(row, 4).data() 
#getting index of column7
index_total=self._model.index(row, 7)
# perform some calculation
total_col7 = value_col4 * price
#saving to column7
self._model.setData(index_total, float(total_col7))

最新更新