【问题标题】:How to display 2 SQLite tables with one to many relation into one QTableWidget如何在一个 QTableWidget 中显示 2 个具有一对多关系的 SQLite 表
【发布时间】:2019-04-01 14:37:29
【问题描述】:

我在 Db 中有以下两个表,具有一对多关系:

self.c.execute("CREATE TABLE IF NOT EXISTS dispatch("
                       "id_dispatch INTEGER PRIMARY KEY AUTOINCREMENT,"
                       "d_date TEXT,"
                       "d_mill TEXT,"
                       "d_buyer TEXT,"
                       "d_addFreight INTEGER,"
                       "d_subFreight INTEGER,"
                       "d_amount INTEGER,"
                       "d_cd INTEGER,"
                       "d_comm INTEGER,"
                       "d_netAmount INTEGER)")
        self.c.execute("CREATE TABLE IF NOT EXISTS dispatch_products("
                       "dispatch_id INTEGER NOT NULL REFERENCES DISPATCH(id_dispatch),"
                       "product INTEGER,"
                       "quantity INTEGER,"
                       "rate INTEGER)")

我正在尝试将这两个表格合二为一并显示在一个表格中,使用以下代码:

def loadTable(self):
    connection = sqlite3.connect('main_databaseSample.db')
    query = "CREATE VIEW myview as SELECT d_buyer," \
            "d_date, product, quantity, rate, d_amount, d_addFreight, d_subFreight, d_netAmount from " \
            "dispatch, dispatch_products WHERE dispatch.id_dispatch = dispatch_products.dispatch_id"
    query = "SELECT * FROM myview"
    result = connection.execute(query)
    self.tableWidget.setRowCount(0)
    for row_number, row_data in enumerate(result):
        self.tableWidget.insertRow(row_number)
        for column_number, data in enumerate(row_data):
            self.tableWidget.setItem(row_number, column_number,QtWidgets.QTableWidgetItem(str(data)))
    connection.close()

问题:重复有多个产品的订单。如何消除具有一对多关系的多个条目?

样本数据:

dispatch table:
ID date   mill buyer addF subF amount cd comm netAmount
1  15-10  abc  A     0    0    100    0  0    100
2  16-10  xyz  B     0    0    200    0  0    200

dispatch_products table:
Dispatch_ID product qty rate
1           M       40  1
1           A       60  1
2           S       50  4

Code Output:
buyer date  product quantity rate amount addFreight subFreight NetAmount
A     15-10 M       40       1    100    0          0          100
A     15-10 A       60       1    100    0          0          100
B     16-10 S       50       4    200    0          0          200

Expected Output:
buyer date  product quantity rate amount addFreight subFreight NetAmount
A     15-10 M       40       1    100    0          0          100
            A       60       1                           
B     16-10 S       50       4    200    0          0          200

【问题讨论】:

    标签: python sqlite pyqt pyqt5 qtablewidget


    【解决方案1】:

    任务是检测是否存在相等的元素,我们必须向 View 添加一个元素,即 dispatch_id 或 id_dispatch 并对其进行排序。检测到 dispatch_id 的变化后,使用setSpan() 加入必要的行,如下所示:

    from PyQt5 import QtCore, QtWidgets
    import sqlite3
    
    class Widget(QtWidgets.QWidget):
        def __init__(self, parent=None):
            super(Widget, self).__init__(parent)
            button = QtWidgets.QPushButton("Press me")
            button.clicked.connect(self.load_table)
            self.tableWidget = QtWidgets.QTableWidget()
    
            lay = QtWidgets.QVBoxLayout(self)
            lay.addWidget(button)
            lay.addWidget(self.tableWidget)
    
        @QtCore.pyqtSlot()
        def load_table(self):
            self.tableWidget.setRowCount(0)
            self.tableWidget.setColumnCount(9)
    
            connection = sqlite3.connect('main_databaseSample.db')
    
            connection.execute("DROP VIEW IF EXISTS myview;")
            query = "CREATE VIEW myview as SELECT dispatch_id, d_buyer," \
                "d_date, product, quantity, rate, d_amount, d_addFreight, d_subFreight, d_netAmount from " \
                "dispatch, dispatch_products WHERE dispatch.id_dispatch = dispatch_products.dispatch_id " \
                "ORDER BY dispatch_id ASC;"
            connection.execute(query)
            query = "SELECT * FROM myview"
            result = connection.execute(query)
            last_id = -1
            start_row = 0
            for row, row_data in enumerate(result):
                self.tableWidget.insertRow(row)
                current_id, *other_values = row_data 
                for col, data in enumerate(other_values):
                    it = QtWidgets.QTableWidgetItem(str(data))
                    self.tableWidget.setItem(row, col, it)
                if last_id != current_id and last_id != -1:
                    self.apply_span(start_row, row - start_row)
                    start_row = row
                last_id = current_id
            if start_row != row:
                self.apply_span(start_row, self.tableWidget.rowCount() - start_row)
    
        def apply_span(self, row, nrow):
            if nrow <= 1:
                return
            for c in (0, 1, 5, 6, 7, 8):
                self.tableWidget.setSpan(row, c, nrow, 1)
                for r in range(row+1, row+nrow):
                    t = self.tableWidget.takeItem(r, c)
                    del t
    
    if __name__ == '__main__':
        import sys
        app = QtWidgets.QApplication(sys.argv)
        w = Widget()
        w.show()
        sys.exit(app.exec_())
    

    添加更多数据我们可以看到以下结果

    【讨论】:

    • 您的解决方案有效,但是当我加载表格“QTableView::setSpan:不会添加单个单元格跨度”时,我收到以下警告。它显示了 12 次。
    • @user3170565 我修好了,我没有注意到警告。请尝试退回。
    • 谢谢!现在它可以工作了。但是当我试图打印这个表数据时,span 没有被应用。我错过了什么吗?
    • @user3170565 表格用什么代码打印?另一方面,这个要求对于我会邀请创建一个新问题来说是不可能的,最后如果我的回答对你有帮助,不要忘记将其标记为正确,如果你不知道该怎么做,请查看tour,这是最好的感谢方式。
    • 我正在尝试使用此打印代码def handlePaintRequest(self, printer): document = QtGui.QTextDocument() cursor = QtGui.QTextCursor(document) table = cursor.insertTable( self.tableWidget.rowCount(), self.tableWidget.columnCount()) for row in range(table.rows()): for col in range(table.columns()): cursor.insertText(self.tableWidget.item(row, col).text()) cursor.movePosition(QtGui.QTextCursor.NextCell) document.print_(printer)
    猜你喜欢
    • 2015-07-15
    • 1970-01-01
    • 2021-07-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-15
    相关资源
    最近更新 更多