简体   繁体   English

如何使用QTableWidget进行PageUp / PageDown表?

[英]How to PageUp/PageDown table with QTableWidget?

I am using QTableWidget i have set 100 rows and 2 columns, now i need to table scrolling with pageup and pagedown buttons. 我正在使用QTableWidget我设置了100行和2列,现在我需要使用pageup和pagedown按钮进行表格滚动。

i'm trying to browse the table with PageUp/PageDown buttons, but the buttons go to the home or go to end the table. 我正在尝试使用PageUp / PageDown按钮浏览表,但是这些按钮将返回主页或结束表。 I wonder if there is a way to scroll the list partially? 我想知道是否有一种方法可以部分滚动列表?

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())

I expect browsing all table items using PageUp/PageDown buttons. 我希望使用PageUp / PageDown按钮浏览所有表项。

While the answer provided by @eyllanesc works fine, I'd like to suggest another approach. 虽然@eyllanesc提供的答案很好用,但我想提出另一种方法。
Even when the scroll bars are hidden, they still exist and are constantly updated according to the item view contents and position, making it possible to use them to scroll, since their valueChanged signal is still connected to the item view itself. 即使滚动条被隐藏,它们仍然存在,并且会根据项目视图的内容和位置不断更新,从而使它们可以滚动,因为它们的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())

As long as you are using ScrollPerItem mode for verticalScrollMode , you can even scroll by a specific amount of items also. 只要您将ScrollPerItem模式用于verticalScrollMode ,您甚至还可以滚动特定数量的项目。
For example, if you want to scroll down by 10 items each time: 例如,如果您想每次向下滚动10个项目:

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

The problem comes if you're using ScrollPerPixel, as items can have different sizes; 如果您使用的是ScrollPerPixel,则会出现问题,因为项目可以具有不同的大小。 so, if you want to use the page keys to scroll by items you'll need to find your own method (as there's no "perfect" one) to scroll according to the currently shown items and their sizes. 因此,如果您想使用页面键来滚动项,则需要找到自己的方法(因为没有“完美”的方法)来根据当前显示的项及其大小进行滚动。 If that's the case, you should implement it using the code provided by eyllanesc, while checking for item positioning (and ensuring if the possibly shown items are near to the end). 如果是这样,您应该使用eyllanesc提供的代码来实现它,同时检查项目的位置(并确保可能显示的项目是否接近尾声)。

You could use the scrollToItem() method but there is a drawback: Not every grid has a QTableWidgetItem associated because you could not move to those grids. 您可以使用scrollToItem()方法,但是有一个缺点:并非每个网格都有关联的QTableWidgetItem因为您无法移动到那些网格。 Instead it is better to use the scrollTo() method that QModelIndex uses, and in that case every grid has a QModelIndex associated. 相反,最好使用QModelIndex使用的scrollTo()方法,在这种情况下,每个网格都有一个关联的QModelIndex。

On the other hand, obtaining the QModelIndex is pure geometry, for this the rect of the viewport() and the indexAt() method are used, then the row and column of the grid are obtained, in the end it is obtained to the next or previous QModelIndex using the model. 另一方面,获得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)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM