gpt4 book ai didi

python - QTableView 编辑模式的问题

转载 作者:行者123 更新时间:2023-12-01 08:46:58 25 4
gpt4 key购买 nike

我对 QStandardItemModel 进行了子类化:

class PPSTableEditModel(QStandardItemModel):

def __init__(self, parent=None):
super(PPSTableEditModel, self).__init__(parent)
self.proxy = QSortFilterProxyModel()
self.proxy.setSourceModel(self)
self.proxy.setFilterKeyColumn(5)
self.proxy.setDynamicSortFilter(True)
self.proxy.setFilterFixedString("0")
self.editmode = None
self.history = []

def edit_record(self, qndx):

#qndx is passed from a QTableView class and contains view.currentIndex()

self.editmode = 2
del self.history[:]
for ndx in range(0, self.columnCount()):
self.history.append(self.item(qndx.row(),ndx).data(Qt.DisplayRole))
self.process_record(qndx) #<---- This works

#ix = self.index(qndx.row(),2)
#self.process_record(ix) #<---- This causes the error

def process_record(self, pndx):
self.parent().tbl_View.selectionModel().setCurrentIndex(pndx, QItemSelectionModel.Select)
self.parent().tbl_View.edit(pndx)

我遇到的问题来自于 edit_record 方法,我将 qndx 传递给 process_record 并且 View 正确进入编辑模式;但是,如果我尝试设置起始列(通过重新分配 qndx),则会收到错误:

edit: index was invalid
edit: editing failed

* 编辑*尝试映射到代理索引进行编辑,但仍然遇到相同的错误:

def edit_record(self, qndx):
self.editmode = 2
del self.history[:]
for ndx in range(0, self.columnCount()):
self.history.append(self.item(qndx.row(),ndx).data(Qt.DisplayRole))
ix = qndx if not self.proxy else self.proxy.mapToSource(qndx)
self.process_record(ix)

* 编辑*MCVE:

import uuid,sys
from PyQt5.QtSql import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *

class PPSTableEditModel(QStandardItemModel):
model_loaded = pyqtSignal()

def __init__(self, parent=None):
super(PPSTableEditModel, self).__init__(parent)
self.proxy = None

def edit_record(self, qndx):
ix = qndx if not self.proxy else self.proxy.mapToSource(qndx)
self.process_record(ix)

def process_record(self, pndx):
self.parent().tbl_View.selectionModel().setCurrentIndex(pndx, QItemSelectionModel.Select)
self.parent().tbl_View.edit(pndx)


class SclDataModel(PPSTableEditModel):

def __init__(self, parent=None):
super(SclDataModel, self).__init__(parent)
self.proxy = QSortFilterProxyModel(self)
self.proxy.setSourceModel(self)
self.proxy.setFilterKeyColumn(5)
self.proxy.setDynamicSortFilter(True)
self.proxy.setFilterFixedString("0")

def load_data(self, parentid):
query = QSqlQuery()
query.prepare('SELECT * FROM scldata WHERE svcdataid=?')
query.addBindValue(parentid)
query.exec_()
while query.next():
record = []
for ndx in range(0, query.record().count()):
item = QStandardItem()
item.setData(query.value(ndx), Qt.DisplayRole)
record.append(item)
record.append(QStandardItem("0"))
self.insertRow(self.rowCount(), record)
self.model_loaded.emit()


class SclDataBrowse(QWidget):
def __init__(self, parent=None):
super(SclDataBrowse, self).__init__(parent)
self.resize(600, 297)
self.tbl_View = QTableView(self)
self.line = QFrame(self)
self.line.setFrameShape(QFrame.HLine)
self.line.setFrameShadow(QFrame.Sunken)
self.spacer = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum)
self.view_layout = QVBoxLayout(self)
self.view_layout.setContentsMargins(0, 0, 0, 0)
self.view_layout.addWidget(self.tbl_View)
self.view_layout.addWidget(self.line)
self.model = SclDataModel(self)
self.parentid = None
self.setup_view()
self.setup_connections()

def setup_view(self):
self.tbl_View.setModel(self.model.proxy)
self.tbl_View.setEditTriggers(QAbstractItemView.NoEditTriggers)
self.tbl_View.setSelectionMode(QAbstractItemView.SingleSelection)
self.tbl_View.setSelectionBehavior(QAbstractItemView.SelectRows)
self.tbl_View.verticalHeader().setVisible(False)
self.tbl_View.verticalHeader().setDefaultSectionSize(22)

