RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 1605845
Accepted
Олег Паламарчук
Олег Паламарчук
Asked:2025-01-29 21:22:01 +0000 UTC2025-01-29 21:22:01 +0000 UTC 2025-01-29 21:22:01 +0000 UTC

QTableView PyQt5 中的总行数

  • 772

我QTableView以表格的形式添加了总行数self.inner_table,它们位于主表的正下方。如果行数太多导致该表无法在屏幕上显示,则向下滚动时会出现“总计”行。但是,问题是,当您向上滚动时,“总计”行不会消失,就像表格本身中的任何其他行一样。为了更好地理解,请应用代码。

我还需要将小部件集中在 CustomTableView 内部,而无需将 main_window 参数传递给它。

请修复代码,以便 CustomTableView 在创建“Total”行方面能够自给自足:这样它就不需要将 main_window 传递给它,也不需要 ContentWidget 类

我附上了代码:

    import sys
from PyQt5.QtWidgets import QTableView, QMainWindow, \
    QApplication, QAbstractItemView, QVBoxLayout, QWidget, \
    QHeaderView, QScrollArea, QHBoxLayout
from PyQt5.QtGui import QStandardItem, QStandardItemModel 
from PyQt5.QtCore import Qt, QSize


class ContentWidget(QWidget):
    def sizeHint(self):  # <--- sizeHint
        return QSize(1500, 1000)


class CustomTableView(QTableView):
    def __init__(self, main_window):
        super().__init__()
        self.setModel(QStandardItemModel(55, 10))
        self.horizontalHeader().setVisible(False)
        self.verticalHeader().setVisible(False)
        self.setVerticalScrollBarPolicy(
            Qt.ScrollBarPolicy.ScrollBarAlwaysOff) 
        self.horizontalHeader().setSectionResizeMode(
            QHeaderView.ResizeMode.Stretch)  
        self.setSelectionMode(
            QAbstractItemView.SelectionMode.SingleSelection)

        self.scrollArea = QScrollArea()
        self.content_widget = ContentWidget()
        self.scrollArea.setWidget(self.content_widget)

        self.add_total_row()
        self.setup_layout()

        main_window.setCentralWidget(self.scrollArea)

    def add_total_row(self):
        self.inner_model = QStandardItemModel(2, 10)
        self.inner_table = QTableView(self)
        self.inner_table.setMaximumHeight(82)
        self.inner_table.setModel(self.inner_model)
        self.inner_table.horizontalHeader().setVisible(False)
        self.inner_table.verticalHeader().setVisible(False)
        self.inner_table.setVerticalScrollBarPolicy(
            Qt.ScrollBarPolicy.ScrollBarAlwaysOff) 
        self.inner_table.horizontalHeader().setSectionResizeMode(
            QHeaderView.ResizeMode.Stretch)  
        self.inner_table.setEditTriggers(
            QAbstractItemView.EditTrigger.NoEditTriggers)
        self.inner_table.setSelectionMode(
            QAbstractItemView.SelectionMode.NoSelection)

    def setup_layout(self):
        self.layout = QVBoxLayout(self.content_widget)
        self.layout.setSpacing(0)
        self.layout.addWidget(self)
        self.layout.addWidget(
            self.inner_table)


class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.table = CustomTableView(self)  # Pass the MainWindow instance as parent
        self.resize(1100, 600)


if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = MainWindow()
    window.show()
    sys.exit(app.exec())
python
  • 2 2 个回答
  • 61 Views

