PyQt - 通过滚动条链接多个QTableView对象

时间:2017-03-17 14:41:18

标签: python pyqt

我在网上搜索过,但一直无法找到解决这个问题的方法。我有三个(虽然这可以是任何数字)QTableView对象,它们都比它们显示的大小(它们也是相等的长度)。对于所有3我有一个自动生成的滚动条。我想点击其中任何一个来移动其他QTableView对象相同的数量。

不幸的是我无法在网上找到解决方案。我得到的最接近的是这个(https://forum.qt.io/topic/25139/solved-synchronizing-two-qtableview-s-scrollbars/3)虽然这对我的情况没有帮助。

对此问题的任何帮助将不胜感激!谢谢!

2 个答案:

答案 0 :(得分:1)

这是一个包含三个QTableView小部件的MCVE,其垂直滚动条已链接。我们将move_other_scrollbars()自定义方法连接到每个滚动条的QAbstractSlider.valueChanged信号,使用lambdas传递相应的信息:滚动条的idx和移动到的scrollbar用户)。反过来,move_other_scrollbars()会找到所有其他滚动条并使用QAbstractSlider.setValue(idx)更新其位置。

from PyQt5.QtCore import (Qt, QStringListModel)
from PyQt5.QtWidgets import (QApplication, QWidget, QTableView, QHBoxLayout)


class MainWindow(QWidget):

    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
        self.table_view_1 = QTableView()
        self.table_view_2 = QTableView()
        self.table_view_3 = QTableView()
        items = ['apples', 'bananas', 'cookies', 'drinks', 'eggs', 'flour', 'gatorade']
        items_2 = ['alligator', 'bear', 'cat', 'deer', 'elephant', 'flamingo', 'goose']
        items_3 = ['Arsenic', 'Boron', 'Carbon', 'Dysprosium', 'Europium', 'Flourine', 'Gold']
        self.model = QStringListModel(items)
        self.model_2 = QStringListModel(items_2)
        self.model_3 = QStringListModel(items_3)

        self.table_view_1.setModel(self.model)
        self.table_view_2.setModel(self.model)
        self.table_view_3.setModel(self.model_3)
        self.layout = QHBoxLayout()

        self.list_of_tables = [self.table_view_1,self.table_view_2, self.table_view_3]

        def move_other_scrollbars(idx,bar):
            scrollbars = {tbl.verticalScrollBar() for tbl in self.list_of_tables}
            scrollbars.remove(bar)
            for bar in scrollbars:
                bar.setValue(idx)

        for tbl in self.list_of_tables:
            scrollbar = tbl.verticalScrollBar()
            scrollbar.valueChanged.connect(lambda idx,bar=scrollbar: move_other_scrollbars(idx, bar))
            self.layout.addWidget(tbl)

        self.setLayout(self.layout)

if __name__ == '__main__':
    import sys

    app = QApplication(sys.argv)
    window = MainWindow()
    window.show()
    sys.exit(app.exec_())

答案 1 :(得分:0)

QTableView有两个ScrollBarverticalScrollBarhorizontalScrollBar。 您可以使用verticalScrollBar ()horizontalScrollBar()获取此对象,滚动条对象具有valueChanged单个当滚动条更改位置时此信号将被发出。 这段代码是一个简单的解决方案。

from PyQt5.QtCore import QStringListModel
from PyQt5.QtWidgets import QApplication, QMainWindow , QTableView, QVBoxLayout,QWidget

class window(QMainWindow):
    def __init__(self):
        super().__init__()
        self.tab1 = QTableView(self)
        self.tab2 = QTableView(self)


        model1=QStringListModel([str(val) for val in range(0,100)])
        model2=QStringListModel([str(val) for val in range(100,200)])

        self.tab1.setModel(model1)
        self.tab2.setModel(model2)

        self.lyout = QVBoxLayout(self)

        self.lyout.addWidget(self.tab1)
        self.lyout.addWidget(self.tab2)


        wid = QWidget(self)
        self.setCentralWidget(wid)
        wid.setLayout(self.lyout)

        # connet the scroll bar signle to our slot
        self.tab1.verticalScrollBar().valueChanged.connect(self.__chnge_position)
        self.tab2.verticalScrollBar().valueChanged.connect(self.__chnge_position)

    def __chnge_position(self,index):
        #slot to change the scroll bar  position of all table
        self.tab1.verticalScrollBar().setValue(index)
        self.tab2.verticalScrollBar().setValue(index)

if __name__ == '__main__':
    import sys
    app = QApplication(sys.argv)
    win = window()
    win.show()
    sys.exit(app.exec_())