用 QTableView 对象覆盖方法 scrollTo
Overriding method scrollTo with a QTableView object
我正在尝试同步 tables (QTableView) 上的两个视图。目标是当我 select 在其中一个 table 中的一行时,另一个 table 滚动到同一行。使用的代码类似这样:
_index = _table.model.index(_row, _column)
_table.scrollTo(_index, QAbstractItemView.PositionAtCenter)
_table 对象是 Python class 继承 QtWidgets.QAbstractItemView 的实例,具有以下签名。
class NewTable(QtWidgets.QAbstractItemView):
def __init__(self, table_widget: QtWidgets.QTableView, table_data: pd.DataFrame, rm_parent = None):
self.rm_parent = rm_parent # Pointer to the main window.
super().__init__()
self.model = TableModel(tbl_data = table_data, rm_parent = rm_parent)
和表模型:
class TableModel(QtCore.QAbstractTableModel):
def __init__(self, rm_parent = None, tbl_data: pd.DataFrame = None) -> None:
super().__init__()
self.rm_parent = rm_parent # Pointer to the main window.
self.tblModelData = tbl_data
self.header_list: List = tbl_data.columns.values.tolist()
渲染到这里,我不知道如何重写 scrollTo 方法。方法returns 'None' 简单的在NewTable中改写class 没有效果
不需要重写scrollTo
方法,创建一个class负责同步QTableView就足够了:
from functools import partial
from PyQt5.QtGui import QStandardItemModel
from PyQt5.QtWidgets import (
QAbstractItemView,
QApplication,
QHBoxLayout,
QTableView,
QTableWidget,
QWidget,
)
class TableSynchronizer:
def __init__(self):
self._tables = []
def register_table(self, table):
self._tables.append(table)
table.selectionModel().selectionChanged.connect(
partial(self._handle_selection_changed, table)
)
def _handle_selection_changed(self, table, selected):
if not isinstance(table, QTableView):
return
ixs = selected.indexes()
if not ixs:
return
row = ixs[0].row()
for tb in self._tables:
if tb == table:
continue
model = tb.model()
if model is None or model.rowCount() == 0:
continue
r = min(row, model.rowCount() - 1)
ix = model.index(r, 0)
tb.scrollTo(ix, QAbstractItemView.PositionAtCenter)
def main():
app = QApplication([])
table1 = QTableWidget(10, 4)
table2 = QTableWidget(8, 5)
table3 = QTableView()
model3 = QStandardItemModel(12, 3)
table3.setModel(model3)
table_synchronizer = TableSynchronizer()
table_synchronizer.register_table(table1)
table_synchronizer.register_table(table2)
table_synchronizer.register_table(table3)
widget = QWidget()
lay = QHBoxLayout(widget)
lay.addWidget(table1)
lay.addWidget(table2)
lay.addWidget(table3)
widget.show()
app.exec_()
if __name__ == "__main__":
main()
我正在尝试同步 tables (QTableView) 上的两个视图。目标是当我 select 在其中一个 table 中的一行时,另一个 table 滚动到同一行。使用的代码类似这样:
_index = _table.model.index(_row, _column)
_table.scrollTo(_index, QAbstractItemView.PositionAtCenter)
_table 对象是 Python class 继承 QtWidgets.QAbstractItemView 的实例,具有以下签名。
class NewTable(QtWidgets.QAbstractItemView):
def __init__(self, table_widget: QtWidgets.QTableView, table_data: pd.DataFrame, rm_parent = None):
self.rm_parent = rm_parent # Pointer to the main window.
super().__init__()
self.model = TableModel(tbl_data = table_data, rm_parent = rm_parent)
和表模型:
class TableModel(QtCore.QAbstractTableModel):
def __init__(self, rm_parent = None, tbl_data: pd.DataFrame = None) -> None:
super().__init__()
self.rm_parent = rm_parent # Pointer to the main window.
self.tblModelData = tbl_data
self.header_list: List = tbl_data.columns.values.tolist()
渲染到这里,我不知道如何重写 scrollTo 方法。方法returns 'None' 简单的在NewTable中改写class 没有效果
不需要重写scrollTo
方法,创建一个class负责同步QTableView就足够了:
from functools import partial
from PyQt5.QtGui import QStandardItemModel
from PyQt5.QtWidgets import (
QAbstractItemView,
QApplication,
QHBoxLayout,
QTableView,
QTableWidget,
QWidget,
)
class TableSynchronizer:
def __init__(self):
self._tables = []
def register_table(self, table):
self._tables.append(table)
table.selectionModel().selectionChanged.connect(
partial(self._handle_selection_changed, table)
)
def _handle_selection_changed(self, table, selected):
if not isinstance(table, QTableView):
return
ixs = selected.indexes()
if not ixs:
return
row = ixs[0].row()
for tb in self._tables:
if tb == table:
continue
model = tb.model()
if model is None or model.rowCount() == 0:
continue
r = min(row, model.rowCount() - 1)
ix = model.index(r, 0)
tb.scrollTo(ix, QAbstractItemView.PositionAtCenter)
def main():
app = QApplication([])
table1 = QTableWidget(10, 4)
table2 = QTableWidget(8, 5)
table3 = QTableView()
model3 = QStandardItemModel(12, 3)
table3.setModel(model3)
table_synchronizer = TableSynchronizer()
table_synchronizer.register_table(table1)
table_synchronizer.register_table(table2)
table_synchronizer.register_table(table3)
widget = QWidget()
lay = QHBoxLayout(widget)
lay.addWidget(table1)
lay.addWidget(table2)
lay.addWidget(table3)
widget.show()
app.exec_()
if __name__ == "__main__":
main()