1. 程式人生 > 其它 >QTreeWidget 與複選框相同的節點選擇

QTreeWidget 與複選框相同的節點選擇

技術標籤:qt

在專案使用過程中經常出現需要選擇一棵樹中的某些節點,通常情況下在樹節點的前面增加複選框即可;但是偶爾也有其他的設計,例如本人碰到的在樹的右側顯示被選擇。接下來將講解如果在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列)放置一個按鈕,可能在後面的文章中分享。