如何删除 QTreeView 缩进
How to remove QTreeView indentation
我想要 QTreeView
没有 左侧的缩进,在每个嵌套级别增加。我尝试设置 QTreeView::setIndentation(0)
。它按照我的意愿删除了缩进,但它也隐藏了树形箭头。
默认行为:
- 有缩进 ✗
- 带箭头✔
setIndentation(0)
之后:
- 没有缩进✔
- 没有箭头 ✗
期望的行为:
- 没有缩进✔
- 带箭头✔
那么如何才能达到第三个例子所示的结果呢?有什么标准的方法可以做到吗,或者我将不得不重新实现 QTreeView::paintEvent()
、QTreeView::drawBranches()
等?
为了解决这个问题,我使用委托来翻译项目的绘制,并绘制箭头。
#include <QtWidgets>
class BranchDelegate: public QStyledItemDelegate
{
public:
using QStyledItemDelegate::QStyledItemDelegate;
void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override{
QStyleOptionViewItem opt(option);
if(index.column() == 0)
opt.rect.adjust(opt.rect.height(), 0, 0, 0);
QStyledItemDelegate::paint(painter, opt, index);
if(index.column() == 0){
QStyleOptionViewItem branch;
branch.rect = QRect(0, opt.rect.y(), opt.rect.height(), opt.rect.height());
branch.state = option.state;
const QWidget *widget = option.widget;
QStyle *style = widget ? widget->style() : QApplication::style();
style->drawPrimitive(QStyle::PE_IndicatorBranch, &branch, painter, widget);
}
}
};
class TreeView: public QTreeView
{
public:
TreeView(QWidget *parent=nullptr):QTreeView(parent)
{
BranchDelegate *delegate = new BranchDelegate(this);
setItemDelegate(delegate);
setIndentation(0);
}
protected:
void mousePressEvent(QMouseEvent *event) override{
QModelIndex index = indexAt(event->pos());
bool last_state = isExpanded(index);
QTreeView::mousePressEvent(event);
if(index.isValid() && last_state == isExpanded(index))
setExpanded(index, !last_state);
}
};
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
TreeView w;
QFileSystemModel model;
model.setRootPath(QDir::rootPath());
w.setModel(&model);
w.setRootIndex(model.index(QDir::homePath()));
/*for (int i = 1; i< model.columnCount() ; ++i) {
w.hideColumn(i);
}*/
w.expandAll();
w.resize(640, 480);
w.show();
return a.exec();
}
如果有水平滚动,eyllanesc 就会崩溃。通常也只有 expands/collapses 单击分支指示器时的视图,而不是索引。
我的解决方案:只更改有父项但没有子项的索引的 Rect。也不要将缩进设置为 0。不需要子类化 QTreeView。
#include <QtWidgets>
class BranchDelegate: public QStyledItemDelegate
{
public:
mIndent = 50;
using QStyledItemDelegate::QStyledItemDelegate;
void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override
{
QStyleOptionViewItem opt(option);
if(index.parent().isValid && (!index.model() || !index.model()->index(0, 0, index).isValid()))
{
opt.rect.adjust(-mIndent, 0, 0, 0);
}
QStyledItemDelegate::paint(painter, opt, index);
}
};
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QTreeView apView;
BranchDelegate* const apDelegate = new BranchDelegate(apView);
apDelegate->mIndent = 50;
apView->setIndentation(apDelegate->mIndent);
apView->setItemDelegateForColumn(0, apDelegate);
QFileSystemModel model;
model.setRootPath(QDir::rootPath());
apView.setModel(&model);
apView.setRootIndex(model.index(QDir::homePath()));
/*for (int i = 1; i< model.columnCount() ; ++i) {
apView.hideColumn(i);
}*/
apView.expandAll();
apView.resize(640, 480);
apView.show();
return a.exec();
}
我想要 QTreeView
没有 左侧的缩进,在每个嵌套级别增加。我尝试设置 QTreeView::setIndentation(0)
。它按照我的意愿删除了缩进,但它也隐藏了树形箭头。
默认行为:
- 有缩进 ✗
- 带箭头✔
setIndentation(0)
之后:
- 没有缩进✔
- 没有箭头 ✗
期望的行为:
- 没有缩进✔
- 带箭头✔
那么如何才能达到第三个例子所示的结果呢?有什么标准的方法可以做到吗,或者我将不得不重新实现 QTreeView::paintEvent()
、QTreeView::drawBranches()
等?
为了解决这个问题,我使用委托来翻译项目的绘制,并绘制箭头。
#include <QtWidgets>
class BranchDelegate: public QStyledItemDelegate
{
public:
using QStyledItemDelegate::QStyledItemDelegate;
void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override{
QStyleOptionViewItem opt(option);
if(index.column() == 0)
opt.rect.adjust(opt.rect.height(), 0, 0, 0);
QStyledItemDelegate::paint(painter, opt, index);
if(index.column() == 0){
QStyleOptionViewItem branch;
branch.rect = QRect(0, opt.rect.y(), opt.rect.height(), opt.rect.height());
branch.state = option.state;
const QWidget *widget = option.widget;
QStyle *style = widget ? widget->style() : QApplication::style();
style->drawPrimitive(QStyle::PE_IndicatorBranch, &branch, painter, widget);
}
}
};
class TreeView: public QTreeView
{
public:
TreeView(QWidget *parent=nullptr):QTreeView(parent)
{
BranchDelegate *delegate = new BranchDelegate(this);
setItemDelegate(delegate);
setIndentation(0);
}
protected:
void mousePressEvent(QMouseEvent *event) override{
QModelIndex index = indexAt(event->pos());
bool last_state = isExpanded(index);
QTreeView::mousePressEvent(event);
if(index.isValid() && last_state == isExpanded(index))
setExpanded(index, !last_state);
}
};
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
TreeView w;
QFileSystemModel model;
model.setRootPath(QDir::rootPath());
w.setModel(&model);
w.setRootIndex(model.index(QDir::homePath()));
/*for (int i = 1; i< model.columnCount() ; ++i) {
w.hideColumn(i);
}*/
w.expandAll();
w.resize(640, 480);
w.show();
return a.exec();
}
如果有水平滚动,eyllanesc 就会崩溃。通常也只有 expands/collapses 单击分支指示器时的视图,而不是索引。
我的解决方案:只更改有父项但没有子项的索引的 Rect。也不要将缩进设置为 0。不需要子类化 QTreeView。
#include <QtWidgets>
class BranchDelegate: public QStyledItemDelegate
{
public:
mIndent = 50;
using QStyledItemDelegate::QStyledItemDelegate;
void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override
{
QStyleOptionViewItem opt(option);
if(index.parent().isValid && (!index.model() || !index.model()->index(0, 0, index).isValid()))
{
opt.rect.adjust(-mIndent, 0, 0, 0);
}
QStyledItemDelegate::paint(painter, opt, index);
}
};
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QTreeView apView;
BranchDelegate* const apDelegate = new BranchDelegate(apView);
apDelegate->mIndent = 50;
apView->setIndentation(apDelegate->mIndent);
apView->setItemDelegateForColumn(0, apDelegate);
QFileSystemModel model;
model.setRootPath(QDir::rootPath());
apView.setModel(&model);
apView.setRootIndex(model.index(QDir::homePath()));
/*for (int i = 1; i< model.columnCount() ; ++i) {
apView.hideColumn(i);
}*/
apView.expandAll();
apView.resize(640, 480);
apView.show();
return a.exec();
}