如何使用 Span 格式从 QtableWidget 打印数据?
How to print data from QtableWidget with Span formatting?
我正在尝试从 QTableWidget 打印数据,它将跨度应用于几列。 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)
示例数据:
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
使用 apply_span 函数,我能够将 table 显示为 'Expected Output',但在打印数据时打印为 'Code Output' 格式。
更新:打印列名时也会被忽略。
首先你必须检测跨度并添加它,但你可能会遇到问题,因为有些项目不可见但它们存在,所以一个任务是为此消除它们,添加更多代码到 apply_span()。另一方面,必须为 header.
添加一个新行
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)
我正在尝试从 QTableWidget 打印数据,它将跨度应用于几列。 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)
示例数据:
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
使用 apply_span 函数,我能够将 table 显示为 'Expected Output',但在打印数据时打印为 'Code Output' 格式。
更新:打印列名时也会被忽略。
首先你必须检测跨度并添加它,但你可能会遇到问题,因为有些项目不可见但它们存在,所以一个任务是为此消除它们,添加更多代码到 apply_span()。另一方面,必须为 header.
添加一个新行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)