2017-09-25 181 views
0

我一直在努力工作這幾天,沒有用,所以希望你們可以幫助我。改變行顏色點擊PyQt

我有一個自定義QSqlTableModel有這個,因爲它的數據功能:

def data(self, index, role): 
    #Formats Cells according to data in them 
    if role == QtCore.Qt.TextAlignmentRole: 
     if index.column() == 2: 
      text = QtSql.QSqlTableModel.data(self, self.index(index.row(), 2), QtCore.Qt.DisplayRole) 

      if text.split(): 
       if not re.search(r'start|Z[NARXTFEISL]|gv', text.split()[0], re.I): 
        return QtCore.Qt.AlignHCenter | QtCore.Qt.AlignTop 
       else: return QtCore.Qt.AlignLeft 
      else: pass 
     else: return QtCore.Qt.AlignLeft 

    if role == QtCore.Qt.BackgroundRole: 
     if 'MILESTONE' in QtSql.QSqlTableModel.data(self, self.index(index.row(), 2), QtCore.Qt.DisplayRole): 
      return QtGui.QBrush(QtCore.Qt.yellow) 


    return QtSql.QSqlTableModel.data(self, index, role) 

這都不是除了BackgroundRole塊真正的問題有關。我想要做的是,當我右鍵單擊tableview上下文菜單上顯示:

menu = QMenu() 
stepx = menu.addAction('Mark Step as Executed') 
stepdx = menu.addAction('Clear Step Execution') 

action = menu.exec_(self.tableView.mapToGlobal(pos)) 
index = self.model.index(self.tableView.rowAt(pos.y()), 2) 

if action == stepx: 
    logging.info(' Executed Step: ' + str(self.tableView.rowAt(pos.y()) + 1)) 
    self.model.setData(index, QtCore.QVariant(QtGui.QBrush(QtCore.Qt.red)), QtCore.Qt.BackgroundRole) 

所有我想要做的是,當我點擊我的"Mark Step as Executed"上下文菜單上,我想行(或甚至細胞,我會採取任何在這一點上)改變爲紅色。

沒有什麼我在做什麼工作,我希望有人可以幫助我。

回答

1

一個簡單的解決方案是在數據庫表中創建一個字段並用作標誌來更改背景顏色,但是如果無法在數據庫中進行更改,則必須創建一個新角色。然後我們將使用該角色進行必要的更改,爲此我們將標誌保存在字典中,字典的關鍵字將作爲標識,因爲這些標識不會更改。

class SqlTableModel(QtSql.QSqlTableModel): 
    ExecuteRole = QtCore.Qt.UserRole + 1 

    def __init__(self, parent=None, db = QtSql.QSqlDatabase()): 
     QtSql.QSqlTableModel.__init__(self, parent, db) 
     self.d = {} 

    def data(self, index, role): 
     if role == self.ExecuteRole: 
      _id = self.getId(index) 
      if _id in self.d.keys(): 
       return self.d[_id] 
      return False 

     if role == QtCore.Qt.BackgroundRole: 
      if self.data(index, self.ExecuteRole): 
       return QtGui.QBrush(QtCore.Qt.red) 
      if 'MILESTONE' in QtSql.QSqlTableModel.data(self, self.index(index.row(), 2), QtCore.Qt.DisplayRole): 
       return QtGui.QBrush(QtCore.Qt.yellow) 

     return QtSql.QSqlTableModel.data(self, index, role) 

    def getId(self, index): 
     ix = self.fieldIndex("id") 
     return self.data(self.index(index.row(), ix), QtCore.Qt.DisplayRole) 

    def setData(self, index, value, role): 
     if role == self.ExecuteRole: 
      self.d[self.getId(index)] = value 
      return True 
     return QtSql.QSqlTableModel.setData(self, index, value, role) 

    def roleNames(self): 
     rn = QtSql.QSqlTableModel.roleNames(self) 
     rn[self.SelectRole] = QtCore.QByteArray(b'execute') 
     return rn 

以上只改變一個選擇的項目,直到它被手動刷新,但是這種行爲是不被希望這樣做必須出具模型dataChanged()信號之一。

class TableView(QtWidgets.QTableView): 
    def contextMenuEvent(self, event): 
     pos = event.pos() 
     menu = QtWidgets.QMenu() 
     stepx = menu.addAction('Mark Step as Executed') 
     stepdx = menu.addAction('Clear Step Execution') 

     action = menu.exec_(self.mapToGlobal(pos)) 
     if action == stepx: 
      if self.model(): 
       index = self.model().index(self.rowAt(pos.y()), 2) 
       self.model().setData(index, True, SqlTableModel.ExecuteRole) 
       self.model().dataChanged.emit(self.model().index(index.row(), 0), 
               self.model().index(index.row(), self.model().columnCount()-1), 
               [QtCore.Qt.BackgroundRole]) 

當前實現的優點是,如果將狀態從True更改爲False,則取消選擇。

self.model().setData(index, False, SqlTableModel.ExecuteRole) 
+0

非常感謝!這在某種意義上起作用,它的確會改變顏色,我喜歡我可以恢復顏色。但是,它似乎將整個表格改爲紅色。不只是所選的行。爲什麼會這樣? – aseylys

+0

你確定嗎?在我的測試中,只需更改所選行,請嘗試以下示例,並讓我知道是否有相同的錯誤:https://gist.github.com/eyllanesc/150e981878122e171bd25dc470781a87 – eyllanesc

+0

如果您分享項目以檢查您所做的項目一個失誤。如果我的答案可以幫助您,請不要忘記標記爲正確。 – eyllanesc