2 个回答

  • Voted
  1. S. Nick
    2025-01-30T00:44:29Z2025-01-30T00:44:29Z

    尝试一下:

    import sys
    from PyQt5.QtWidgets import  QTableView, QMainWindow, \
        QApplication, QAbstractItemView, QVBoxLayout, QWidget, \
        QHeaderView
    from PyQt5.QtGui import QStandardItem, QStandardItemModel 
    from PyQt5.QtCore import Qt
    
    
    class CustomTableView(QTableView):
        def __init__(self, parent= None):
            super().__init__(parent)
            
            self.table_row_count = 55
            
            self.outer_model = QStandardItemModel(
                self.table_row_count, 10)
            self.setModel(self.outer_model)
            self.horizontalHeader().setVisible(False)
            self.verticalHeader().setVisible(False)
            self.setSelectionMode(
                QAbstractItemView.SelectionMode.SingleSelection)
    #        self.add_total_row()
    
        def add_total_row(self):
            self.inner_model = QStandardItemModel(2, 10)
            self.inner_table = QTableView(self)
            self.inner_table.setObjectName('inner_table')            # +
            self.inner_table.setMaximumHeight(82)                    # +
            self.inner_table.setMinimumHeight(82)                    # +
            
            self.inner_table.setModel(self.inner_model)
            self.inner_table.horizontalHeader().setVisible(False)    # +
            self.inner_table.verticalHeader().setVisible(False)      # +
            self.inner_table.setEditTriggers(
                QAbstractItemView.EditTrigger.NoEditTriggers)
            self.inner_table.setSelectionMode(
                QAbstractItemView.SelectionMode.NoSelection)
    
        def resizeEvent(self, event):
            super().resizeEvent(event)
            pass
            '''
            self.inner_table.setGeometry(
                0, self.rowHeight(0)*self.table_row_count,
                self.viewport().width(), self.rowHeight(0)*2+5)
            '''
    
    # +++ vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
    class MainWindow(QMainWindow):
        def __init__(self):
            super().__init__()
    
            self.central_widget = QWidget()                          # +++
            self.setCentralWidget(self.central_widget)
    
            self.table = CustomTableView()
            self.table.setAlternatingRowColors(True)
            self.table.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff) 
            self.table.horizontalHeader().setSectionResizeMode(
                QHeaderView.Stretch)         
            self.table.add_total_row()
            self.table.inner_table.horizontalHeader().setSectionResizeMode(
                QHeaderView.Stretch)
            
            self.layout = QVBoxLayout(self.central_widget)           # +++  
            self.layout.setSpacing(0)        
            self.layout.addWidget(self.table, stretch=9) 
            self.layout.addWidget(self.table.inner_table, 
                stretch=0, alignment=Qt.AlignBottom)
            self.layout.addStretch(1) 
    
            for i in range(self.table.outer_model.rowCount()): 
                it = QStandardItem(f"{i}")
                self.table.outer_model.setItem(i, 0, it)
    
    Stylesheet = '''
    /* тут вы можете установить свои стили для виджетов */
    #inner_table { 
        border: 2px solid #f9009B;
        background-color: #8EDE81;
        selection-background-color: #999;
    }
    '''
            
    
    if __name__ == '__main__':
        app = QApplication(sys.argv)
        app.setStyleSheet(Stylesheet)
        app.setStyleSheet
        window = MainWindow()
        window.resize(1100, 600)
        window.show()
        sys.exit(app.exec())
    # +++ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    

    在此处输入图片描述

    在此处输入图片描述



    更新:

    尝试一下:

    import sys
    from PyQt5.QtWidgets import  QTableView, QMainWindow, \
        QApplication, QAbstractItemView, QVBoxLayout, QWidget, \
        QHeaderView, QScrollArea, QHBoxLayout
    from PyQt5.QtGui import QStandardItem, QStandardItemModel 
    from PyQt5.QtCore import Qt, QSize
    
    
    class ContentWidget(QWidget):
            
        def sizeHint(self):                                 # <--- sizeHint
            return QSize(1500, 1000)
        
    
    class CustomTableView(QTableView):
        def __init__(self, parent= None):
            super().__init__(parent)
            
            self.table_row_count = 55
            
            self.outer_model = QStandardItemModel(
                self.table_row_count, 10)
            self.setModel(self.outer_model)
            self.horizontalHeader().setVisible(False)
            self.verticalHeader().setVisible(False)
            self.setSelectionMode(
                QAbstractItemView.SelectionMode.SingleSelection)
    
        def add_total_row(self):
            self.inner_model = QStandardItemModel(2, 10)
            self.inner_table = QTableView(self)
            self.inner_table.setObjectName('inner_table')  
            self.inner_table.setMaximumHeight(82)         
            self.inner_table.setMinimumHeight(82)         
            
            self.inner_table.setModel(self.inner_model)
            self.inner_table.horizontalHeader().setVisible(False)
            self.inner_table.verticalHeader().setVisible(False)  
            self.inner_table.setEditTriggers(
                QAbstractItemView.EditTrigger.NoEditTriggers)
            self.inner_table.setSelectionMode(
                QAbstractItemView.SelectionMode.NoSelection)
    
        def resizeEvent(self, event):
            super().resizeEvent(event)
            pass
            '''
            self.inner_table.setGeometry(
                0, self.rowHeight(0)*self.table_row_count,
                self.viewport().width(), self.rowHeight(0)*2+5)
            '''
    
    
    class MainWindow(QMainWindow):
        def __init__(self):
            super().__init__()
      
            self.scrollArea = QScrollArea()                         # +++
            self.setCentralWidget(self.scrollArea)
            
            self.content_widget = ContentWidget()                   # +++
            self.scrollArea.setWidget(self.content_widget)
            
            self.table = CustomTableView()
            self.table.setAlternatingRowColors(True)
            self.table.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff) 
            self.table.horizontalHeader().setSectionResizeMode(
                QHeaderView.Stretch)         
            self.table.add_total_row()
            self.table.inner_table.horizontalHeader().setSectionResizeMode(
                QHeaderView.Stretch)
            
            self.layout = QVBoxLayout(self.content_widget)   
     
            self.layout.setSpacing(0)        
            self.layout.addWidget(self.table, stretch=9) 
            self.layout.addWidget(self.table.inner_table, 
                stretch=0, alignment=Qt.AlignBottom)
            self.layout.addStretch(1) 
    
            for i in range(self.table.outer_model.rowCount()): 
                it = QStandardItem(f"{i}")
                self.table.outer_model.setItem(i, 0, it)
    
    
    Stylesheet = '''
    /* тут вы можете установить свои стили для виджетов */
    #inner_table { 
        border: 2px solid #f9009B;
        background-color: #8EDE81;
        selection-background-color: #999;
    }
    '''
            
    
    if __name__ == '__main__':
        app = QApplication(sys.argv)
        app.setStyleSheet(Stylesheet)
        window = MainWindow()
        window.resize(1100, 600)
        window.show()
        sys.exit(app.exec())
    

    在此处输入图片描述

    在此处输入图片描述

    • 1
  2. Best Answer
    needKVAS
    2025-01-31T18:25:17Z2025-01-31T18:25:17Z

    在我看来,将两个小部件放置在一起并不是解决问题的最佳方法。如果我是你,我会使用一个代理模型,负责在原始模型中添加额外的行。

    下面是一个实现示例:

    import sys
    from PyQt5.QtWidgets import  QTableView, QMainWindow, QApplication, QAbstractItemView
    from PyQt5.QtGui import QStandardItem, QStandardItemModel
    from PyQt5.QtCore import Qt, QSize, QIdentityProxyModel, QModelIndex, QVariant
    
    
    class TotalRowProxyModel(QIdentityProxyModel):
        def __init__(self, parent = None):
            super().__init__(parent)
        
        def isTotalRow(self, row, column, parent):
            return (not parent.isValid() and row == super().rowCount(parent) and column < self.columnCount())
        
        def rowCount(self, index):
            if not index.isValid():
                return super().rowCount(index) + 1
            return super().rowCount(index)
            
        def index(self, row, column, parent):
            if self.isTotalRow(row, column, parent):
                return self.createIndex(row, column, self)
            return super().index(row, column, parent)
            
        def parent(self, child):
            if child.internalPointer() is self:
                return QModelIndex();
            return super().parent(child)
        
        def sibling(self, row, column, idx):
            if self.isTotalRow(row, column, self.parent(idx)):
                return self.createIndex(row, column, self)
            return super().sibling(row, column, idx)
            
        def mapToSource(self, proxyIndex):
            if proxyIndex.internalPointer() is self:
                return QModelIndex();
            return super().mapToSource(proxyIndex)
            
        def flags(self, index):
            if index.internalPointer() is self:
                return Qt.ItemIsSelectable | Qt.ItemIsEnabled | Qt.ItemNeverHasChildren
            return super().flags(index)
        
        #Здесь вы подсовываете свои значения итого
        def data(self, proxyIndex, role):
            if proxyIndex.internalPointer() is self:
                if role == Qt.DisplayRole:
                    if proxyIndex.column() == 2:
                        return QVariant("Итого: 2")
                    return QVariant("Пустое итого")
                return QVariant()
            return super().data(proxyIndex, role)
    
    class CustomTableView(QTableView):
        def __init__(self, parent= None):
            super().__init__(parent)
            self.table_row_count = 40
            self.outer_model = QStandardItemModel(
                self.table_row_count, 10)
            self.proxy_model = TotalRowProxyModel()
            self.proxy_model.setSourceModel(self.outer_model)
            self.setModel(self.proxy_model)
            self.horizontalHeader().setVisible(False)
            self.verticalHeader().setVisible(False)
            self.setSelectionMode(
                QAbstractItemView.SelectionMode.SingleSelection)
    
    
    class MainWindow(QMainWindow):
        def __init__(self):
            super().__init__()
            self.table = CustomTableView()
            self.setGeometry(0, 0, 1550, 1000)
            self.setCentralWidget(self.table)
    
    
    if __name__ == '__main__':
        app = QApplication(sys.argv)
        window = MainWindow()
        window.show()
        sys.exit(app.exec_())
    
    

    这里没有添加数据的实现,但我认为您可以自己做。如果不需要突出显示总行,您可以清除相应的标志。

    • 0

