ฉันจะรับข้อมูลที่ผู้ใช้เปลี่ยนแปลงในตารางใน PyQT ด้วย Python และ SQLite3 ได้อย่างไร

ฉันมีตารางที่ปรากฏบน GUI ของฉัน ผู้ใช้สามารถแก้ไขตารางนี้ได้จาก GUI ฉันจะรับข้อมูลทั้งหมดที่ได้รับการแก้ไขและอัพเดตในฐานข้อมูลได้อย่างไร? ผู้ใช้ทำเครื่องหมายในช่องสำหรับแต่ละแถวที่ต้องการอัปเดตเป็นฐานข้อมูล ดังนั้นฉันจึงมีรายการแถวทั้งหมดที่ต้องอัปเดต ฉันต้องการรายการสิ่งอันดับ โดยที่แต่ละสิ่งอันดับคือแถวของค่าใหม่ที่ต้องอัปเดต โดยที่ฟิลด์ 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 ใน GUI โดยให้รายการดัชนีที่มีการเปลี่ยนแปลง และวิธีใดวิธีหนึ่งให้อัปเดตการเปลี่ยนแปลงเหล่านั้นลงในฐานข้อมูล นอกจากนี้ การทราบวิธีหยุดผู้ใช้ไม่ให้แก้ไขบางฟิลด์จะเป็นประโยชน์เช่นกัน เนื่องจากจะทำให้ฐานข้อมูลเสียหาย


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