Как получить информацию о том, что пользователь изменил таблицу в PyQT с помощью Python и SQLite3

У меня есть таблица, которая появляется в моем графическом интерфейсе. Пользователь может редактировать эту таблицу из графического интерфейса. как мне получить всю отредактированную информацию и обновить ее в базе данных? Пользователь устанавливает флажок для каждой строки, которую он хочет обновить в базе данных, поэтому у меня есть список всех строк, которые требуют обновления. Я хочу иметь список кортежей, где каждый кортеж представляет собой строку новых значений, которые необходимо обновить, учитывая, что поле ID остается неизменным (я также хочу знать, как сделать так, чтобы пользователь не мог редактировать некоторые поля).

def click_btn_mailouts(self):
    self.screen_name = "mailouts"
    self.cur.execute("""SELECT s.StudentID, s.FullName, m.PreviouslyMailed, m.nextMail, m.learnersDate, m.RestrictedDate, m.DefensiveDate FROM
                        StudentProfile s LEFT JOIN Mailouts m ON s.studentID=m.studentID""")
    self.all_data = self.cur.fetchall()

    self.table.setRowCount(len(self.all_data))
    self.tableFields = ["Check","Full name","Previously mailed?","Next mail","learnersDate","Restricted date","Defensive driving date"]
    self.table.setColumnCount(len(self.tableFields))
    self.table.setHorizontalHeaderLabels(self.tableFields)
    self.checkbox_list = []
    for i, item in enumerate(self.all_data):
        FullName = QtGui.QTableWidgetItem(str(item[1]))
        PreviouslyMailed = QtGui.QTableWidgetItem(str(item[2]))
        LearnersDate = QtGui.QTableWidgetItem(str(item[3]))
        RestrictedDate = QtGui.QTableWidgetItem(str(item[4]))
        DefensiveDate = QtGui.QTableWidgetItem(str(item[5]))
        NextMail = QtGui.QTableWidgetItem(str(item[6]))
        self.table.setItem(i, 1, FullName)
        self.table.setItem(i, 2, PreviouslyMailed)
        self.table.setItem(i, 3, LearnersDate)
        self.table.setItem(i, 4, RestrictedDate)
        self.table.setItem(i, 5, DefensiveDate)
        self.table.setItem(i, 6, NextMail)
        chkBoxItem = QtGui.QTableWidgetItem()
        chkBoxItem.setFlags(QtCore.Qt.ItemIsUserCheckable | QtCore.Qt.ItemIsEnabled)
        chkBoxItem.setCheckState(QtCore.Qt.Unchecked)
        self.checkbox_list.append(chkBoxItem)
        self.table.setItem(i, 0, self.checkbox_list[i])

"""here is the format that I have for the edit function"""

def click_btn_edit(self):
    checkedRows = []
    for i, checkbox in enumerate(self.checkbox_list):
        if checkbox.checkState() == QtCore.Qt.Checked:
            checkedRows.append(i)
            """as the list itterates, if the checkbox item is ticked, 
            it passes through the if statement, otherwise it is ignored.
            checkedRows becomes a list of all the indexes in the table where
            an edit needs to be made"""                

Итак, в основном мне нужно знать, как получить изменения, внесенные в QTableWidget в графическом интерфейсе, с учетом списка индексов, в которые были внесены изменения, и каким-то образом обновить эти изменения в базе данных. Также было бы полезно знать, как запретить пользователю редактировать некоторые поля, так как это приведет к беспорядку в базе данных.


person Paul Jackways    schedule 28.09.2016    source источник
comment
Нужно ли манипулировать базой данных вручную? PyQt предлагает отличный интерфейс под названием QtSql, в котором вы можете определить подключение к базе данных QtSql.QSqlDatabase. Затем она управляется моделью базы данных QtSql.QSqlTableModel и подключается к базе данных QtGui.QTableView. Таким образом, изменения в QTableView напрямую отражаются в базе данных без необходимости написания каких-либо запросов к базе данных. Хорошей отправной точкой может быть это руководство tutorialspoint.com/pyqt/pyqt_database_handling.htm.   -  person ImportanceOfBeingErnest    schedule 28.09.2016
comment
Я вынужден быть самоучкой в ​​​​PyQT, поэтому я не знал, что это вообще существует. Моя программа уже слишком зависит от QTableWidget. Есть ли способ установить стратегию редактирования для QTableWidget или способ доступа к данным, которые пользователь отредактировал в таблице?   -  person Paul Jackways    schedule 01.10.2016
comment
Я все же думаю, что стоит использовать интерфейс QtSql. Поскольку QTableWidget наследуется от QTableView, я не могу себе представить, что вам нужно будет многое изменить в своем коде, за исключением удаления множества ненужных строк.   -  person ImportanceOfBeingErnest    schedule 01.10.2016


Ответы (1)


Вы можете делать несколько разных вещей.

Чтобы предотвратить редактирование, вы можете просто удалить флаг редактирования для элементов, которые вы не хотите, чтобы пользователь редактировал.

FullName.setFlags(FullName.flags() & ~Qt.ItemIsEditable)

Похоже, вы сохраняете исходные данные (например, self.all_data). Вы можете просто сравнить данные в выбранных ячейках таблицы с исходными данными и обновить только поля, которые изменились.

Вы также можете подключиться к сигналу itemChanged для виджета таблицы и сохранить текущий список всех индексов, которые изменились с момента последнего обновления

    ...
    self.changed_items = set()
    self.table.itemChanged.connect(self.log_change)

def log_change(self, item):
    self.changed_items.add(item)

В качестве альтернативы, в зависимости от того, сколько контроля вы хотите, вы также можете создать QItemDelegate, чтобы делать все это.

person Brendan Abel    schedule 28.09.2016
comment
Когда я попробовал первое предложение, я получил ошибку: AttributeError: объект «QTableWidgetItem» не имеет атрибута «setItemFlags». Я поместил их внизу функции click_btn_mailouts(). - person Paul Jackways; 29.09.2016
comment
Я удалил «элемент» из «setItemFlags», и это сработало, спасибо. - person Paul Jackways; 29.09.2016
comment
Что такое элемент в функции, которую вы предоставили? Если это QTableWidgetItem, мне может понадобиться объяснение, что это такое, потому что я действительно не знаю, как работают элементы. - person Paul Jackways; 29.09.2016
comment
Итак, теперь у меня есть список записей, которые были отредактированы, но записи — это неотредактированные записи. Есть ли способ получить отредактированные записи? - person Paul Jackways; 29.09.2016
comment
@PaulJackways Я не понимаю, что вы имеете в виду. Отредактированные данные должны содержаться в каждом тексте QTableWidgetItem. - person Brendan Abel; 29.09.2016
comment
У меня есть код: FullName.setFlags(FullName.flags() & ~Qt.ItemIsEditable) NextMail.setFlags(NextMail.flags() & ~Qt.ItemIsEditable) self.changed_items = set() self.table.itemChanged.connect(self.log_change) .................................................. ................................. def log_change(self): self.changed_items.add(self.item) print(self.item) и печатает то, что было в записях до того, как они были отредактированы. - person Paul Jackways; 02.10.2016