我试图将QTableView中的水平和垂直标题设置为自动换行但没有任何成功。
我想将所有列设置为相同的宽度(包括垂直标题),以及将多行文本设置为自动换行的列。如果单词比列宽,它应该偏向正确。 我设法使用QTableView设置了elide - > horizontalHeader() - > setTextElideMode(Qt :: ElideRight),但由于QHeaderView没有setWordWrap方法,所以我不能对自动换行做同样的事情。因此,如果文本是多行的,它就会消失。在表格视图上设置自动换行不会做任何事情。表格单元格只包含小数字,所以问题只出在标题上,我想避免使用' / n'因为标题是动态设置的。可能还有一些其他设置我已经改变了不允许自动换行功能吗?
答案 0 :(得分:1)
我设法使用QHeaderView
的子类并在其中重新实现sectionSizeFromContents
和paintSection
方法找到解决方案。这是PyQt5中的演示(使用Python 3.5.2和Qt 5.6测试):
import sys
import string
import random
from PyQt5 import QtCore, QtWidgets, QtGui
class HeaderViewWithWordWrap(QtWidgets.QHeaderView):
def __init__(self):
QtWidgets.QHeaderView.__init__(self, QtCore.Qt.Horizontal)
def sectionSizeFromContents(self, logicalIndex):
if self.model():
headerText = self.model().headerData(logicalIndex,
self.orientation(),
QtCore.Qt.DisplayRole)
options = self.viewOptions()
metrics = QtGui.QFontMetrics(options.font)
maxWidth = self.sectionSize(logicalIndex)
rect = metrics.boundingRect(QtCore.QRect(0, 0, maxWidth, 5000),
self.defaultAlignment() |
QtCore.Qt.TextWordWrap |
QtCore.Qt.TextExpandTabs,
headerText, 4)
return rect.size()
else:
return QtWidgets.QHeaderView.sectionSizeFromContents(self, logicalIndex)
def paintSection(self, painter, rect, logicalIndex):
if self.model():
painter.save()
self.model().hideHeaders()
QtWidgets.QHeaderView.paintSection(self, painter, rect, logicalIndex)
self.model().unhideHeaders()
painter.restore()
headerText = self.model().headerData(logicalIndex,
self.orientation(),
QtCore.Qt.DisplayRole)
painter.drawText(QtCore.QRectF(rect), QtCore.Qt.TextWordWrap, headerText)
else:
QtWidgets.QHeaderView.paintSection(self, painter, rect, logicalIndex)
class Model(QtCore.QAbstractTableModel):
def __init__(self):
QtCore.QAbstractTableModel.__init__(self)
self.model_cols_names = [ "Very-very long name of my first column",
"Very-very long name of my second column",
"Very-very long name of my third column",
"Very-very long name of my fourth column" ]
self.hide_headers_mode = False
self.data = []
for i in range(0, 10):
row_data = []
for j in range(0, len(self.model_cols_names)):
row_data.append(''.join(random.choice(string.ascii_uppercase +
string.digits) for _ in range(6)))
self.data.append(row_data)
def hideHeaders(self):
self.hide_headers_mode = True
def unhideHeaders(self):
self.hide_headers_mode = False
def rowCount(self, parent):
if parent.isValid():
return 0
else:
return len(self.data)
def columnCount(self, parent):
return len(self.model_cols_names)
def data(self, index, role):
if not index.isValid():
return None
if role != QtCore.Qt.DisplayRole:
return None
row = index.row()
if row < 0 or row >= len(self.data):
return None
column = index.column()
if column < 0 or column >= len(self.model_cols_names):
return None
return self.data[row][column]
def headerData(self, section, orientation, role):
if role != QtCore.Qt.DisplayRole:
return None
if orientation != QtCore.Qt.Horizontal:
return None
if section < 0 or section >= len(self.model_cols_names):
return None
if self.hide_headers_mode == True:
return None
else:
return self.model_cols_names[section]
class MainForm(QtWidgets.QMainWindow):
def __init__(self, parent=None):
QtWidgets.QMainWindow.__init__(self, parent)
self.model = Model()
self.view = QtWidgets.QTableView()
self.view.setModel(self.model)
self.view.setHorizontalHeader(HeaderViewWithWordWrap())
self.setCentralWidget(self.view)
def main():
app = QtWidgets.QApplication(sys.argv)
form = MainForm()
form.show()
app.exec_()
if __name__ == '__main__':
main()
答案 1 :(得分:1)
我能够合并上面的两种方法(c ++,Qt 5.12),效果非常好。 (模型上没有Hideheaders)
QHeaderView::sectionSizeFromContents()
,以使文本占位大小QSize MyHeaderView::sectionSizeFromContents(int logicalIndex) const
{
const QString text = this->model()->headerData(logicalIndex, this->orientation(), Qt::DisplayRole).toString();
const int maxWidth = this->sectionSize(logicalIndex);
const int maxHeight = 5000; // arbitrarily large
const auto alignment = defaultAlignment();
const QFontMetrics metrics(this->fontMetrics());
const QRect rect = metrics.boundingRect(QRect(0, 0, maxWidth, maxHeight), alignment, text);
const QSize textMarginBuffer(2, 2); // buffer space around text preventing clipping
return rect.size() + textMarginBuffer;
}
tableview->horizontalHeader()->setDefaultAlignment(Qt::AlignCenter | (Qt::Alignment)Qt::TextWordWrap);
答案 2 :(得分:0)
2010年的open Qt issue表示这可能不容易实现。 但是,根据2015年的唯一评论,此问题有一个简单的解决方法,如下所示:
myTable->horizontalHeader()->setDefaultAlignment(Qt::AlignCenter | (Qt::Alignment)Qt::TextWordWrap);
我刚刚使用Qt 5.12进行了测试,幸运的是它仍然可以正常工作。
答案 3 :(得分:0)
在python中:
myTableView.horizontalHeader().setDefaultAlignment(Qt.AlignCenter | Qt.Alignment(Qt.TextWordWrap))