Bagaimana cara mendapatkan informasi bahwa pengguna telah mengubah tabel di PyQT dengan Python dan SQLite3

Saya memiliki tabel yang muncul di GUI saya. Pengguna dapat mengedit tabel ini dari GUI. bagaimana cara mendapatkan semua informasi yang telah diedit dan memperbaruinya di database? Pengguna mencentang kotak untuk setiap baris yang ingin mereka perbarui ke database, jadi saya memiliki daftar semua baris yang perlu diperbarui. Saya ingin memiliki daftar tupel, di mana setiap tupel adalah deretan nilai baru yang perlu diperbarui, mengingat bidang ID tetap tidak berubah (saya juga ingin tahu cara membuat pengguna tidak dapat mengedit beberapa bidang).

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"""                

Jadi pada dasarnya saya perlu tahu cara membuat perubahan di QTableWidget di GUI mengingat daftar indeks tempat perubahan telah dilakukan, dan entah bagaimana memperbarui perubahan tersebut ke dalam database. Akan sangat membantu juga jika mengetahui cara menghentikan pengguna mengedit beberapa kolom, karena hal itu akan mengacaukan database.


person Paul Jackways    schedule 28.09.2016    source sumber
comment
Apakah perlu memanipulasi database secara manual? PyQt menawarkan antarmuka hebat yang disebut QtSql tempat Anda dapat menentukan koneksi database QtSql.QSqlDatabase. Ini kemudian dikelola oleh model database QtSql.QSqlTableModel dan dihubungkan ke QtGui.QTableView. Dengan cara ini, perubahan dalam QTableView secara langsung tercermin dalam database tanpa perlu menulis query database apa pun. Titik awal yang baik mungkin adalah tutorial ini tutorialspoint.com/pyqt/pyqt_database_handling.htm   -  person ImportanceOfBeingErnest    schedule 28.09.2016
comment
Saya terpaksa otodidak di PyQT, jadi saya tidak tahu kalau ini ada. Program saya sudah terlalu bergantung pada QTableWidget. Apakah ada cara agar Anda dapat menetapkan strategi edit untuk QTableWidget, atau cara agar Anda dapat mengakses data yang telah diedit pengguna di tabel?   -  person Paul Jackways    schedule 01.10.2016
comment
Saya masih berpikir bahwa ada baiknya menggunakan antarmuka QtSql. Karena QTableWidget mewarisi dari QTableView, saya tidak dapat membayangkan bahwa Anda perlu banyak mengubah kode Anda kecuali menghapus banyak baris yang tidak perlu.   -  person ImportanceOfBeingErnest    schedule 01.10.2016


Jawaban (1)


Anda dapat melakukan beberapa hal berbeda.

Untuk mencegah pengeditan, Anda cukup menghapus tanda edit untuk item yang tidak ingin diedit oleh pengguna

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

Sepertinya Anda menyimpan data asli (yaitu self.all_data). Anda cukup membandingkan data di sel tabel yang dipilih dengan data asli dan hanya memperbarui bidang yang telah diubah.

Anda juga dapat terhubung ke sinyal itemChanged untuk widget tabel dan menyimpan menjalankan daftar semua indeks yang telah berubah sejak penyegaran terakhir

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

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

Alternatifnya, bergantung pada seberapa banyak kontrol yang Anda inginkan, Anda juga dapat membuat QItemDelegate untuk melakukan semua ini.

person Brendan Abel    schedule 28.09.2016
comment
Ketika saya mencoba saran pertama, saya mendapatkan kesalahan: AttributeError: objek 'QTableWidgetItem' tidak memiliki atribut 'setItemFlags'. Saya meletakkannya di bagian bawah fungsi 'click_btn_mailouts()' - person Paul Jackways; 29.09.2016
comment
Saya menghapus 'item' dari 'setItemFlags' dan berhasil, terima kasih. - person Paul Jackways; 29.09.2016
comment
Apa item dalam fungsi yang Anda berikan? Jika itu QTableWidgetItem, saya mungkin memerlukan penjelasan tentang apa itu, karena saya tidak begitu tahu cara kerja item tersebut. - person Paul Jackways; 29.09.2016
comment
Jadi saya sekarang memiliki daftar catatan yang telah diedit, tetapi catatan tersebut adalah catatan yang belum diedit. Apakah ada cara agar saya bisa mendapatkan catatan yang telah diedit? - person Paul Jackways; 29.09.2016
comment
@PaulJackways Saya tidak yakin apa yang Anda maksud. Data yang diedit harus terdapat di setiap teks QTableWidgetItem. - person Brendan Abel; 29.09.2016
comment
Saya memiliki kode: 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) dan mencetak apa yang dimiliki catatan sebelum diedit. - person Paul Jackways; 02.10.2016