【问题标题】:How to PageUp/PageDown table with QTableWidget?如何使用 QTableWidget PageUp/PageDown 表格?
【发布时间】:2019-12-07 21:51:19
【问题描述】:

我正在使用 QTableWidget 我已经设置了 100 行和 2 列,现在我需要使用 pageup 和 pagedown 按钮滚动表格。

我正在尝试使用 PageUp/PageDown 按钮浏览表格,但按钮会转到主页或结束表格。我想知道是否有办法部分滚动列表?

from PyQt5.QtWidgets import QVBoxLayout, QPushButton, QHBoxLayout, QApplication, QWidget, QTableWidget, QTableWidgetItem
import sys
from PyQt5.QtCore import Qt


class Window(QWidget):
    def __init__(self):
        super().__init__()

        self.title = "PyQt5 Tables"
        self.top = 100
        self.left = 100
        self.width = 500
        self.height = 400

        self.qtd_rows = 100

        self.table_widget = QTableWidget()

        self.init_window()

    def init_window(self):
        self.setWindowTitle(self.title)
        self.setGeometry(self.top, self.left, self.width, self.height)
        self.creating_tables()
        self.show()

    def creating_tables(self):
        self.table_widget = QTableWidget()
        self.table_widget.setAutoScroll(True)
        self.table_widget.setRowCount(self.qtd_rows)
        self.table_widget.setColumnCount(2)

        self.table_widget.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.table_widget.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)

        vbox = QVBoxLayout()

        for text, slot in (("PageUp", self.btn_page_up), ("PageDown", self.btn_page_down)):
            button = QPushButton(text)
            vbox.addWidget(button)
            button.clicked.connect(slot)

        for i in range(0, self.qtd_rows):
            self.table_widget.setItem(i, 0, QTableWidgetItem("Name_" + str(i)))
            self.table_widget.setItem(i, 1, QTableWidgetItem("Email"))

        vBoxLayout = QVBoxLayout()
        vBoxLayout.addWidget(self.table_widget)

        hBox = QHBoxLayout()
        hBox.addLayout(vBoxLayout)
        hBox.addLayout(vbox)

        self.setLayout(hBox)

    def btn_page_up(self):
        self.table_widget.scrollToTop()

    def btn_page_down(self):
        self.table_widget.scrollToBottom()


App = QApplication(sys.argv)
window = Window()
sys.exit(App.exec())

我希望使用 PageUp/PageDown 按钮浏览所有表格项。

【问题讨论】:

    标签: python python-3.x pyqt pyqt5 qtablewidget


    【解决方案1】:

    您可以使用scrollToItem() 方法,但有一个缺点:并非每个网格都有关联的QTableWidgetItem,因为您无法移动到这些网格。相反,最好使用 QModelIndex 使用的scrollTo() 方法,在这种情况下,每个网格都有一个关联的 QModelIndex。

    另一方面,获取QModelIndex是纯几何,为此使用viewport()的rect和indexAt()的方法,然后得到网格的行和列,最后得到使用模型到下一个或上一个 QModelIndex。

    def btn_up(self):
        ix = self.table_widget.indexAt(self.table_widget.viewport().rect().topLeft())
        previous_ix = self.table_widget.model().index(ix.row() - 1, ix.column())
        self.table_widget.scrollTo(previous_ix)
    
    def btn_down(self):
        ix = self.table_widget.indexAt(self.table_widget.viewport().rect().bottomLeft())
        next_ix = self.table_widget.model().index(ix.row() + 1, ix.column())
        self.table_widget.scrollTo(next_ix)
    

    【讨论】:

    • 感谢您的回答和解释。
    • @eyllanesc btn_down 有一个小问题:如果视图靠近表格底部并且最后一行已经可见,即使使用 QAbstractItemView.PositionAtBottom 也不会再滚动甚至是 EnsureVisible(至少在 Qt 5.7 上,我无法使用较新的版本进行测试)。我认为最好使用滚动条功能,即使它们不可见;我正在添加另一个答案,希望你不介意:-)
    【解决方案2】:

    虽然@eyllanesc 提供的answer 工作正常,但我想建议另一种方法。
    即使滚动条被隐藏,它们仍然存在并根据项目视图的内容和位置不断更新,从而可以使用它们进行滚动,因为它们的valueChanged 信号仍然连接到项目视图本身。

    def btn_page_up(self):
        scrollBar = self.table_widget.verticalScrollBar()
        scrollBar.setValue(scrollBar.value() - scrollBar.pageStep())
    
    def btn_page_down(self):
        scrollBar = self.table_widget.verticalScrollBar()
        scrollBar.setValue(scrollBar.value() + scrollBar.pageStep())
    

    只要您对verticalScrollMode 使用ScrollPerItem 模式,您甚至还可以滚动特定数量的项目。
    例如,如果您想每次向下滚动 10 个项目:

    def btn_scroll_down(self):
        scrollBar = self.table_widget.verticalScrollBar()
        scrollBar.setValue(scrollBar.value() + scrollBar.singleStep() * 10)
    

    如果您使用的是 ScrollPerPixel,就会出现问题,因为项目可以有不同的大小;因此,如果您想使用页面键滚动项目,您需要找到自己的方法(因为没有“完美”的方法)根据当前显示的项目及其大小进行滚动。如果是这种情况,您应该使用 eyllanesc 提供的代码来实现它,同时检查项目位置(并确保可能显示的项目接近尾声)。

    【讨论】:

    • 你是对的!我测试了两个答案,你的建议效果更好,QAbstractItemView.PositionAtBottom 滚动表格直到最后。 eyllanesc 的建议并不总是滚动到最后,但两个答案都很好。谢谢。
    猜你喜欢
    • 1970-01-01
    • 2010-12-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-14
    • 1970-01-01
    相关资源
    最近更新 更多