目录
1. 问题的提出
在开发中,需要设置QTableView控件的列宽,但通过QTableView类的setColumnWidth函数设置列宽,发现不起作用。例如下代码不能改变第1列的列宽:
ui->groupGuaraTv->setColumnWidth(0, 400);
其中ui->groupGuaraTv为QTableView类对象。
2. 预备知识
本博文用到了Qt的Model/View/Delegate 框架,如果对Qt的“模型/视图/委托”框架不懂,本博文很难读懂。如果不懂这方面的知识,请在Qt Assistant 中输入Model/View Programming 学习了解。读者本机Qt安装目录下的Examples\Qt-XX.XX.XX\widgets\itemviews目录下有很多model/view framework的例子,可以进行自学了解,其中XX.XX.XX为Qt的版本号,如:5.14.1。
3.解决方法
先实现一个代理类,代码实现如下:
styleDelegate.cpp
#include "styleDelegate.h"
#include<QPainter>
CStyleDelegate::CStyleDelegate(QObject *parent)
: QStyledItemDelegate(parent)
{
}
QSize CStyleDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
{
auto colIndex = index.column();
auto it = m_mpColumnWidth.find(colIndex);
if(it == m_mpColumnWidth.end()) // 如果该列不需要设置列宽,就用代理项默认的列宽
{
return QStyledItemDelegate::sizeHint(option, index);
}
else // 如果该列需要设置列宽,就用设置的列宽
{
return QSize(it->second, option.rect.height());
}
}
void CStyleDelegate::setColumnWidth(int columnIndex, int columnWidth)
{
m_mpColumnWidth[columnIndex] = columnWidth;
}
styleDelegate.h
#ifndef STYLE_DELEGATE_H
#define STYLE_DELEGATE_H
#include <QStyledItemDelegate>
#include<map>
using std::map;
class CStyleDelegate : public QStyledItemDelegate
{
Q_OBJECT
public:
explicit CStyleDelegate(QObject *parent = nullptr);
public:
/* 改变列宽度。
* 注意:本函数仅仅对QTableView起作用,
* 对QTreeView、QTableWidget不起作用(这种情况下,用QTreeView、QTableWidget自己的setColumnWidth函数)
*/
void setColumnWidth(int columnIndex, int columnWidth);
protected:
virtual QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const override;
private:
map<int, int> m_mpColumnWidth; // 需要改变列宽的列索引和该列列宽的map
};
#endif // STYLE_DELEGATE_H
对QTableView对象设置列宽代码如下:
#include"styleDelegate.h"
// 构造一个代理类对象
auto pFaultDelegate = new CStyleDelegate(this);
// 将代理类对象设置到QTableView类ui->myTableView对象上
ui->myTableView->setItemDelegate(pDelegate);
// 改变列宽
pFaultDelegate->setColumnWidth(0, 400);
pFaultDelegate->setColumnWidth(1, 800);
4.注意的问题
- 一定要调用代理类CStyleDelegate的setColumnWidth函数来改变QTableView的列宽,调用QTableView自身的setColumnWidth函数不会改变列宽。CStyleDelegate的setColumnWidth函数是自己取的名称,为了避免和QTableView自身的setColumnWidth函数混淆,造成误解,你可以将CStyleDelegate的setColumnWidth函数改为其它名称,如:setItemWidth。
- QTreeView、QTableWidget类也可以用setItemDelegate方法来设置代理,调用它们的setItemDelegate方法来将CStyleDelegate类对象设置为代理,但调用CStyleDelegate的setColumnWidth函数来改变QTreeView、QTableWidget的列宽不会起作用,在这种情况下,用QTreeView、QTableWidget自己的setColumnWidth函数设置列宽能起效果。也就是说2节中提到的方法仅仅对QTableView列宽起作用,对QTreeView、QTableWidget改变列宽不起作用。