首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何用setData在PyQt5 QAbstractTableModel上实现QSqlRelationalTableModel

如何用setData在PyQt5 QAbstractTableModel上实现QSqlRelationalTableModel
EN

Stack Overflow用户
提问于 2022-11-04 13:51:35
回答 2查看 29关注 0票数 0

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

我有这个简单的代码,现在我不知道如何实现setData函数。我不能给字段设定值。我得到了TypeError:'QSqlRelationalTableModel‘对象不是可订阅的错误。

此外,如何在列上进行计算(例如。(总栏)?

代码语言:javascript
运行
复制
    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()

提前感谢

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2022-11-04 16:48:20

"object不是可订阅的“错误意味着您试图访问不提供此类接口的对象的项或索引。

代码语言:javascript
运行
复制
>>> obj = 100
>>> print(obj[2])

TypeError: 'int' object is not subscriptable

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

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

代码语言:javascript
运行
复制
        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
票数 0
EN

Stack Overflow用户

发布于 2022-11-04 18:43:22

我找到了解决办法,但我不确定是否完全正确,但效果很好。

代码语言:javascript
运行
复制
self._model.setData(index, value, role)

对于计算出的列,我有用于column3的工作代码

代码语言:javascript
运行
复制
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))
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/74318100

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档