2017-08-24 15 views
-1

私は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行目は、直前に削除されました):

Screenshot of QTableView with one row deleted

行を削除しても問題が解決しない場合は、詳細な説明が見つからない「終了コード11で処理済み」でアプリケーションを終了させて​​ください(プラットフォーム固有、Mac OSおよびPython 3.6でPyCharmを使用しています)

ありがとうございました

答えて

1

これはわかりました。やや。 それは直接の回答ではありませんが、削除方法をコンテキストメニューからツールバーアイコンに変更しました。シンプル

def deletePayRate(self): 
    index = self.currentIndex() 
    deleteconfirmation = QtWidgets.QMessageBox.critical(self.parent(), "Delete row", "Really delete the selected Pay Rate?", QtWidgets.QMessageBox.Yes, QtWidgets.QMessageBox.No) 
    if deleteconfirmation == QtWidgets.QMessageBox.Yes: 
     self.model.removeRow(index.row()) 
     self.model.submitAll() 
     return 
    else: 
     return 

を、それは動作します: 選択行、以下のクラスのメソッドを呼び出し、ツールバーのアイコンをクリックしてください。

関連する問題