使用 Python 在 QTableWidget 中设置列跨度 (setSpan) 的问题

问题描述 投票:0回答:1

我在包含文本的 HeaderCol 对象(下方)中有我的标题信息,文本要出现的实际行(它是前两行之一)开始列和跨度(列数)

我有以下代码:

import sys
from PyQt5.QtWidgets import QTableWidget, QTableWidgetItem, QApplication, QDialog, QVBoxLayout, QHBoxLayout


class TenantEvent:

TENANT_EVENTS = []

def __init__(self, text):
    self.text = text
    TenantEvent.TENANT_EVENTS.append(self.text)


class HeaderCol:
    MAX_COL = 0
    HEADERS = [[]]

    def __init__(self, text, row, col, span=1, header_row=0):
        if row == 0:
            HeaderCol.MAX_COL += col
        self.text = text
        self.row = row
        self.col = col
        self.span = span

        if len(HeaderCol.HEADERS) <= header_row:
            HeaderCol.HEADERS.append([])

        HeaderCol.HEADERS[header_row].append(self)


class TransactionsTable(QTableWidget):
    HEADER_TOP_ROW = 0
    HEADER_SECOND_ROW = 1

    col = 0
    row = HEADER_TOP_ROW
    ENTRY_COL = HeaderCol('Entry', row, col, 2)
    col += ENTRY_COL.span
    DUE_COL = HeaderCol('Due', row, col, 4)
    col += DUE_COL.span
    PAID_COL = HeaderCol('Paid', row, col, 7)
    col += PAID_COL.span
    MANAGEMENT_COL = HeaderCol('Management', row, col, 2)
    col += MANAGEMENT_COL.span

    col = 0
    row = HEADER_SECOND_ROW

    DATE_COL = HeaderCol('Date', row, col, 1, 1)
    col += DATE_COL.span
    EVENT_COL = HeaderCol('Event', row, col, 1, 1)
    col += EVENT_COL.span
    FEES_AND_CHARGES_COL = HeaderCol('Fees & Charges', row, col, 1, 1)
    col += FEES_AND_CHARGES_COL.span
    RENT_COL = HeaderCol('Rent', row, col, 1, 1)
    col += RENT_COL.span
    TAX_DUE_COL = HeaderCol('Tax', row, col, 1, 1)
    col += TAX_DUE_COL.span
    TOTAL_DUE_COL = HeaderCol('Total Due', row, col, 1, 1)
    col += TOTAL_DUE_COL.span
    PAID_COL = HeaderCol('Paid', row, col, 1, 1)
    col += PAID_COL.span
    PAYMENT_METHOD_COL = HeaderCol('Payment Method', row, col, 1, 1)
    col += PAYMENT_METHOD_COL.span
    CHECK_NUMBER_COL = HeaderCol('Check Number', row, col, 1, 1)
    col += CHECK_NUMBER_COL.span
    DATE_BANKED_COL = HeaderCol('Date Banked', row, col, 1, 1)
    col += DATE_BANKED_COL.span
    RENT_COL = HeaderCol('Rent', row, col, 1, 1)
    col += RENT_COL.span
    TAX_PAID_COL = HeaderCol('Tax', row, col, 1, 1)
    col += TAX_PAID_COL.span
    TOTAL_PAID_COL = HeaderCol('Total Paid', row, col, 1, 1)
    col += TOTAL_PAID_COL.span
    TENANT_STATUS_COL = HeaderCol('Tenant Status', row, col, 1, 1)
    col += TENANT_STATUS_COL.span
    EXPENSE_COL = HeaderCol('Expense', row, col)
    col += EXPENSE_COL.span
    MANAGEMENT_FEE_COL = HeaderCol('Management Fee', row, col)
    HeaderCol.MAX_COL = col + MANAGEMENT_FEE_COL.span
    NET_COL = HeaderCol('Net', row, col)
    col += NET_COL.span
    NOTES_COL = HeaderCol('Notes', row, col)
    col += NOTES_COL.span

    FEE_DUE_EVENT = TenantEvent('Fee Due')
    MANAGEMENT_EXPENSE_EVENT = TenantEvent('Management Expense')
    RENT_DUE_EVENT = TenantEvent('Rent Due')
    LATE_FEE_EVENT = TenantEvent('Late Fee')
    RENT_PAID_EVENT = TenantEvent('Rent Paid')
    FEE_PAID_EVENT = TenantEvent('Fee Paid')
    BOUNCED_RENT_CHECK_EVENT = TenantEvent('Bounced Rent Check')
    BOUNCED_CHECK_FEE_EVENT = TenantEvent('Bounced Check Fee Due')
    REPAIRS_AND_MAINTENANCE_EVENT = TenantEvent('Repairs & Maintenance')

def __init__(self, data, *args):
    QTableWidget.__init__(self, *args)
    self.verticalHeader().setVisible(False)
    self.horizontalHeader().setVisible(False)

    self.data = data
    # self.set_data()
    self.setRowCount(20)
    self.setColumnCount(HeaderCol.MAX_COL+30)
    self.resizeColumnsToContents()
    self.resizeRowsToContents()

