File: table.py
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_Dialog(object):
def setupUi(self, Dialog):
Dialog.resize(515, 285)
self.gridLayout = QtWidgets.QGridLayout(Dialog)
self.tableWidget = QtWidgets.QTableWidget(Dialog)
self.tableWidget.setColumnCount(4)
self.tableWidget.setRowCount(0)
item = QtWidgets.QTableWidgetItem()
item.setText("Column 1")
self.tableWidget.setHorizontalHeaderItem(0, item)
item = QtWidgets.QTableWidgetItem()
item.setText("Column 2")
self.tableWidget.setHorizontalHeaderItem(1, item)
item = QtWidgets.QTableWidgetItem()
item.setText("Column 3")
self.tableWidget.setHorizontalHeaderItem(2, item)
item = QtWidgets.QTableWidgetItem()
item.setText("Column 4")
self.tableWidget.setHorizontalHeaderItem(3, item)
self.tableWidget.horizontalHeader().setCascadingSectionResizes(False)
self.tableWidget.horizontalHeader().setStretchLastSection(False)
self.gridLayout.addWidget(self.tableWidget, 0, 0, 1, 1)
File: run_me.py
from PyQt5 import QtCore, QtGui, QtWidgets
import sys
from table import Ui_Dialog
class Run_me:
def __init__(self):
self.app = QtWidgets.QApplication(sys.argv)
self.Dialog = QtWidgets.QDialog()
self.ui = Ui_Dialog()
self.ui.setupUi(self.Dialog)
self.Dialog.show()
self.ui.tableWidget.resizeColumnsToContents()
self.find_table_column_min_width()
horizontal_header = self.ui.tableWidget.horizontalHeader()
self.ui.tableWidget.setHorizontalHeader(CustomHeader(self.ui.tableWidget,self.columns_min_width))
self.ui.tableWidget.updateGeometries()
sys.exit(self.app.exec_())
def find_table_column_min_width(self):
total_columns = self.ui.tableWidget.columnCount()
self.columns_min_width = []
for column_index in range(0,total_columns):
column_width = self.ui.tableWidget.columnWidth(column_index)
self.columns_min_width.append(column_width)
class CustomHeader(QtWidgets.QHeaderView):
def __init__(self,table,columns_min_width):
self.columns_min_width = columns_min_width
self.total_columns = len(self.columns_min_width)
self.header_labels = []
for column_index in range(0,self.total_columns):
column_text = table.horizontalHeaderItem(column_index).text()
self.header_labels.append(column_text)
super().__init__(QtCore.Qt.Horizontal,table)
self.table = self.parentWidget()
for column_index in range(0,self.total_columns):
header_item = self.parentWidget().horizontalHeaderItem(column_index)
header_item.setText(self.header_labels[column_index])
self.track_move = False
self.setVisible(True)
self.updateGeometries()
def mousePressEvent(self,event):
self.track_move = False
self.click = event.pos()
self.click_original = event.pos()
self.currentSectionRects = []
for column_index in range(0,self.total_columns):
self.updateGeometries()
self.currentSectionRects.append(QtCore.QRect())
self.currentSectionRects[column_index].setRect(self.sectionViewportPosition(column_index), 0, self.sectionSize(column_index), self.viewport().height())
if abs(self.currentSectionRects[column_index].right()-self.click.x())<4:
self.track_move = True
self.click = QtCore.QPoint(self.currentSectionRects[column_index].right(),0)
for column_index in range(0,self.total_columns):
self.setSectionResizeMode(column_index,QtWidgets.QHeaderView.Interactive)
QtWidgets.QHeaderView.mousePressEvent(self, event)
cursor_shape = self.cursor().shape()
if cursor_shape == QtCore.Qt.CursorShape.SplitHCursor:
self.track_move = True
else:
self.track_move = False
if self.track_move:
self.distances_from_right = []
for column_index in range(0,self.total_columns):
right = self.currentSectionRects[column_index].right()
distance = abs(right - self.click.x())
self.distances_from_right.append(distance)
min_distance = 10000
min_index = -1
for column_index in range(0,self.total_columns):
distance = self.distances_from_right[column_index]
if distance<min_distance:
min_index = column_index
min_distance = distance
self.min_index = min_index
def mouseMoveEvent(self,event):
self.moved = event.pos()
if self.track_move:
column_index = self.min_index
self.updateGeometries()
currentSectionRect = QtCore.QRect()
currentSectionRect.setRect(self.sectionViewportPosition(column_index), 0, self.sectionSize(column_index), self.viewport().height())
if self.click.x()>self.moved.x():
column_width = self.table.columnWidth(column_index)
if column_width<=self.columns_min_width[column_index]:
event.ignore()
self.setSectionResizeMode(column_index,QtWidgets.QHeaderView.Interactive)
self.table.setColumnWidth(column_index,self.columns_min_width[column_index])
self.setSectionResizeMode(column_index,QtWidgets.QHeaderView.Fixed)
return None
else:
self.setSectionResizeMode(column_index,QtWidgets.QHeaderView.Interactive)
QtWidgets.QHeaderView.mouseMoveEvent(self, event)
else:
self.setSectionResizeMode(column_index,QtWidgets.QHeaderView.Interactive)
QtWidgets.QHeaderView.mouseMoveEvent(self, event)
else:
QtWidgets.QHeaderView.mouseMoveEvent(self, event)
def mouseReleaseEvent(self,event):
self.track_move = False
QtWidgets.QHeaderView.mouseReleaseEvent(self, event)
for column_index in range(0,self.total_columns):
self.setSectionResizeMode(column_index,QtWidgets.QHeaderView.Interactive)
if __name__ == "__main__":
program = Run_me()
With this scripts i want to set a minimum width constraint when the user decides to resize a column.
The problem with this scripts is: Sometimes while pressing in resize area with the SplitHCursor and resize starts, the resize proccess stops but the cursor shape is still SplitHCursor. I don't know why this is happens.
If you find any other bug, or simpler solution feel free to answer or comment.