Qt-QTreeView自定义树控件

Qt-QTreeView自定义树控件
在做中大型项目时,可能又成百上千个功能界面,而这些功能界面无非就是数据的输入与输出,那么对常用的控件进行定制是非常重要的。本人认为Qt的原生控件使用起来有以下几点问题:
1、 Qt控件为了兼容各种情况,设计得是比较抽象的,对于新员工来说理解起来比较困难,接口调用也复杂;
2、 不同的人对代码理解不同,Qt的控件用起来也是各显神通,后期维护起来非常困难;
3、 每个公司的产品有自己的外观风格,定制控件可以同一实现外观,无需开发人员自己处理。
可能刚刚看感觉比想象中的复杂一点,但是只要多看几遍就会清楚为什么Qt的控件要这样设计,项绘制部分参考了网上的代码。
主要自定义两个类,CustomTree和CustomTreeItemDelegate,类关系如下图:

核心代码:


void CustomTreeDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    painter->setRenderHint(QPainter::Antialiasing);

    //绘制背景
    QColor colorBg;
    if (option.state & QStyle::State_Selected)
    {
        colorBg = m_view->checkedBgColor();
    }
    else if (option.state & QStyle::State_MouseOver)
    {
        colorBg = m_view->hoverBgColor();
    }
    else
    {
        colorBg = m_view->bgColor();
    }
    QRect bgRect(0, option.rect.top(), m_view->width(), option.rect.height()); // 直接用option.rect,二级树左边有空白
    painter->fillRect(bgRect, colorBg);

    // 绘制checked状态的item的右侧三角形
    if (option.state & QStyle::State_Selected)
    {
        painter->setPen(Qt::NoPen);
        painter->setBrush(m_view->checkedTextColor());
        QVector<QPointF> points;
        points.append(QPointF(option.rect.right(), option.rect.top() + option.rect.height() * 0.3));
        points.append(QPointF(option.rect.right(), option.rect.top() + option.rect.height() * 0.7));
        points.append(QPointF(option.rect.right() - option.rect.height() * 0.3, option.rect.top() + option.rect.height() * 0.5));
        painter->drawPolygon(points);
    }

    //绘制+-伸缩图片
    if (m_model->itemFromIndex(index)->hasChildren())
    {
        QPixmap pix(18, 16);
        pix.fill(Qt::transparent);
        QPainter p(&pix);
        p.setRenderHint(QPainter::Antialiasing);
        int penWidth = 2;
        //根据采用的背景色判断
        QColor icoColorSelected;
        QColor icoColorNormal;
        QColor icoColorHover;
        icoColorSelected = m_view->checkedTextColor();
        icoColorNormal = m_view->textColor();
        icoColorHover = m_view->hoverTextColor();
        p.setBrush(Qt::NoBrush);
        if (option.state & QStyle::State_Selected)
        {
            p.setPen(QPen(icoColorSelected, penWidth));
        }
        else if (option.state & QStyle::State_MouseOver)
        {
            p.setPen(QPen(icoColorHover, penWidth));
        }
        else
        {
            p.setPen(QPen(icoColorNormal, penWidth));
        }
        // 绘制+-线条图片
        if (!m_view->isExpanded(index))
        {
            p.drawLine(QPointF(8, 8), QPointF(18, 8));
            p.drawLine(QPointF(12, 4), QPointF(12, 12));
        } else
        {
            p.drawLine(QPointF(8, 8), QPointF(18, 8));
        }

        QPixmap img(pix);
        QRect targetRect = option.rect;
        targetRect.setWidth(16);
        targetRect.setHeight(16);
        QPoint c = option.rect.center();
        c.setX(8 + option.rect.x());
        targetRect.moveCenter(c);
        painter->drawPixmap(targetRect, img, img.rect());
    }

    //绘制条目文字
    QColor colorText;
    if (option.state & QStyle::State_Selected)
    {
        colorText = m_view->checkedTextColor();
    }
    else if (option.state & QStyle::State_MouseOver)
    {
        colorText = m_view->hoverTextColor();
    }
    else
    {
        colorText = m_view->textColor();
    }
    painter->setPen(QPen(colorText));

    //绘制文字离左边的距离
    int margin = 25;
    QRect rect = option.rect;
    rect.setWidth(rect.width() - margin);
    rect.setX(rect.x() + margin);
    QFont normalFont("Microsoft Yahei", 9);
    painter->setFont(normalFont);
    painter->drawText(rect, Qt::AlignLeft | Qt::AlignVCenter, index.data(Qt::DisplayRole).toString());

    //绘制分隔符线条
    if (m_view->isShowLine())
    {
        painter->setPen(QPen(m_view->lineColor(), 1));
        if (!index.parent().isValid()) // 判断是否为一级item
        {
            painter->drawLine(option.rect.topLeft(), option.rect.topRight());
        }
    }

    //绘制提示信息
    QString recordInfo = m_view->infoStr(index);
    //如果不需要显示提示信息或者提示信息为空则返回
    if (recordInfo.isNull() || recordInfo.isEmpty() || !recordInfo.length())
    {
        return;
    }
    QPen decorationPen(option.state & QStyle::State_Selected ? m_view->checkedBgColor() : m_view->checkedTextColor());
    QBrush decorationBrush(option.state & QStyle::State_Selected ? m_view->checkedTextColor() : m_view->checkedBgColor());
    QFont decorationFont("Microsoft Yahei", 8);
    painter->setFont(decorationFont);
    //绘制提示信息背景
    QRect decoration = option.rect;
    decoration.setHeight(15);
    decoration.moveCenter(option.rect.center());
    decoration.setLeft(option.rect.right() - 55);
    decoration.setRight(option.rect.right() - 15);
    painter->setPen(decorationPen);
    QPainterPath path;
    path.addRoundedRect(decoration, 7, 7);
    painter->fillPath(path, decorationBrush);
    //如果是数字则将超过999的数字显示成 999+
    if (recordInfo.toInt() > 999)
    {
        recordInfo = "999+";
    }
    //如果显示的提示信息长度超过4则将多余显示成省略号..
    if (recordInfo.length() > 4) {
        recordInfo = recordInfo.mid(0, 4) + "..";
    }
    painter->drawText(decoration, Qt::AlignCenter, recordInfo);
}


