QTreeView 一个竖直滚动条引起的问题

一 问题描述

一般情况,当QTreeView的item展开后,数据较多时会展示滚动条,如果item上有右对齐的显示文本,在item展开/收起变化时,竖直滚动条会呈现显示/隐藏变化,右对齐文本会“左右移动”,视觉效果差。原因是滚动条出现后“挤占了”item的空间。

Windows下有该问题,Mac下没有问题。

二 问题展示Demo

环境Win10,Qt5.9.2

新建UI工程,在UI拖入一个QTreeView和一个QLabel。主窗体构造函数代码如下:

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    // 设置delegate
    QTreeView* tree = ui->treeView;
    tree->setItemDelegate(new MyTreeDelegate(tree, ui->label));

    // 设置model
    QStandardItemModel *model = new QStandardItemModel(tree);
    model->setHorizontalHeaderLabels(QStringList()<< "Demo");
    model->appendRow(new QStandardItem("1"));
    model->item(0)->appendRow(new QStandardItem("11"));
    model->item(0)->appendRow(new QStandardItem("12"));
    model->item(0)->appendRow(new QStandardItem("13"));
    model->item(0)->appendRow(new QStandardItem("14"));
    model->item(0)->appendRow(new QStandardItem("15"));
    model->item(0)->appendRow(new QStandardItem("16"));
    model->item(0)->appendRow(new QStandardItem("17"));
    model->item(0)->appendRow(new QStandardItem("18"));
    model->item(0)->appendRow(new QStandardItem("19"));
    model->item(0)->appendRow(new QStandardItem("20"));
    model->appendRow(new QStandardItem("2"));
    model->appendRow(new QStandardItem("3"));
    model->appendRow(new QStandardItem("4"));
    model->appendRow(new QStandardItem("5"));
    model->appendRow(new QStandardItem("6"));
    model->appendRow(new QStandardItem("7"));
    tree->setModel(model);

    // 设置VerticalScrollBarPolicy
    tree->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
}

其中MyTreeDelegate为自定义派生类:

// .h
class MyTreeDelegate : public QStyledItemDelegate
{
public:
    MyTreeDelegate(QObject* parent, QLabel* label);
    ~MyTreeDelegate(){}

protected:
    void paint(QPainter* painter,
               const QStyleOptionViewItem& option,
               const QModelIndex& index) const;
private:
    QLabel* label_;
};


// .cpp
MyTreeDelegate::MyTreeDelegate(QObject *parent, QLabel* label)
: QStyledItemDelegate(parent),label_(label)
{
}

void MyTreeDelegate::paint(QPainter *painter, 
     const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    QRect rect = option.rect;
    rect.setRight(rect.right() - 20);
    painter->drawText(rect, Qt::AlignVCenter | Qt::AlignRight, QString("rect.right:") +
                      QString::number(rect.right()));
    QStyledItemDelegate::paint(painter, option, index);
}

显示效果:

很明显在item展开,出现竖直滚动条后,右对齐文本挤向左边了。不停展开/收起,右对齐文本”左右跳动“。

三 方案

将画文本的rect.right()补偿回来。

void MyTreeDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    QRect rect = option.rect;


    // 改动代码部分
    QTreeView* tree = dynamic_cast<QTreeView*>(parent());
    if(NULL != tree->verticalScrollBar() && tree->verticalScrollBar()->isVisible())
    {
        label_->setText(QString("TreeView VerticalScrollBar visible, width:") +
                        QString::number(tree->verticalScrollBar()->width()));
    
        // 补偿宽度
        rect.setRight(rect.right() + tree->verticalScrollBar()->width());
    }
    else
    {
        label_->setText(QString("TreeView VerticalScrollBar is not visible!"));
    }
    

    rect.setRight(rect.right() - 20);
    painter->drawText(rect, Qt::AlignVCenter | Qt::AlignRight, QString("rect.right:") +
                      QString::number(rect.right()));
    QStyledItemDelegate::paint(painter, option, index);
}

 

如图所示,不论竖直滚动条是否出现,item上右对齐的文本位置不会发生变化。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值