我是Pyqt的新手,需要帮助我用setData表模型在QAbstractTableModel上设置QSqlRelationalTableModel
我有这个简单的代码,现在我不知道如何实现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()
提前感谢
发布于 2022-11-04 16:48:20
"object不是可订阅的“错误意味着您试图访问不提供此类接口的对象的项或索引。
>>> 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
发布于 2022-11-04 18:43:22
我找到了解决办法,但我不确定是否完全正确,但效果很好。
self._model.setData(index, value, role)
对于计算出的列,我有用于column3的工作代码
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))
https://stackoverflow.com/questions/74318100
复制相似问题