Python 如何使用Span格式从QtableWidget打印数据?

Python 如何使用Span格式从QtableWidget打印数据?,python,sqlite,pyqt,pyqt5,qtablewidget,Python,Sqlite,Pyqt,Pyqt5,Qtablewidget,我正在尝试从QTableWidget打印数据,它将span应用于少数列。Span合并行以处理一对多关系 问题:打印时忽略Span格式设置 class TableViewPage(QtWidgets.QMainWindow, Ui_table_MainWindow): def __init__(self, parent=None): super(TableViewPage, self).__init__(parent) self.setupUi(self)

我正在尝试从QTableWidget打印数据,它将span应用于少数列。Span合并行以处理一对多关系

问题:打印时忽略Span格式设置

class TableViewPage(QtWidgets.QMainWindow, Ui_table_MainWindow):
    def __init__(self, parent=None):
        super(TableViewPage, self).__init__(parent)
        self.setupUi(self)
        self.btn_load.clicked.connect(self.loadTable)
        self.btn_preview.clicked.connect(self.handlePreview)
        self.btn_print.clicked.connect(self.handlePrint)

        for row in range(self.tableWidget.rowCount()):
            for col in range(self.tableWidget.columnCount()):
                item = QtWidgets.QTableWidgetItem()
                item.setTextAlignment(QtCore.Qt.AlignCenter)
                self.tableWidget.setItem(row, col, item)
        self.tableWidget.setHorizontalHeaderLabels(
            'Party|Date|Product|Qty|Rate|Amt|Loading|Freight|Net|CD|Comm'.split('|'))

    def loadTable(self):
        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)

    def handlePrint(self):
        dialog = QtPrintSupport.QPrintDialog()
        if dialog.exec_() == QtWidgets.QDialog.Accepted:
            self.handlePaintRequest(dialog.printer())

    def handlePreview(self):
        dialog = QtPrintSupport.QPrintPreviewDialog()
        dialog.paintRequested.connect(self.handlePaintRequest)
        dialog.exec_()

    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)
使用apply_span函数,我可以将表格显示为“预期输出”,但在打印数据时,数据以“代码输出”格式打印


更新:打印列名时也会被忽略。

首先,您必须检测跨度并添加它,但您可能会遇到问题,因为有些项目不可见,但它们存在,因此一项任务是消除它们。为此,请添加更多代码以应用_span()。另一方面,必须为标题添加新行

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)
        # remove hidden items
        for r in range(row+1, row+nrow):
            t = self.tableWidget.takeItem(r, c)
            del t

@QtCore.pyqtSlot(QtPrintSupport.QPrinter)
def handlePaintRequest(self, printer):
    document = QtGui.QTextDocument()
    cursor = QtGui.QTextCursor(document)
    table = cursor.insertTable(self.tableWidget.rowCount()+1, self.tableWidget.columnCount())

    for c in range(table.columns()):
        it = self.tableWidget.horizontalHeaderItem(c)
        cursor.insertText(str(c) if it is None else it.text())
        cursor.movePosition(QtGui.QTextCursor.NextCell)

    for row in range(1, table.rows()):
        for col in range(table.columns()):
            it = self.tableWidget.item(row-1, col)
            cursor.insertText("" if it is None else it.text())
            cursor.movePosition(QtGui.QTextCursor.NextCell)

    for row in range(1, table.rows()):
        for col in range(table.columns()):
            table.mergeCells(row, col, self.tableWidget.rowSpan(row-1, col), 1)
    document.print_(printer)
def apply_span(自身、行、行):

如果nrow没有神奇的解决方案可以猜出您想要的输出格式。如果您想以不同的格式设置跨距,您必须自己编写所有必要的代码(即检查and/or,然后根据需要更改格式)。@ekhumoro我知道我必须自己编写代码,但这需要一些时间来学习,而且我对PYQt是新手。此外,这里的问题是,“预期输出”格式已经在QTableWidget中实现,但在打印时格式丢失。那么,在打印之前是否需要再次格式化?您是否确实需要将表打印为
QTextDocument
?如果您只想直接打印表格,请查看的答案。其中显示了打印小部件的不同方式。所有小部件都有一个方法,允许您在小部件出现在屏幕上时打印它的图像。
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)
        # remove hidden items
        for r in range(row+1, row+nrow):
            t = self.tableWidget.takeItem(r, c)
            del t

@QtCore.pyqtSlot(QtPrintSupport.QPrinter)
def handlePaintRequest(self, printer):
    document = QtGui.QTextDocument()
    cursor = QtGui.QTextCursor(document)
    table = cursor.insertTable(self.tableWidget.rowCount()+1, self.tableWidget.columnCount())

    for c in range(table.columns()):
        it = self.tableWidget.horizontalHeaderItem(c)
        cursor.insertText(str(c) if it is None else it.text())
        cursor.movePosition(QtGui.QTextCursor.NextCell)

    for row in range(1, table.rows()):
        for col in range(table.columns()):
            it = self.tableWidget.item(row-1, col)
            cursor.insertText("" if it is None else it.text())
            cursor.movePosition(QtGui.QTextCursor.NextCell)

    for row in range(1, table.rows()):
        for col in range(table.columns()):
            table.mergeCells(row, col, self.tableWidget.rowSpan(row-1, col), 1)
    document.print_(printer)