def setup_connections(self):
self.tbl_View.doubleClicked.connect(self.edit_record)
self.model.model_loaded.connect(self.format_view)

def set_parent(self, parentid):
self.parentid = parentid
self.model.load_data(self.parentid)

def format_view(self):
if self.model.rowCount():
header = ["recorid", "svcdataid", "Start Amount", "End Amount", "Rate", "deleteflag"]
for n in range(0, len(header)):
self.model.setHeaderData(n, Qt.Horizontal, header[n])
self.tbl_View.horizontalHeader().setSectionResizeMode(2, QHeaderView.Stretch)
self.tbl_View.horizontalHeader().setSectionResizeMode(3, QHeaderView.Stretch)
self.tbl_View.setColumnWidth(4, 85)
self.tbl_View.setColumnHidden(0, True)
self.tbl_View.setColumnHidden(1, True)
self.tbl_View.setColumnHidden(5, True)

def set_parent_record(self, parentid):
self.parentid = parentid
self.model.load_data(self.parentid)

def edit_record(self):
qndx = self.tbl_View.currentIndex()
self.model.edit_record(qndx)


app = QApplication(sys.argv)
mainWin = SclDataBrowse()
db = QSqlDatabase.addDatabase("QMYSQL")
db.setHostName("myhost")
db.setUserName("myusr")
db.setPassword("mypassword")
db.setDatabaseName("mydbname")
db.open()
mainWin.show()
mainWin.set_parent("a5865717-e125-11e8-80c0-d4ae52cc00a8")
sys.exit(app.exec_())

* 编辑*似乎与 QSortFilterProxyModel 相关,尽管我无法确定它。将索引传递给 process_record 而不通过代理映射它允许我进行编辑,但底层数据不正确。

*** EDIT ***
import sys

from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtSql import *
from PyQt5.QtWidgets import *


class PPSTableEditModel(QStandardItemModel):
model_loaded = pyqtSignal()

def __init__(self, parent=None):
super(PPSTableEditModel, self).__init__(parent)
self.proxy = None

def edit_record(self, qndx):
ix = qndx.sibling(qndx.row(), 2)
self.process_record(ix)
#ix = qndx if not self.proxy else self.proxy.mapToSource(qndx)
#self.process_record(ix)

def delete_record(self, qndx):
ix = qndx if not self.proxy else self.proxy.mapToSource(qndx)
self.item(ix.row(),5).setData("1",Qt.DisplayRole)

def process_record(self, pndx):
for ndx in range(0,self.columnCount()):
print('{0},{1}----->{2}'.format(pndx.row(),ndx,self.item(pndx.row(),ndx).data(Qt.DisplayRole)))
self.parent().tbl_View.selectionModel().setCurrentIndex(pndx, QItemSelectionModel.Select)
self.parent().tbl_View.edit(pndx)


class SclDataModel(PPSTableEditModel):

def __init__(self, parent=None):
super(SclDataModel, self).__init__(parent)
self.proxy = QSortFilterProxyModel(self)
self.proxy.setSourceModel(self)
self.proxy.setFilterKeyColumn(5)
self.proxy.setDynamicSortFilter(True)
self.proxy.setFilterFixedString("0")

def load_data(self, parentid):
data = (
{"recordid": "1", "svcdataid": 1, "samount": .01, "eamount": 5000, "rate": .065, "delflag": "0"},
{"recordid": "2", "svcdataid": 1, "samount": 5000.01, "eamount": 10000, "rate": .065, "delflag": "0"},
{"recordid": "3", "svcdataid": 1, "samount": 10000.01, "eamount": 15000, "rate": .060, "delflag": "0"},
{"recordid": "4", "svcdataid": 1, "samount": 15000.01, "eamount": 20000, "rate": .055, "delflag": "0"},
{"recordid": "5", "svcdataid": 1, "samount": 20000.01, "eamount": 99999, "rate": .05, "delflag": "0"}
)
for ndx,rec in enumerate(data):
record = []
for key in rec:
item = QStandardItem()
item.setData(rec[key], Qt.DisplayRole)
record.append(item)
self.insertRow(self.rowCount(), record)
self.model_loaded.emit()


