在 PyQt4 中调整 QTableView 的垂直大小 Header?
Resize Vertical Header of QTableView in PyQt4?
我需要缩小第一列(垂直 headers 的列)
如何在 PyQt4 中调整 QTableView 的垂直 header 大小?
我有非常大的 headers 和小的 GUI 块来显示这个 table 所以,请帮助我!
我可以调整所有列的大小,但无法确定调整垂直 headers 的大小?
我尝试了很多方法,例如:
self.tableView.setColumnWidth(0, 30) // only able to change the data columns in table not headers
self.tableView.verticalHeader().setResizeMode(QHeaderView.Interactive) //Able to change the height of headers but not width of them
我想制作可以由用户调整大小的headers并且不依赖于项目的任何其他参数,如window大小,其他列的大小....
有人可以帮我解决这个问题吗?
PyQt 往往有一些糟糕的文档,但 this page 提供了有关 QTableView 的所有可能信息 class。
我不确定您的具体问题是什么,但是您可以尝试:
self.tableView.horizontalHeader().setSectionResizeMode(3)
The documentation of .setSectionResize()
或者,如果您想将每个 header 调整为设定大小,请尝试:
self.tableView.horizontalHeader().resizeSection(0, pixelSize1)
self.tableView.horizontalHeader().resizeSection(1, pixelSize2)
self.tableView.horizontalHeader().resizeSection(2, pixelSize3)
...
您可以使用 setMaximWidth, and use setTextElideMode 来限制垂直 header 的大小,以调整文本的裁剪方式。
但是,没有 built-in 方法可以让用户调整垂直 header 宽度。因此,作为 work-around,您可以使用 resize-event 将垂直 header 的宽度调整为总宽度的百分比。这样,调整 window 的大小也会改变垂直 header.
的宽度
这是一个实现所有这些的演示脚本:
import sys
from PyQt4 import QtCore, QtGui
class Window(QtGui.QWidget):
def __init__(self, rows, columns):
super(Window, self).__init__()
self.table = QtGui.QTableView(self)
self.table.installEventFilter(self)
self.table.verticalHeader().setTextElideMode(QtCore.Qt.ElideRight)
model = QtGui.QStandardItemModel(rows, columns, self.table)
for row in range(rows):
item = QtGui.QStandardItem('FOO_BAR_123_AB_CD_%s' % row)
model.setVerticalHeaderItem(row, item)
for column in range(columns):
item = QtGui.QStandardItem('(%d, %d)' % (row, column))
item.setTextAlignment(QtCore.Qt.AlignCenter)
model.setItem(row, column, item)
self.table.setModel(model)
layout = QtGui.QVBoxLayout(self)
layout.addWidget(self.table)
def eventFilter(self, source, event):
if event.type() == QtCore.QEvent.Resize and source is self.table:
source.verticalHeader().setMaximumWidth(source.width() / 4)
return super(Window, self).eventFilter(source, event)
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
window = Window(15, 5)
window.setGeometry(600, 100, 400, 300)
window.show()
sys.exit(app.exec_())
更新:
我尝试编写自定义 header class 来实现用户调整垂直 header 宽度的大小。它 almost 有效,但我找不到在用鼠标拖动时正确更新视图的方法。无论如何,这是我目前所拥有的演示,以防任何人看到如何使其工作:
import sys
from PyQt4 import QtCore, QtGui
class HeaderView(QtGui.QHeaderView):
def __init__(self, table):
super(HeaderView, self).__init__(QtCore.Qt.Horizontal, table)
self.setClickable(True)
self.setHighlightSections(True)
self.setResizeMode(QtGui.QHeaderView.Interactive)
self._vheader = table.verticalHeader()
self._resizing = False
self._start_position = -1
self._start_width = -1
def mouseMoveEvent(self, event):
if self._resizing:
width = event.x() - self._start_position + self._start_width
if width > 0:
self._vheader.setFixedWidth(width)
# TODO: find a proper replacement for this
self.geometriesChanged.emit()
else:
super(HeaderView, self).mouseMoveEvent(event)
if 0 <= event.x() <= 3:
if not self.testAttribute(QtCore.Qt.WA_SetCursor):
self.setCursor(QtCore.Qt.SplitHCursor)
def mousePressEvent(self, event):
if not self._resizing and event.button() == QtCore.Qt.LeftButton:
if 0 <= event.x() <= 3:
self._start_position = event.x()
self._start_width = self._vheader.width()
self._resizing = True
return
super(HeaderView, self).mousePressEvent(event)
def mouseReleaseEvent(self, event):
self._resizing = False
super(HeaderView, self).mouseReleaseEvent(event)
class Window(QtGui.QWidget):
def __init__(self, rows, columns):
super(Window, self).__init__()
self.table = QtGui.QTableView(self)
self.table.setHorizontalHeader(HeaderView(self.table))
self.table.verticalHeader().setTextElideMode(QtCore.Qt.ElideRight)
model = QtGui.QStandardItemModel(rows, columns, self.table)
for row in range(rows):
item = QtGui.QStandardItem('FOO_BAR_123_AB_CD_%s' % row)
item.setToolTip(item.text())
model.setVerticalHeaderItem(row, item)
for column in range(columns):
item = QtGui.QStandardItem('(%d, %d)' % (row, column))
item.setTextAlignment(QtCore.Qt.AlignCenter)
model.setItem(row, column, item)
self.table.setModel(model)
layout = QtGui.QVBoxLayout(self)
layout.addWidget(self.table)
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
window = Window(15, 5)
window.setGeometry(600, 100, 400, 300)
window.show()
sys.exit(app.exec_())
Ekhumoro 的解决方案近乎完美。在调整大小期间看到的断断续续的拖动行为与调整大小发生时坐标 space 的变化有关。
要修复这种不稳定的行为并平滑地调整大小,您应该使用全局坐标 space 而不是 header 视图的局部坐标。
为此,只需将 event.x() 替换为 event.globalX()
#width = event.x() - self._start_position + self._start_width
width = event.globalX() - self._start_position + self._start_width
#self._start_position = event.x()
self._start_position = event.globalX()
我还更改了从垂直 header 而不是水平 header 发出的几何变化信号。因为实际上改变大小的是垂直 header。然而,在我的测试案例中,我不能说它很重要,但从概念上讲它似乎是正确的。
#self.geometriesChanged.emit()
self._vheader.geometriesChanged.emit()
我需要缩小第一列(垂直 headers 的列)
如何在 PyQt4 中调整 QTableView 的垂直 header 大小?
我有非常大的 headers 和小的 GUI 块来显示这个 table 所以,请帮助我!
我可以调整所有列的大小,但无法确定调整垂直 headers 的大小?
我尝试了很多方法,例如:
self.tableView.setColumnWidth(0, 30) // only able to change the data columns in table not headers
self.tableView.verticalHeader().setResizeMode(QHeaderView.Interactive) //Able to change the height of headers but not width of them
我想制作可以由用户调整大小的headers并且不依赖于项目的任何其他参数,如window大小,其他列的大小....
有人可以帮我解决这个问题吗?
PyQt 往往有一些糟糕的文档,但 this page 提供了有关 QTableView 的所有可能信息 class。
我不确定您的具体问题是什么,但是您可以尝试:
self.tableView.horizontalHeader().setSectionResizeMode(3)
The documentation of .setSectionResize()
或者,如果您想将每个 header 调整为设定大小,请尝试:
self.tableView.horizontalHeader().resizeSection(0, pixelSize1)
self.tableView.horizontalHeader().resizeSection(1, pixelSize2)
self.tableView.horizontalHeader().resizeSection(2, pixelSize3)
...
您可以使用 setMaximWidth, and use setTextElideMode 来限制垂直 header 的大小,以调整文本的裁剪方式。
但是,没有 built-in 方法可以让用户调整垂直 header 宽度。因此,作为 work-around,您可以使用 resize-event 将垂直 header 的宽度调整为总宽度的百分比。这样,调整 window 的大小也会改变垂直 header.
的宽度这是一个实现所有这些的演示脚本:
import sys
from PyQt4 import QtCore, QtGui
class Window(QtGui.QWidget):
def __init__(self, rows, columns):
super(Window, self).__init__()
self.table = QtGui.QTableView(self)
self.table.installEventFilter(self)
self.table.verticalHeader().setTextElideMode(QtCore.Qt.ElideRight)
model = QtGui.QStandardItemModel(rows, columns, self.table)
for row in range(rows):
item = QtGui.QStandardItem('FOO_BAR_123_AB_CD_%s' % row)
model.setVerticalHeaderItem(row, item)
for column in range(columns):
item = QtGui.QStandardItem('(%d, %d)' % (row, column))
item.setTextAlignment(QtCore.Qt.AlignCenter)
model.setItem(row, column, item)
self.table.setModel(model)
layout = QtGui.QVBoxLayout(self)
layout.addWidget(self.table)
def eventFilter(self, source, event):
if event.type() == QtCore.QEvent.Resize and source is self.table:
source.verticalHeader().setMaximumWidth(source.width() / 4)
return super(Window, self).eventFilter(source, event)
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
window = Window(15, 5)
window.setGeometry(600, 100, 400, 300)
window.show()
sys.exit(app.exec_())
更新:
我尝试编写自定义 header class 来实现用户调整垂直 header 宽度的大小。它 almost 有效,但我找不到在用鼠标拖动时正确更新视图的方法。无论如何,这是我目前所拥有的演示,以防任何人看到如何使其工作:
import sys
from PyQt4 import QtCore, QtGui
class HeaderView(QtGui.QHeaderView):
def __init__(self, table):
super(HeaderView, self).__init__(QtCore.Qt.Horizontal, table)
self.setClickable(True)
self.setHighlightSections(True)
self.setResizeMode(QtGui.QHeaderView.Interactive)
self._vheader = table.verticalHeader()
self._resizing = False
self._start_position = -1
self._start_width = -1
def mouseMoveEvent(self, event):
if self._resizing:
width = event.x() - self._start_position + self._start_width
if width > 0:
self._vheader.setFixedWidth(width)
# TODO: find a proper replacement for this
self.geometriesChanged.emit()
else:
super(HeaderView, self).mouseMoveEvent(event)
if 0 <= event.x() <= 3:
if not self.testAttribute(QtCore.Qt.WA_SetCursor):
self.setCursor(QtCore.Qt.SplitHCursor)
def mousePressEvent(self, event):
if not self._resizing and event.button() == QtCore.Qt.LeftButton:
if 0 <= event.x() <= 3:
self._start_position = event.x()
self._start_width = self._vheader.width()
self._resizing = True
return
super(HeaderView, self).mousePressEvent(event)
def mouseReleaseEvent(self, event):
self._resizing = False
super(HeaderView, self).mouseReleaseEvent(event)
class Window(QtGui.QWidget):
def __init__(self, rows, columns):
super(Window, self).__init__()
self.table = QtGui.QTableView(self)
self.table.setHorizontalHeader(HeaderView(self.table))
self.table.verticalHeader().setTextElideMode(QtCore.Qt.ElideRight)
model = QtGui.QStandardItemModel(rows, columns, self.table)
for row in range(rows):
item = QtGui.QStandardItem('FOO_BAR_123_AB_CD_%s' % row)
item.setToolTip(item.text())
model.setVerticalHeaderItem(row, item)
for column in range(columns):
item = QtGui.QStandardItem('(%d, %d)' % (row, column))
item.setTextAlignment(QtCore.Qt.AlignCenter)
model.setItem(row, column, item)
self.table.setModel(model)
layout = QtGui.QVBoxLayout(self)
layout.addWidget(self.table)
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
window = Window(15, 5)
window.setGeometry(600, 100, 400, 300)
window.show()
sys.exit(app.exec_())
Ekhumoro 的解决方案近乎完美。在调整大小期间看到的断断续续的拖动行为与调整大小发生时坐标 space 的变化有关。
要修复这种不稳定的行为并平滑地调整大小,您应该使用全局坐标 space 而不是 header 视图的局部坐标。 为此,只需将 event.x() 替换为 event.globalX()
#width = event.x() - self._start_position + self._start_width
width = event.globalX() - self._start_position + self._start_width
#self._start_position = event.x()
self._start_position = event.globalX()
我还更改了从垂直 header 而不是水平 header 发出的几何变化信号。因为实际上改变大小的是垂直 header。然而,在我的测试案例中,我不能说它很重要,但从概念上讲它似乎是正确的。
#self.geometriesChanged.emit()
self._vheader.geometriesChanged.emit()