QTreeWidget 与复选框相同的节点选择

在项目使用过程中经常出现需要选择一棵树中的某些节点,通常情况下在树节点的前面增加复选框即可;但是偶尔也有其他的设计,例如本人碰到的在树的右侧显示被选择。接下来将讲解如果在QTreeWidget的右侧显示被选择。

效果图如下:
QTreeWidget示例,能够在右侧选择节点
实现方法:
1、配置树为两列

ui->treeWidget->setColumnCount(2);
ui->treeWidget->header()->setSectionResizeMode(0, QHeaderView::ResizeToContents);
ui->treeWidget->header()->setSectionResizeMode(1, QHeaderView::Fixed);
ui->treeWidget->setColumnWidth(1, 14);

2、添加一颗简单的树

ui->treeWidget->header()->hide();
QStringList zhangsan;
zhangsan<<QString("张三");
QTreeWidgetItem *zhangsanroot = new QTreeWidgetItem(ui->treeWidget, zhangsan);
zhangsanroot->setData(0, Qt::UserRole, 1);//UserRole表示节点类型
zhangsanroot->setData(0, Qt::UserRole+1, 0);//UserRole+1表示节点点击状态

QStringList strLisi;
strLisi<<QString("李四");
QTreeWidgetItem *lisi = new QTreeWidgetItem(zhangsanroot, strLisi);
lisi->setData(0, Qt::UserRole, 2);
lisi->setData(0, Qt::UserRole+1, 0);

QStringList strMing;
strMing<<QString("明明");
QTreeWidgetItem *mingming = new QTreeWidgetItem(zhangsanroot, strMing);
mingming->setData(0, Qt::UserRole, 2);
mingming->setData(0, Qt::UserRole+1, 0);

3、树节点被点击的时候改变属性值

connect(ui->treeWidget, &QTreeWidget::itemClicked, this, &TreeWidgetDialog::slotClick);
void TreeWidgetDialog::slotClick(QTreeWidgetItem *item, int column)
{
    int role = item->data(0, Qt::UserRole).toInt();
    if(role == 1){
        //选中下面所有的
    }else if(role == 2){
        //选中单个
        int select = item->data(0, Qt::UserRole+1).toInt();
        select = !select;
        item->setData(0, Qt::UserRole+1, select);
    }
}

4、接下来就是重点,本人是使用代理绘制实现选择,直接上代码
下面代码是代理绘制的实现:需要重写paint和sizeHint函数;paint函数是对每个index(即每个item)的区域option.rect的适当位置进行绘制,本次就是对item的第一列左侧开始绘制一个14*14的图片,因为第一步中设置第一列为14,因此图片正好填充整列。当然有了代理绘制的实现,我们需要设置树使用下面的代理绘制:ui->treeWidget->setItemDelegate(new TreeViewDelegate);

#include <QStyledItemDelegate>
class TreeViewDelegate : public QStyledItemDelegate
{
    Q_OBJECT
public:
    TreeViewDelegate::TreeViewDelegate(QObject *parent = Q_NULLPTR) :
        QStyledItemDelegate(parent)
    {

    }

    void TreeViewDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
    {
        if(index.column() == 1){
            painter->save();
            QRectF iconRect = QRect(option.rect.x(),option.rect.y()+(30-14)/2, 14, 14);
            QTreeWidgetItem *item = static_cast<QTreeWidgetItem*>(index.internalPointer());
            int select = item->data(0, Qt::UserRole+1).toInt();
            if(select){
               painter->drawImage(iconRect, QImage("Y:/Documents/tcpClient1/select_c.png").scaled(14,14));
            }else{
                painter->drawImage(iconRect, QImage("Y:/Documents/tcpClient1/select.png").scaled(14,14));
            }
            painter->restore();
        }
        QStyledItemDelegate::paint(painter, option, index);
    }

    QSize TreeViewDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
    {
        return QSize(250, 30);
    }
};

这里我是使用代理绘制实现选中和取消选中的绘制图片不同达到选中和取消选中节点的效果。当然也可以在第1列(总共两列,第0列和第1列)放置一个按钮,可能在后面的文章中分享。

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值