Advertisement
StSav012

Table Widget with Cells Resizable by Mouse

Feb 18th, 2025 (edited)
93
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 4.19 KB | Source Code | 0 0
  1. import sys
  2. from typing import cast
  3.  
  4. from PySide6.QtCore import QEvent, QObject, QPointF, Qt
  5. from PySide6.QtGui import QMouseEvent
  6. from PySide6.QtWidgets import QApplication, QTableWidget, QWidget
  7.  
  8.  
  9. class ResizableTableWidget(QTableWidget):
  10.     _grab_tol: float = 4.0
  11.  
  12.     def __init__(
  13.             self,
  14.             /,
  15.             parent: QWidget | None = None,
  16.             *,
  17.             rowCount: int | None = None,
  18.             columnCount: int | None = None,
  19.     ) -> None:
  20.         super().__init__(parent, rowCount=rowCount, columnCount=columnCount)
  21.  
  22.         self.horizontalHeader().hide()
  23.         self.verticalHeader().hide()
  24.  
  25.         self._col_to_resize: int | None = None
  26.         self._row_to_resize: int | None = None
  27.  
  28.         QApplication.instance().installEventFilter(self)
  29.  
  30.     def eventFilter(self, o: QObject, event: QEvent, /) -> bool:
  31.         if o is not self.viewport():
  32.             return False
  33.  
  34.         match event.type():
  35.             case QEvent.Type.MouseMove:
  36.                 pos: QPointF = cast(QMouseEvent, event).position()
  37.                 x: float = pos.x()
  38.                 y: float = pos.y()
  39.  
  40.                 col: bool = self.columnAt(round(x - ResizableTableWidget._grab_tol)) != self.columnAt(
  41.                     round(x + ResizableTableWidget._grab_tol)
  42.                 )
  43.                 row: bool = self.rowAt(round(y - ResizableTableWidget._grab_tol)) != self.rowAt(
  44.                     round(y + ResizableTableWidget._grab_tol)
  45.                 )
  46.                 if col and row:
  47.                     self.setCursor(Qt.CursorShape.SizeAllCursor)
  48.                 elif col:
  49.                     self.setCursor(Qt.CursorShape.SizeHorCursor)
  50.                 elif row:
  51.                     self.setCursor(Qt.CursorShape.SizeVerCursor)
  52.                 else:
  53.                     self.unsetCursor()
  54.  
  55.                 if cast(QMouseEvent, event).buttons() != Qt.MouseButton.LeftButton:
  56.                     return False
  57.  
  58.                 if self._col_to_resize is not None:
  59.                     if (
  60.                             abs(sum(self.columnWidth(i) for i in range(self._col_to_resize + 1)) - x)
  61.                             > ResizableTableWidget._grab_tol / 4
  62.                     ):
  63.                         self.setColumnWidth(
  64.                             self._col_to_resize,
  65.                             round(x - sum(self.columnWidth(i) for i in range(self._col_to_resize))),
  66.                         )
  67.                         self.updateGeometries()
  68.                 if self._row_to_resize is not None:
  69.                     if (
  70.                             abs(sum(self.rowHeight(i) for i in range(self._row_to_resize + 1)) - y)
  71.                             > ResizableTableWidget._grab_tol / 4
  72.                     ):
  73.                         self.setRowHeight(
  74.                             self._row_to_resize,
  75.                             round(y - sum(self.rowHeight(i) for i in range(self._row_to_resize))),
  76.                         )
  77.                         self.updateGeometries()
  78.  
  79.             case QEvent.Type.MouseButtonPress:
  80.                 if cast(QMouseEvent, event).buttons() != Qt.MouseButton.LeftButton:
  81.                     return False
  82.  
  83.                 pos: QPointF = cast(QMouseEvent, event).position()
  84.                 x: float = pos.x()
  85.                 y: float = pos.y()
  86.  
  87.                 if self.columnAt(round(x - ResizableTableWidget._grab_tol)) != self.columnAt(
  88.                         round(x + ResizableTableWidget._grab_tol)
  89.                 ):
  90.                     self._col_to_resize = self.columnAt(round(x - ResizableTableWidget._grab_tol))
  91.                 if self.rowAt(round(y - ResizableTableWidget._grab_tol)) != self.rowAt(
  92.                         round(y + ResizableTableWidget._grab_tol)
  93.                 ):
  94.                     self._row_to_resize = self.rowAt(round(y - ResizableTableWidget._grab_tol))
  95.  
  96.             case QEvent.Type.MouseButtonRelease:
  97.                 self._col_to_resize = None
  98.                 self._row_to_resize = None
  99.  
  100.         return False
  101.  
  102.  
  103. if __name__ == "__main__":
  104.     QApplication(sys.argv)
  105.     t: ResizableTableWidget = ResizableTableWidget(rowCount=4, columnCount=3)
  106.     t.show()
  107.     QApplication.exec()
  108.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement