PyQt - QTableView doesn't respond dataChanged signal?

QSqlQueryModel is a great database model, but it is read only. So I rewrite its setData() and flags() method. Now, I can edit my database table from QTableView

But QTableView won't refresh itself when I emited a dataChanged(), when I edited a textbox in the QTableView and clicked somewhere else, the new value wrote into the database successfully, but the value of the textbox reverted to the old value. I have to re-select the whole table, got really bad performance...

Why?

class StudentsTableModel(QtSql.QSqlQueryModel):
    def __init__(self):
        QtSql.QSqlQueryModel.__init__(self)
        self.LockedColumns = []

    def flags(self, index):
        flags = QtSql.QSqlQueryModel.flags(self, index)
        if index.column() not in self.LockedColumns:
            flags |= QtCore.Qt.ItemIsEditable
        return flags

    def setData(self, index, value, role):
        primary_key_index = self.index(index.row(), 0)
        name = self.data(primary_key_index)
        field = self.record().fieldName(index.column())
        self.update(name, field, value)

        self.dataChanged.emit(self.index, self.index)

        # Why DataView isn't refresh automatically when
        # a dataChanged signal emited? Force re-select...
        self.select(self.week)

        return True

    def update(self, name, field, value):
        query = QtSql.QSqlQuery()
        sql = ("UPDATE student_info SET '%s' = '%s' WHERE 学生姓名 = '%s'"
                % (field, value, name))
        query.exec(sql)

    def select(self, week):
        self.week = week
        sql = ("SELECT 学生姓名,第%s周,小组 FROM student_info" % (week))
        self.setQuery(sql)

Answers


See how if this model works for you:

class sqlTableModel(QSqlTableModel):
    def __init__(self, parent=None):
        super(sqlTableModel, self).__init__(parent)

    def setData(self, index, value, role=Qt.EditRole):
        if role == Qt.EditRole:
            value = value.strip() if type(value) == str else value

        return super(sqlTableModel, self).setData(index, value, role)

    def flags(self, index):
        itemFlags = super(sqlTableModel, self).flags(index)

        if index.column() != 0:
            return itemFlags | Qt.ItemIsEditable

        return itemFlags ^ Qt.ItemIsEditable #  First column not editable

Instead of setQuery, to set the table I would have something like this in the main class:

def setDatabase(self, nameDatabase):
    self.database = QSqlDatabase.addDatabase("QSQLITE")
    self.database.setDatabaseName(nameDatabase)

    return self.database.open()

def setTable(self, nameTable):
    self.model = sqlTableModel(self)
    self.model.setEditStrategy(QSqlTableModel.OnManualSubmit)
    self.model.setTable(nameTable)
    self.model.select()

    self.view.setModel(self.model)

def saveTable(self):
    if self.model.submitAll():
        return True

    self.model.database().rollback()
    return False

Need Your Help

Hosting Node with Heroku - Internal Server Error

node.js heroku express

Im trying to host a Node + Express app with Heroku however when I try to render a view I get an "Internal Server Error"

jquery select/option box - linked relationship

jquery select option

Is this case possible using javascript or jquery?

About UNIX Resources Network

Original, collect and organize Developers related documents, information and materials, contains jQuery, Html, CSS, MySQL, .NET, ASP.NET, SQL, objective-c, iPhone, Ruby on Rails, C, SQL Server, Ruby, Arrays, Regex, ASP.NET MVC, WPF, XML, Ajax, DataBase, and so on.