私はQTableView
クラスを持ち、SQLITEデータベース内からデータを表示するにはQSQLRelationalTableModel
クラスを持っています。Python - QSQLRelationalTableModel/QTableViewから選択した行を削除する
私はPyQtクラス内のさまざまなメソッドを上書きする必要があるため、これらを自分自身にサブクラス化しました。
私は、TableViewを自動的に再描画する「行を削除する」機能を実装しようとしています。
残念ながら私は迷っています。一部の列に対して返されるデータを変更する必要があるため、モデル内でdata()
メソッドを上書きしました。 行を削除すると、このdata()
メソッドは明らかにその行を返すことはなく、型エラーが発生します(欠落している行のデータが返されることを期待しています)。 現時点では、try/exceptブロック(それは悪い習慣であることがわかっています)に座っていて、動作しない場合は "Deleted"を返します。ここで
は私の完全なモデルである:ここでは
class PayRateTableModel(QtSql.QSqlRelationalTableModel):
def __init__(self,master):
QtSql.QSqlRelationalTableModel.__init__(self,db=master.db)
self.header_labels = ['ID','From','To','Day Rate','Night Rate', 'Description']
self.editable_columns = [1,2,3,4,5]
self.setTable('payrates')
self.setEditStrategy(QtSql.QSqlRelationalTableModel.OnRowChange)
self.select()
def columnCount(self,master,parent=QtCore.QModelIndex()):
return 6
def flags(self, index):
flags=super(self.__class__, self).flags(index)
if index.column() not in self.editable_columns:
flags ^= QtCore.Qt.ItemIsEditable
return flags
def headerData(self, p_int, Qt_Orientation, role=QtCore.Qt.DisplayRole):
if role == QtCore.Qt.DisplayRole and Qt_Orientation == QtCore.Qt.Horizontal:
return self.header_labels[p_int]
return QtCore.QAbstractTableModel.headerData(self,p_int, Qt_Orientation,role)
def data(self, index, role):
row=index.row()
col=index.column()
data = super(PayRateTableModel, self).data(index, role)
if role==QtCore.Qt.TextAlignmentRole:
return QtCore.Qt.AlignCenter
elif role==QtCore.Qt.FontRole:
f=QtGui.QFont
return f
elif role==QtCore.Qt.ForegroundRole and index.column() not in self.editable_columns:
return QtGui.QColor(150,150,150)
try:
if (col in [1,2]) and (role==QtCore.Qt.DisplayRole) and data:
data=super(PayRateTableModel, self).data(index,role)
year=data[:4]
month=data[5:7]
day=data[8:10]
data=QtCore.QDate(int(year),int(month),int(day)).toString("dd/MM/yyyy")
return data
elif col in [3,4] and role ==QtCore.Qt.DisplayRole:
data=super(PayRateTableModel, self).data(index,role)
return '%.4f' % data
except:
return "Deleted"
return super(PayRateTableModel, self).data(index,role)
は私のテーブルビューには、これは実際に動作しますが、それはデータを削除しますが、それはのようなテーブルの上に半分の行を残し
class PayRateTableView(QtWidgets.QTableView):
""" Display table of editable pay rates"""
def __init__(self, master):
QtWidgets.QTableView.__init__(self)
self.hideColumn(0)
self.setSortingEnabled(True)
self.model = PayRateTableModel(master)
self.sortmodel=DateSortProxyModel()
self.sortmodel.setSourceModel(self.model)
self.setModel(self.sortmodel)
self.sortByColumn(1,QtCore.Qt.AscendingOrder)
self.setSelectionBehavior(QtWidgets.QTableView.SelectRows)
self.resizeRowsToContents()
self.resizeColumnsToContents()
self.setAlternatingRowColors(True)
self.horizontalHeader().setSectionResizeMode(QtWidgets.QHeaderView.Stretch)
self.setItemDelegateForColumn(1, CalendarDelegate(master))
self.setItemDelegateForColumn(2, CalendarDelegate(master))
self.setItemDelegateForColumn(3, PayRateDelegate(master))
self.setItemDelegateForColumn(4, PayRateDelegate(master))
self.vhead=self.verticalHeader()
self.vhead.setVisible(False)
self.vhead.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
self.vhead.customContextMenuRequested.connect(self.contextMenuEvent)
def sizeHintForRow(self, p_int):
return 20
def contextMenuEvent(self, event):
index = self.currentIndex()
menu=QtWidgets.QMenu(self)
menu.popup(QtGui.QCursor.pos())
deleteAction = menu.addAction("Delete Row")
action = menu.exec_(self.mapToGlobal(event.pos()))
if action == deleteAction:
self.model.removeRow(index.row())
self.model.submitAll()
ですこの(3行目は、直前に削除されました):
行を削除しても問題が解決しない場合は、詳細な説明が見つからない「終了コード11で処理済み」でアプリケーションを終了させてください(プラットフォーム固有、Mac OSおよびPython 3.6でPyCharmを使用しています)
ありがとうございました