Mengubah Warna Baris Saat Klik PyQt

Saya sudah mencoba mengerjakan ini selama berhari-hari, tetapi tidak berhasil, jadi semoga kalian dapat membantu saya.

Saya punya QSqlTableModel khusus yang memiliki ini sebagai fungsi datanya:

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)

Tidak ada satupun yang benar-benar relevan dengan pertanyaan kecuali blok BackgroundRole. Apa yang saya coba lakukan adalah ketika saya mengklik kanan pada tableview, menu konteks muncul:

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)

Yang saya coba lakukan adalah ketika saya mengklik "Mark Step as Executed" pada menu konteks saya, saya ingin baris (atau bahkan sel, saya akan mengambil apa pun saat ini) berubah menjadi merah.

Apa yang saya lakukan tidak ada yang berhasil dan saya berharap seseorang dapat membantu saya.


person aseylys    schedule 25.09.2017    source sumber


Jawaban (1)


Solusi sederhana adalah dengan membuat bidang dalam tabel database dan menggunakannya sebagai tanda untuk mengubah warna latar belakang, namun jika Anda tidak dapat membuat perubahan tersebut dalam database, Anda harus membuat peran baru. dan kemudian kita akan menggunakan peran itu untuk membuat perubahan yang diperlukan, untuk ini kita akan menyimpan tandanya di kamus, kunci kamusnya adalah id karena ini tidak berubah.

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

Cara di atas hanya mengubah item yang dipilih hingga disegarkan secara manual, tetapi perilaku ini bukan yang ingin dilakukan sehingga sinyal model dataChanged() harus dikeluarkan.

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])

Keuntungan penerapan saat ini adalah tidak dipilihnya jika kita mengubah status dari Benar ke Salah.

self.model().setData(index, False, SqlTableModel.ExecuteRole)
person eyllanesc    schedule 25.09.2017
comment
Terima kasih banyak untuk ini! Ini berfungsi dalam arti memang mengubah warna, dan saya senang bisa mengembalikan warnanya. Namun, tampaknya mengubah seluruh tabel menjadi merah. Bukan hanya baris yang dipilih. Mengapa hal itu bisa terjadi? - person aseylys; 25.09.2017
comment
Apa kamu yakin? Dalam pengujian saya, cukup ubah baris yang dipilih, coba contoh berikut dan beri tahu saya jika Anda memiliki kesalahan yang sama: gist.github.com/eyllanesc/150e981878122e171bd25dc470781a87 - person eyllanesc; 25.09.2017
comment
Jika Anda membagikan proyek Anda untuk memeriksa di mana Anda melakukan kesalahan. Jika jawaban saya membantu Anda jangan lupa menandainya sebagai benar. - person eyllanesc; 25.09.2017
comment
Contoh Anda berhasil, tetapi contoh saya tidak. Saya yakin ini ada hubungannya dengan cara saya menginisialisasi qTableView. Tapi inilah proyek saya sejauh ini. github.com/aseylys/sView EDIT: Dan saya menandai Anda sebagai terjawab karena Anda melakukannya, itu program saya ketidakmampuan untuk bekerja sama itulah masalahnya - person aseylys; 25.09.2017
comment
@aseylys Bagaimana cara memuat database? Saya tidak melihat data apa pun di tampilan tabel. - person eyllanesc; 25.09.2017
comment
File->Open Script, maaf, saya belum sempat membaca README. - person aseylys; 25.09.2017
comment
Masalahnya adalah Anda tidak memiliki kunci utama di tabel Anda, tapi menurut saya Row # dapat digunakan dengan mengubah: ix = self.fieldIndex("id") menjadi ix = self.fieldIndex("Row #") - person eyllanesc; 25.09.2017