Python 单击PyQt更改行颜色

Python 单击PyQt更改行颜色,python,python-3.x,pyqt,pyqt5,Python,Python 3.x,Pyqt,Pyqt5,这几天我一直在努力,但都没用,希望你们能帮我 我有一个定制的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(s

这几天我一直在努力,但都没用,希望你们能帮我

我有一个定制的
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)
我所要做的就是当我在上下文菜单上单击“将步骤标记为已执行”时,我希望该行(甚至单元格,此时我将选择任何内容)变为红色


我所做的一切都不起作用,我希望有人能帮助我

一个简单的解决方案是在数据库表中创建一个字段,并将其用作更改背景颜色的标志,但如果无法在数据库中进行更改,则必须创建一个新角色。然后我们将使用该角色进行必要的更改,为此我们将在字典中保存标志,字典的键将是id,因为这些不会更改

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
上述操作仅在手动刷新之前更改选定项,但此行为不是要执行此操作的行为必须发出model
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)

非常感谢!这确实改变了颜色,我喜欢我能还原颜色。然而,它似乎改变了整个表红色。不仅仅是选定的行。为什么会这样?你确定吗?在我的测试中,只需更改所选的行,尝试以下示例,并让我知道是否存在相同的错误:如果共享项目以检查哪里出错。如果我的答案对你有帮助,请别忘了把它标为正确的。你的例子有效,但我的不行。我相信这与我如何初始化
qTableView
有关。但这是我目前的项目。编辑:我将您标记为已回答,因为您这样做了,问题是我的程序无法合作。问题是您的表中没有主键,但我认为可以通过更改来使用
Row
ix=self.fieldIndex(“id”)
ix=self.fieldIndex(“Row”)