class SclDataBrowse(QWidget):
def __init__(self, parent=None):
super(SclDataBrowse, self).__init__(parent)
self.resize(600, 297)
self.tbl_View = QTableView(self)
self.line = QFrame(self)
self.line.setFrameShape(QFrame.HLine)
self.line.setFrameShadow(QFrame.Sunken)
self.spacer = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum)
self.view_layout = QVBoxLayout(self)
self.view_layout.setContentsMargins(0, 0, 0, 0)
self.view_layout.addWidget(self.tbl_View)
self.view_layout.addWidget(self.line)
self.btn_layout = QHBoxLayout()
self.btn_layout.setContentsMargins(6, 6, 6, 6)
self.btn_delete = QPushButton()
self.btn_delete.setText("Delete")
self.btn_layout.addWidget(self.btn_delete)
self.view_layout.addLayout(self.btn_layout)
self.model = SclDataModel(self)
self.parentid = None
self.setup_view()
self.setup_connections()

def setup_view(self):
self.tbl_View.setModel(self.model.proxy)
self.tbl_View.setEditTriggers(QAbstractItemView.NoEditTriggers)
self.tbl_View.setSelectionMode(QAbstractItemView.SingleSelection)
self.tbl_View.setSelectionBehavior(QAbstractItemView.SelectRows)
self.tbl_View.verticalHeader().setVisible(False)
self.tbl_View.verticalHeader().setDefaultSectionSize(22)

def setup_connections(self):
self.tbl_View.doubleClicked.connect(self.edit_record)
self.btn_delete.clicked.connect(self.delete_record)
self.model.model_loaded.connect(self.format_view)

def set_parent(self, parentid):
self.parentid = parentid
self.model.load_data(self.parentid)

def format_view(self):
if self.model.rowCount():
header = ["recorid", "svcdataid", "Start Amount", "End Amount", "Rate", "deleteflag"]
for n in range(0, len(header)):
self.model.setHeaderData(n, Qt.Horizontal, header[n])
self.tbl_View.horizontalHeader().setSectionResizeMode(2, QHeaderView.Stretch)
self.tbl_View.horizontalHeader().setSectionResizeMode(3, QHeaderView.Stretch)
self.tbl_View.setColumnWidth(4, 85)
self.tbl_View.setColumnHidden(0, True)
self.tbl_View.setColumnHidden(1, True)
self.tbl_View.setColumnHidden(5, True)

def set_parent_record(self, parentid):
self.parentid = parentid
self.model.load_data(self.parentid)

def edit_record(self):
qndx = self.tbl_View.currentIndex()
self.model.edit_record(qndx)

def delete_record(self):
qndx = self.tbl_View.currentIndex()
self.model.delete_record(qndx)



app = QApplication(sys.argv)
mainWin = SclDataBrowse()
mainWin.show()
mainWin.set_parent("a5865717-e125-11e8-80c0-d4ae52cc00a8")
sys.exit(app.exec_())

使用此代码,表中有 5 个条目。例如,如果您删除第二条记录,过滤器会正确隐藏“已删除”记录。现在双击第三行或第四行,process_record 中输出的数据报告正确的行,但与该行关联的数据不正确。

最佳答案

根据您的代码,您想要访问位于同一行但在第二列的索引,即它是 QModelIndex 的同级,因此您必须使用同级功能:

def edit_record(self, qndx):
ix = qndx.sibling(qndx.row(), 2)
self.process_record(ix)
<小时/>

问题是因为你使用item来获取数据,QTableView不知道k,它只知道已经建立的模型,即QSortFilterProxyModel,所以需要 edit()selectionModel().SetCurrentIndex() 的 QModelIndex 必须是 QSortFilterProxyModel 这就是为什么我的初始解决方案有效,但在您的印象中,您使用的是 PPSTableEditModel 模型,因此解决方案是使用代理,但没有必要存储它,因为 QModelIndex 保存模型引用所属:

def process_record(self, pndx):
model = pndx.model()
for ndx in range(model.columnCount()):
print('{0},{1}----->{2}'.format(pndx.row(), ndx, model.index(pndx.row(),ndx).data(Qt.DisplayRole)))
self.parent().tbl_View.selectionModel().setCurrentIndex(pndx, QItemSelectionModel.Select)
self.parent().tbl_View.edit(pndx)

关于python - QTableView 编辑模式的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53268053/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com