相关问题

  • 是否可以以某种方式自定义 QTabWidget?

  • telebot.anihelper.ApiException 错误

  • Python。检查一个数字是否是 3 的幂。输出 无

  • 解析多个响应

  • 交换两个数组的元素,以便它们的新内容也反转

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    我看不懂措辞

    • 1 个回答
  • Marko Smith

    请求的模块“del”不提供名为“default”的导出

    • 3 个回答
  • Marko Smith

    "!+tab" 在 HTML 的 vs 代码中不起作用

    • 5 个回答
  • Marko Smith

    我正在尝试解决“猜词”的问题。Python

    • 2 个回答
  • Marko Smith

    可以使用哪些命令将当前指针移动到指定的提交而不更改工作目录中的文件?

    • 1 个回答
  • Marko Smith

    Python解析野莓

    • 1 个回答
  • Marko Smith

    问题:“警告:检查最新版本的 pip 时出错。”

    • 2 个回答
  • Marko Smith

    帮助编写一个用值填充变量的循环。解决这个问题

    • 2 个回答
  • Marko Smith

    尽管依赖数组为空,但在渲染上调用了 2 次 useEffect

    • 2 个回答
  • Marko Smith

    数据不通过 Telegram.WebApp.sendData 发送

    • 1 个回答
  • Martin Hope
    Alexandr_TT 2020年新年大赛! 2020-12-20 18:20:21 +0000 UTC
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5