通过子类调用模型方法

问题描述 投票:0回答:1

我想做的是创建QTableView的子类,该子类将接受标准化模型(这是mysql查询的结果),并填充它。有了它,我想定义一个自定义上下文菜单,该菜单允许我添加或删除行。这种方法允许我一次定义模型和子类,然后将它们都调用,以使用许多不同的查询填充它们,而无需重复代码。

add_rowremove_row QAction本质上将调用模型方法insertRowsremoveRows

这是一个起作用的示例(除了独立的mariadb模块:

from PySide2 import QtWidgets, QtCore, Qt, QtGui
import maria_db
import numpy

app = QtWidgets.QApplication([])

#Define model for tablePersonnel
class TableModel(QtCore.QAbstractTableModel):

    def __init__(self, db,query,tableName,id):
        super(TableModel, self).__init__()
        self.db=db
        self.query=query
        self.tableName=tableName
        self.id=id
        self.pullData()

    def pullData(self):
        self.datasheet=self.db.RunQuery(self.query)
        self.rows = numpy.array(self.datasheet.fetchall())
        self.headers = numpy.array(self.datasheet.column_names)
        self.idIndex=int(numpy.where(self.headers==self.id)[0])

    def data(self, index, role):
        if role == QtCore.Qt.DisplayRole:
            return str(self.rows[index.row()][index.column()])

    def rowCount(self, parent):
        return len(self.rows)

    def columnCount(self, parent):
        return len(self.headers)

    def headerData(self, section, orientation, role=QtCore.Qt.DisplayRole):
        if orientation == QtCore.Qt.Horizontal and role == QtCore.Qt.DisplayRole:
            return self.headers[section]

    def flags(self,index):
        if index.column()!=self.idIndex:
            return QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsEditable | QtCore.Qt.ItemIsSelectable
        else:
            return QtCore.Qt.ItemIsSelectable

    def setData(self, index,value,role=QtCore.Qt.EditRole):
        if index.isValid():
            sel_id=self.rows[index.row()][0]
            sel_column=self.headers[index.column()]
            if self.db.UpdateCell(self.tableName,sel_id,self.id,sel_column,value)==True:
                self.rows[self.idFinder(self.rows,sel_id)][1]=value
                self.dataChanged.emit(index,index)
        return True

    def insertRows(self):
        print("inserting row!!!")

    def removeRows(self):
        pass

    #find index of selected ID
    def idFinder(self,data, search):
        for i in range(len(data)):
            for j in range(len(data[i])):
                if data[i][j] == search:
                    return i
        else:
            return False

class EditTable(QtWidgets.QTableView):
    def __init__(self):
        super(EditTable, self).__init__()
        self.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
        self.customContextMenuRequested.connect(self.context_menu)

    def context_menu(self):
        context=QtWidgets.QMenu()
        add_row=context.addAction("Add row")
        add_row.triggered.connect(lambda: self.personnelTableModel.insertRows())
        rem_row=context.addAction("Remove row")
        rem_row.triggered.connect(lambda: self.personnelTableModel.removeRows())
        cursor=QtGui.QCursor()
        context.exec_(cursor.pos())


class MainWindow(QtWidgets.QMainWindow):
    def __init__(self):
        super(MainWindow, self).__init__()
        widget = QtWidgets.QWidget()
        layout = QtWidgets.QVBoxLayout()
        widget.setLayout(layout)


        button = QtWidgets.QPushButton("Push me")

        self.db = maria_db.ConnectDb("localhost", "root", "1234", "test")
        self.personnelTableModel = TableModel(self.db,"SELECT * FROM personnel","personnel","personnel_id")

        table = EditTable()
        table.setModel(self.personnelTableModel)

        layout.addWidget(table)
        layout.addWidget(button)

        self.setCentralWidget(widget)


window = MainWindow()
window.show()
app.exec_()

所以我的问题是,当我调用add_row.triggered.connect(lambda: self.personnelTableModel.insertRows())时,我得到了一个'EditTable' object has no attribute 'personnelTableModel',这实际上意味着self中没有方法insertRows。如何通过子类本身引用分配给使用QTableView EditTable子类构造的对象的模型?我会以错误的方式处理此问题吗?

python model-view-controller pyside2
1个回答
0
投票

EditTable的personalTableModel是什么?模型,以及如何从视图访问模型?使用model()方法。另一方面,不需要lambda方法。

def context_menu(self):
    context=QtWidgets.QMenu()
    add_row=context.addAction("Add row")
    add_row.triggered.connect(self.model().insertRows)
    rem_row=context.addAction("Remove row")
    rem_row.triggered.connect(self.model().removeRows)
    cursor=QtGui.QCursor()
    context.exec_(cursor.pos())
© www.soinside.com 2019 - 2024. All rights reserved.