def add_headers(self):
    print(f'{"text":>15}\trow\tcol\tr_s\tc_s')
    for header_row in range(2):
        for header in HeaderCol.HEADERS[header_row]:
            row = header_row
            col = header.col
            row_span = 1
            col_span = header.span
            print(f'{header.text:>15}\t{row}\t{col}\t{row_span}\t{col_span}')
            self.setSpan(row, col, row_span, col_span)
            new_item = QTableWidgetItem(header.text)
            self.setItem(header_row, header.col, new_item)

class TransactionsDialog(QDialog):
    def __init__(self, data, *args):
        super().__init__()
        top_layout = QVBoxLayout()
        layout = QHBoxLayout()
        self.table = TransactionsTable(data, *args)
        layout.addWidget(self.table)
        top_layout.addLayout(layout)
        self.setLayout(top_layout)
        self.resize(2400, 600)


def main():
    app = QApplication(sys.argv)
    data = {'col1': ['1', '2', '3', '4'],
            'col2': ['1', '2', '1', '3'],
            'col3': ['1', '1', '2', '1']}

    dialog = TransactionsDialog(data, 4, 3)
    dialog.show()
    dialog.exec()
    sys.exit(app.exec_())


if __name__ == '__main__':
    main()

打印输出是这样的(在我看来是正确的):

           text row col r_s c_s
          Entry 0   0   1   2
            Due 0   2   1   4
           Paid 0   6   1   7
     Management 0   13  1   2
        Expense 0   14  1   1
 Management Fee 0   15  1   1
            Net 0   15  1   1
          Notes 0   16  1   1
           Date 1   0   1   1
          Event 1   1   1   1
 Fees & Charges 1   2   1   1
           Rent 1   3   1   1
            Tax 1   4   1   1
      Total Due 1   5   1   1
           Paid 1   6   1   1
 Payment Method 1   7   1   1
   Check Number 1   8   1   1
    Date Banked 1   9   1   1
           Rent 1   10  1   1
            Tax 1   11  1   1
     Total Paid 1   12  1   1
  Tenant Status 1   13  1   1

问题是单元格布局不正确,没有得到正确的文本:

第一列和第一行是正确的(条目0 0 1 2) 第一行的前两个单元格跨越在一起。 问题是第一行的下一个条目 (Due 0 2 1 4) 合并了第一行的所有其余单元格,我假设因为第一行没有更多的单元格,其余的分布在桌子。我试过在第二次输入后停止,但占用第一行所有剩余单元格的问题仍然存在。

我刚刚尝试了以下代码:

def add_headers(self):
    row = 0
    col = 0
    row_span = 1
    col_span = 3
    self.setSpan(row, col, row_span, col_span)
    row = 0
    col = 4
    row_span = 1
    col_span = 3
    self.setSpan(row, col, row_span, col_span)

前两个单元格合并到第 1 行,但接下来的单元格保持正常。啊!

好吧,我把我的问题归结为:

---------------------------------------------------------------------------------
!       !               !                       !                               !
!       !               !                       !                               !
!       !               !                       !                               !
---------------------------------------------------------------------------------
!       !       !       !       !       !       !       !       !       !       !
! col=0 ! col=1 ! col=2 ! col=3 ! col=4 ! col=5 ! col=6 ! col=7 ! col=8 ! col=9 !
!       !       !       !       !       !       !       !       !       !       !
--------------------------------------------------------------------------------
!       !       !       !       !       !       !       !       !       !       !
-       !       !       !       !       !       !       !       !       !       !
-       !       !       !       !       !       !       !       !       !       !
---------------------------------------------------------------------------------

    row = 0
    col = 0
    row_span = 1
    col_span = 1
    self.setSpan(row, col, row_span, col_span)
    new_item = QTableWidgetItem(f"setSpan({row}, {col}, {row_span}, {col_span})")
    self.setItem(row, col, new_item)
    col = 1
    col_span = 2
    self.setSpan(row, col, row_span, col_span)
    new_item = QTableWidgetItem(f"setSpan({row}, {col}, {row_span}, {col_span})")
    self.setItem(row, col, new_item)
    col = 3
    col_span = 3
    self.setSpan(row, col, row_span, col_span)
    new_item = QTableWidgetItem(f"setSpan({row}, {col}, {row_span}, {col_span})")
    self.setItem(row, col, new_item)
    col = 6
    col_span = 4
    self.setSpan(row, col, row_span, col_span)
    new_item = QTableWidgetItem(f"setSpan({row}, {col}, {row_span}, {col_span})")
    self.setItem(row, col, new_item)
    return

这根本不起作用:

python qt qtablewidget
1个回答
0
投票

找到了! 在构造函数中,我发现我在设置标题后正在调整表格的大小。

© www.soinside.com 2019 - 2024. All rights reserved.