void CustomTree::addItem(const QString &text, QStandardItem *parent)
{
    if (NULL == parent)
    {
        m_model->appendRow(new QStandardItem(text));
    }
    else
    {
        parent->appendRow(new QStandardItem(text));
    }
}

void CustomTree::addItem(const QString &parentText, const QString &text)
{
    QList<QStandardItem *> ls = m_model->findItems(parentText, Qt::MatchRecursive);

    if (!ls.isEmpty())
    {
        foreach (QStandardItem *item, ls)
        { // 找到的都加上
            addItem(text, item);
        }
    }
}

 调用实例:

    customTree->addItem("系统参数");
    customTree->setItemInfo("系统参数", "管理员");
    customTree->addItem("轴参数");
    customTree->addItem("轴参数", "轴1");
    customTree->addItem("轴参数", "轴2");
    customTree->addItem("轴参数", "轴3");

    customTree->addItem("用户参数");
    customTree->addItem("用户参数", "公共");
    customTree->addItem("用户参数", "用户1");
    customTree->addItem("用户参数", "用户2");
    customTree->addItem("用户参数", "用户3");

    customTree->addItem("设备参数");
    customTree->addItem("设备参数", "设备1");
    customTree->addItem("设备参数", "设备2");
    customTree->addItem("设备参数", "设备3");

运行效果: 

 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Qt是一种流行的跨平台C++应用程序框架,在GUI开发方面非常出色。Qt包含大量的控件,其中一个是控件QTreeView。这个控件允许用户显示带有形视图的数据模型,它是QAbstractItemView的派生类之一。 QTreeView控件具有以下特点: 1. 显示数据模型 - QTreeView控件显示控件绑定的数据模型。用户可以打开和关闭节点以显示或隐藏子节点。 2. 的构建 - 的层次结构是通过节点之间的父子关系来定义的。最上面的节点称为根节点,其余的为子节点。 3. 定制化 - QTreeView控件可以被用户定制。用户可以通过设置控件的颜色、字体、大小和对齐方式等来将控件表现为自己想要的样子。 4. 功能强大 - QTreeView控件有很多内置的功能,包括可排序、可过滤、可编辑等等。它也允许用户通过自定义delegate,来实现额外的交互行为。 下面是一些使用QTreeView控件的示例: 1. 创建一个QTreeView控件QTreeView *treeView = new QTreeView(parent); 2. 设置它的数据模型: QStandardItemModel *model = new QStandardItemModel(parent); treeView->setModel(model); 3. 填充数据模型: QStandardItem *rootItem = model->invisibleRootItem(); QStandardItem *item1 = new QStandardItem("Item 1"); QStandardItem *item2 = new QStandardItem("Item 2"); rootItem->appendRow(item1); rootItem->appendRow(item2); 4. 显示控件: treeView->show(); QTreeView控件是一个非常强大的控件,可以用于各种情况下。它可以轻松地显示大量的数据,并让用户轻松地翻阅它们。在GUI开发中,QTreeView控件是一个非常有用的控件

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值