精华内容
下载资源
问答
  • 自定义树控件

    2012-11-07 16:11:54
    是一个 CTreeCtrl 用法的示例,给出了CTreeCtrl与Check Box 和 Radio buttown在一起的用法-CTreeCtrl is an example of usage, and given CTreeCtrl Check Box and Radio buttown together Usage
  • Qt-QTreeView自定义树控件

    千次阅读 2020-01-18 13:14:11
    Qt-QTreeView自定义树控件 在做中大型项目时,可能又成百上千个功能界面,而这些功能界面无非就是数据的输入与输出,那么对常用的控件进行定制是非常重要的。本人认为Qt的原生控件使用起来有以下几点问题: 1、 Qt...

    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");
    

    效果:
    在这里插入图片描述在这里插入图片描述

    展开全文
  • 树控件允许“每个项目样式”,并且不需要位图数组
  • CTreeData自定义树控件

    2009-08-11 14:26:18
    很好的哦,可以帮助你做很多的事情,信不信就看你的了
  • id:treeViewStyle //自定义样式 TreeViewStyle { indentation: 30 //节点间隔 branchDelegate: Image { //节点的展开标记图 id:image source: styleData.isExpanded ? "qrc:/pic/collapse.png" : "qrc:/...
    • 背景:

             前段时间工作需要使用QML的TreeView,要通过拖动节点,对应节点执行对应的操作,查了很多的资料,没有看到关于节点可拖动的资料,查看TreeView的源码,貌似存在关于节点拖动的地方,但是始终没有看到可以使用的接口,只好自己动手造轮子了,加上使用过程中踩了不少的坑,也算是给后面用到的人一个案例吧,如果有什么好的建议,什么疑问,又或者有好的萝卜坑推荐,都可以加这个QQ:995187021,即使没有解决问题,也可以交个朋友。

    • 效果:

    • 代码:(直接上代码了,不知道怎么描述,看注释吧,有问题加QQ)

    MyTreeView.qml

     

    import QtQuick 2.0
    import QtQuick.Controls 1.4
    import QtQuick.Controls.Styles 1.4
    import QtQml.Models 2.2
    
    Rectangle{
        property variant nodePic: ["qrc:/pic/pan.png","qrc:/pic/dir.png","qrc:/pic/file.png"]
        id:root
        TreeView{
            id:myTree
            anchors.fill:parent
            style: treeViewStyle
            selection: sel
            headerVisible: false    //隐藏列的头,想知道作用可以注释掉运行看效果
            Component.onCompleted: {
                model = TreeModel.model() //从TreeModel获取model
            }
            
            itemDelegate:Item{          //节点代理
                id:treeItem
                Image {                 //节点前的图片
                    id: nodeImg
                    height: parent.height
                    width: {                //不同级的节点图片宽度不一样
                        if(styleData.depth==0){
                            return parent.width/6
                        }else if(styleData.depth==1){
                            return parent.width/10
                        }else if(styleData.depth==2){
                            return parent.width/6
                        }
                    }
                    source: {                       //不同级的节点图片不一样
                        if(styleData.depth==0){
                            return nodePic[0]
                        }else if(styleData.depth==1){
                            return nodePic[1]
                        }else if(styleData.depth==2){
                            return nodePic[2]
                        }
                    }
                }
                Text{
                    id:itemText
                    anchors.left: nodeImg.right
                    anchors.leftMargin: 4
                    anchors.bottom:parent.bottom
                    // elide: styleData.elideMode
                    text:styleData.value       //显示来自model的文本
                    color: styleData.selected ? "#007dff":"white"  //选中时字体颜色切换
                    font.pointSize:styleData.selected ? 10:9      //选中时字体大小改变
                    
                    Drag.active: styleData.depth<=1 ? false:itemMosue.drag.active;//一级节点不可拖动
                    Drag.supportedActions: Qt.CopyAction;   //选择复制数据到DropArea
                    Drag.dragType: Drag.Automatic;          //选择自动开始拖动
                    Drag.mimeData: {"text": text};          //选择要传的数据,这里传文本
                    
                    MouseArea{                              //节点代理的鼠标事件
                        id:itemMosue
                        hoverEnabled: true
                        anchors.fill: parent
                        drag.target: itemText
                        
                        Drag.onDragStarted: {       //控制台打印开始拖动
                            console.log("start")
                        }
                        onPressed: {
                            sel.setCurrentIndex(styleData.index,0x0010) //点击了文字,选中该节点
                            if(styleData.isExpanded){                   //切换节点的展开状态
                                myTree.collapse(styleData.index)
                            }
                            else{
                                myTree.expand(styleData.index)
                            }
                        }
                        //onReleased: parent.Drag.drop()
                    }
                }
            }
            TableViewColumn {               //列
                title:qsTr("所有通道")
                role: "text"                //显示的元素
                width: 200                  //列的宽
            }
        }
        ItemSelectionModel {            //自定义添加选中
            id: sel
            model: TreeModel.model();
        }
        Component {
            id:treeViewStyle            //树的自定义样式
            TreeViewStyle {
                indentation: 30         //节点间隔
                branchDelegate: Image { //节点的展开标记图
                    id:image
                    source: styleData.isExpanded ? "qrc:/pic/collapse.png" : "qrc:/pic/expansion.png"
                    width: 9
                    height:9
                    anchors.top:parent.top
                    anchors.topMargin: 2
                }
                rowDelegate: Rectangle {            //行代理
                    height: 16
                    color:styleData.selected? "#e9fffd" : "#323232" //这里决定了节点选中的颜色和背景颜色
                }
                
            }
        }
    }
    

    main.qml

    import QtQuick 2.7
    import QtQuick.Window 2.2
    
    Window {
        visible: true
        width: 640
        height: 480
        title: qsTr("Hello World")
    
        MyTreeView{
            id:myTree
            height: parent.height
            width: parent.width/2
        }
        Rectangle{
                    id:dropContainer
                    height: parent.height/2
                    width: parent.width/4
                    anchors.left: myTree.right
                    y:10
                    Text {
                        id: accptedText
                        text: qsTr("请拖动树节点到该矩形框!!!")
                        color: "red"
                    }
                      border.color: "red"
                      border.width: 1
                      DropArea{
                                id:myDropArea
                                anchors.fill: parent
                                onDropped: {
                                if(drop.supportedActions == Qt.CopyAction){
                                        accptedText.text=drop.getDataAsString("text")
                                }
                             }
                      }
    
        }
    }
    

     压缩包下载链接:

    1.GitHub:https://github.com/simplewen/QML

    2CSDN下载:https://download.csdn.net/download/weixin_40912639/10778343

     

     

    展开全文
  • 自定义树控件

    2018-05-24 23:55:52
    自定义树控件 可以添加自己喜欢的图标
  • 自定义树控件(用三角箭头替换+-按钮), CButtonST是一个十分有用按钮控件
  • 下拉框呈现树控件
  • 自定义树形结构控件

    2015-07-29 10:42:11
    自定义任意层级控件自定义ListView):用到的知识:1.反射+注解,
  • 水平树 Treeview自定义高级控件 菜单分级形 C#
  • 自定义树形列表控件

    2018-11-02 10:25:21
    简单易用的形列表控件,结合形和列表控件,亲测通过编译
  • qt中定义了很多简单实用的数据展示视图控件,比如表格和形表等。由于表格的结构和数据库存储类似,所以qt提供一个类来实现表格视图和数据库的直接连接。但是对于形结构,在数据库中的表达和视图的表达有较大差异...

    前言

    qt中定义了很多简单实用的数据展示视图控件,比如表格和树形表等。由于表格的结构和数据库存储类似,所以qt提供一个类来实现表格视图和数据库的直接连接。但是对于树形结构,在数据库中的表达和视图的表达有较大差异,qt尚未提供相关的功能。
    本文的背景是要做一个模板的管理功能。由于模板的组织方式是层级结构(树形结构),所以要用到树形控件。又要求具有持久化保存模板的功能,将来还可能扩展的远程的模板统一管理,所以使用数据库进行模板的保存。

    所以本文要介绍的是笔者最近做的一个基于QTreeWidget的自定义树形控件,可以实现右击菜单,每次更改树结构后实时修改数据库,初始化时从数据库读取树形结构并显示。
    具体效果如下:
    在这里插入图片描述
    但由于内容比较多,笔者打算分为两篇进行介绍,首先在这一篇中,介绍qt控件的继承以及在界面中把控件提升(promete)为自定义的控件。在下一篇中,介绍如何把对树的操作写入数据库以及如何在初始化过程中从数据库读取树结构。

    具体实现

    控件类的定义

    首先,自定义的控件要继承自QTreeWidget,然后需要添加一些增加根节点,删除节点,增加目录,增加模板,重命名节点等想要实现功能的槽函数,这些槽函数会在后面右击菜单中调用。右击菜单在qt中是一个action,需要定义几个QAction变量。initTreeWidget()函数在程序启动时从数据库读取树形结构,但是本文只介绍控件的自定义相关内容,这个函数中会生成一个固定的树。

    class QMyTreeWidget : public QTreeWidget
    {
        Q_OBJECT
    public:
        explicit QMyTreeWidget(QWidget *parent = 0);
    
    private slots:
        void on_treeWidget_customContextMenuRequested(const QPoint &pos);
        void addRootNode();
        void deleteAllNodes();
        void addCategory();
        void addTemplate();
    
        void deleteNode();
        void reNameNode();
    
    private:
    
        void initTreeWidget();
    
        QTreeWidgetItem* curItem;  //当前被右击的item
        //空白地方点击
        QAction *addRootNodeAction;
        QAction *deleteAllNodesAction;
    
        //节点上点击
        QAction *addCategoryAction;
        QAction *addTemplateAction;
        QAction *deleteNodeAction;
        QAction *reNameNodeAction;
    
    };
    

    action和槽函数连接

    addRootNodeAction = new QAction("&addRootNode", this);
    deleteAllNodesAction = new QAction("&deleteAllNodes", this);
    
    addCategoryAction = new QAction("&addCategory", this);
    addTemplateAction = new QAction("&addTemplate", this);
    
    deleteNodeAction = new QAction("&deleteNode", this);
    reNameNodeAction = new QAction("&reNameNode", this);
    
    connect(addRootNodeAction,SIGNAL(triggered()),this,SLOT(addRootNode()));
    connect(deleteAllNodesAction,SIGNAL(triggered()),this,SLOT(deleteAllNodes()));
    
    connect(addCategoryAction,SIGNAL(triggered()),this,SLOT(addCategory()));
    connect(addTemplateAction,SIGNAL(triggered()),this,SLOT(addTemplate()));
    
    connect(deleteNodeAction,SIGNAL(triggered()),this,SLOT(deleteNode()));
    connect(reNameNodeAction,SIGNAL(triggered()),this,SLOT(reNameNode()));
    

    右击菜单实现

    首先,需要把控件的contextMenuPolicy选项设为CustomContextMenu
    然后把右击菜单动作和槽函数连接起来

    connect(this,SIGNAL(customContextMenuRequested(QPoint)),this,SLOT(on_treeWidget_customContextMenuRequested(QPoint)));
    

    在槽函数中实现不同位置点击弹出不同的菜单

    void QMyTreeWidget::on_treeWidget_customContextMenuRequested(const QPoint &pos)
    {
        curItem=this->itemAt(pos);  //获取当前被点击的节点
    
        //在空白位置点击,弹出菜单:添加根节点,删除所有模板。
        if(curItem == NULL)
        {
            QMenu *popMenu =new QMenu(this);//定义一个右键弹出菜单
            popMenu->addAction(addRootNodeAction);
            popMenu->addAction(deleteAllNodesAction);
            popMenu->exec(QCursor::pos());
        }
        else{
            QVariant var = curItem->data(0,Qt::UserRole);
            qDebug() << var.toString() << endl;
            //读取表,对isCategory字段进行判断
            if(1)   //选中目录
            {
                qDebug() << "category" << endl;
                QMenu *popMenu =new QMenu(this);//定义一个右键弹出菜单
                popMenu->addAction(addCategoryAction);
                popMenu->addAction(addTemplateAction);
                popMenu->addAction(deleteNodeAction);
                popMenu->addAction(reNameNodeAction);
                popMenu->exec(QCursor::pos());
            }
            else     //选中模板
            {
                qDebug() << "template" << endl;
                QMenu *popMenu =new QMenu(this);//定义一个右键弹出菜单
                popMenu->addAction(deleteNodeAction);
                popMenu->addAction(reNameNodeAction);
                popMenu->exec(QCursor::pos());
            }
        }
    }
    

    槽函数实现过程

    重命名节点:

    void QMyTreeWidget::reNameNode()
    {
        qDebug() << "reNameNode" << endl;
    
        QInputDialog dia(this);
        dia.setWindowTitle("Input Dialog");
        dia.setLabelText("Please input text:");
        dia.setInputMode(QInputDialog::TextInput);//可选参数:DoubleInput  TextInput
    
        if(dia.exec() == QInputDialog::Accepted)
        {
           qDebug() << dia.textValue();
           curItem->setText(0,dia.textValue());
    
           //更新数据库
           //curTtem->data   dia.textValue()
        }
    }
    

    删除节点:

    void QMyTreeWidget::deleteNode()
    {
        qDebug() << "deleteNode" << endl;
        //curItem->data()  当前UUID  删除该索引
    
        QTreeWidgetItem* parent = curItem->parent();
        if(parent == NULL)
        {
            //得到索引
            int index = 0;
            int count = this->topLevelItemCount();
            for(int i = 0;i<count;i++)
            {
                //QTreeWidget
                //ui->treeWidget->TopLevelItem()
                QTreeWidgetItem* temp = this->topLevelItem(i);
                if(curItem->data(0,Qt::UserRole).toString() == temp->data(0,Qt::UserRole).toString())
                {
                    index = i;
                }
            }
            this->takeTopLevelItem(index);
        }
        else
            parent->removeChild(curItem);
    
        //删除数据库一行
        //curTtem->data
    }
    

    增加一个叶节点,该节点下不能再添加节点

    void QMyTreeWidget::addTemplate()
    {
        qDebug() << "addTemplate" << endl;
        //新节点ID     根       模板名称  颜色值    是否目录
        //随机UUID  当前UUID   title   colors      0
        //curItem->data()  当前UUID
        QTreeWidgetItem *temp=new QTreeWidgetItem(curItem);
    
        QInputDialog dia(this);
        dia.setWindowTitle("Input Dialog");
        dia.setLabelText("Please input text:");
        dia.setInputMode(QInputDialog::TextInput);//可选参数:DoubleInput  TextInput
    
        if(dia.exec() == QInputDialog::Accepted)
        {
           qDebug() << dia.textValue();
           temp->setText(0,dia.textValue());
    
           QVariant var;
           QString str = QUuid::createUuid().toString();
           var.setValue(str);
           temp->setData(0,Qt::UserRole,var);
        }
    }
    

    添加一个目录,该节点可以有子节点

    void QMyTreeWidget::addCategory()
    {
        qDebug() << "addCategory" << endl;
        //在TEMPLATE表中新加一行
        //新节点ID     根       模板名称  颜色值     是否目录
        //随机UUID  当前UUID   title   colors       1
        //curItem->data()  当前UUID
    
        QTreeWidgetItem *temp=new QTreeWidgetItem(curItem);
    
        QInputDialog dia(this);
        dia.setWindowTitle("Input Dialog");
        dia.setLabelText("Please input text:");
        dia.setInputMode(QInputDialog::TextInput);//可选参数:DoubleInput  TextInput
    
        if(dia.exec() == QInputDialog::Accepted)
        {
           qDebug() << dia.textValue();
           temp->setText(0,dia.textValue());
    
           QVariant var;
           QString str = QUuid::createUuid().toString();
           var.setValue(str);
           temp->setData(0,Qt::UserRole,var);
    	   
    	   //数据库添加一行
    	   //UUID: str    Title:dia.textValue()
        }
    }
    
    

    删除所有节点:

    void QMyTreeWidget::deleteAllNodes()
    {
        qDebug() << "deleteAllNodes" << endl;
    	this->clear();
        //清空数据库表
     
    }
    

    添加根节点,在整个树为空时,在任意位置点击可以选择

    void QMyTreeWidget::addRootNode()
    {
        qDebug() << "addRootNode" << endl;
        //在TEMPLATE表中新加一行
        //新节点ID   根   模板名称  颜色值    是否目录
        //随机UUID  -1   title   colors     1
        QTreeWidgetItem *temp=new QTreeWidgetItem(this);
    
        QInputDialog dia(this);
        dia.setWindowTitle("Input Dialog");
        dia.setLabelText("Please input text:");
        dia.setInputMode(QInputDialog::TextInput);//可选参数:DoubleInput  TextInput
    
        if(dia.exec() == QInputDialog::Accepted)
        {
           qDebug() << dia.textValue();
           temp->setText(0,dia.textValue());
    
           QVariant var;
           QString str = QUuid::createUuid().toString();
           var.setValue(str);
           temp->setData(0,Qt::UserRole,var);
        }
    }
    

    初始化一个固定的树

    void QMyTreeWidget::initTreeWidget()
    {
        //初始化时从数据库读取当前树结构,需要使用递归的方法
    
        //initTreeWidget() 的实现
        this->clear();
        //ui->treeWidget->clear();
        this->setHeaderHidden(true);
        //ui->treeWidget->setHeaderHidden(true);
        //第一组
        QTreeWidgetItem *group1=new QTreeWidgetItem(this);
        group1->setText(0,"group1");
        QVariant var;
        QString str = QUuid::createUuid().toString();
        var.setValue(str);
        group1->setData(0,Qt::UserRole,var);
    
    
        QTreeWidgetItem *item11=new QTreeWidgetItem(group1);
        item11->setText(0,"item11");
        QTreeWidgetItem *newnew=new QTreeWidgetItem(item11);
        newnew->setText(0,"newnew");
    
        QTreeWidgetItem *item12=new QTreeWidgetItem(group1);
        item12->setText(0,"item12");
        QTreeWidgetItem *item13=new QTreeWidgetItem(group1);
        item13->setText(0,"item13");
    
        //第二组
        QTreeWidgetItem *group2=new QTreeWidgetItem(this);
        group2->setText(0,"group2");
    
        QTreeWidgetItem *item21=new QTreeWidgetItem(group2);
        item21->setText(0,"item21");
    
        QTreeWidgetItem *item22=new QTreeWidgetItem(group2);
        item22->setText(0,"item22");
    
        QTreeWidgetItem *item23=new QTreeWidgetItem(group2);
        item23->setText(0,"item23");
        item23->setFlags(Qt::ItemIsUserCheckable|Qt::ItemIsEnabled|Qt::ItemIsSelectable);
        item23->setCheckState(0,Qt::Unchecked);
    }
    

    至此,控件的自定义已经完成。这个demo可以实现右键操作,并且控件结构随之变化。但是在程序重新启动后,上次更改过的内容全部丢失。要解决问题,需要用数据库保存树结构。这将在下一篇中进行介绍。预知后事如何,请听下回分解。

    展开全文
  • 【Vue】自定义树控件

    千次阅读 2019-05-09 20:36:21
    /*自定义树控件的核心就是“组件自己调用自己” 这里将树形控件封装成一个子组件*/ <div :style="indent" @click="toggleChildren"> //toggleChildren事件为“展开内容”、“关闭内容”的控制事件 /* ...

    效果图:
    在这里插入图片描述
    数据结构:

          tree: {
            title: '', //  标题(姓名) 
            key: '0',
            head: '', // 头像
            selectStatus: false, // checkBox选中状态
            children: [
              {
                title: '旺旺一部',
                key: '0-0',
                head: '',
                selectStatus: false,
                children: [
                  {
                    key: '0-0-0',
                    title: '旺仔1',
                    head: require('@/assets/wan.jpg'),
                    selectStatus: false
                  }
                ]
              },
              {
                title: '旺旺二部',
                key: '0-1',
                head: '',
                selectStatus: false,
                children: [
                  {
                    title: '旺旺二部一队',
                    key: '0-1-0',
                    head: '',
                    selectStatus: false,
                    children: [
                      {
                        title: '旺旺二部一队一班',
                        key: '0-1-0-2',
                        head: '',
                        selectStatus: false,
                        children: [
                          {
                            title: '旺仔3',
                            key: '0-1-0-2-0',
                            head: require('@/assets/wan.jpg'),
                            selectStatus: false
                          }
                        ]
                      }
                    ]
                  }
                ]
              }
            ]
          },
    

    思路:

    /*自定义树形控件的核心就是“组件自己调用自己”  这里将树形控件封装成一个子组件*/
    <template>
      <div>
        <div class="tree-custom">
          <div :style="indent" @click="toggleChildren"> //toggleChildren事件为“展开内容”、“关闭内容”的控制事件  
          	/* 
          	这里是递归数据显示的具体内容    
          	例如:本项目递归的具体内容从效果图上看就是“图片/头像”、“标题/名字”、“null/CheckBox”
          	效果图显示逻辑是:
          	<div v-if="!headImg && label" >
          	//如果没有头像图片有标题,则显示 “箭头-标题”样式
            </div>
            <div v-if="headImg">
          	//如果有头像图片,则显示 “头像-姓名-checkBox”样式
            </div>
          	*/			   
          </div>
          <tree-custom  // “自己调用自己”
            :key="children.key"  // key值唯一 
            v-for="children in treeData"  
            v-if="showChildren"  //  根据 toggleChildren事件 判断是否展开内容
            :treeData="children.children"   //  下面都是一些属性,应该都能看懂吧!不多说了!
            :label="children.title"
            :headImg="children.head"
            :pkid="children.key"
            :depth="depth+1"  //  这个是用来控制每行缩进的样式,可移步下方=>indent ()看具体用处
            :selectStatus="children.selectStatus"
            v-bind="$attrs"  //  这两个是用来实现祖孙组件通信的
            v-on="$listeners"
          >
          </tree-custom>
        </div>
      </div>
    </template>
    <script>
    export default {
      name: 'TreeCustom', // 要给我们的组件一个名字!不然怎么调用呢
      data () {
        return {
          showChildren: true,  // 这个就是控制是否显示内容的data~也就是展开和收起!
          currentInfoData: {} // 这个的用处是获取当前行的数据,为了简洁在上方代码的具体用处已经被我删掉了~意义不大
        }
      },
      //对象的默认值应由一个工厂函数返回,避免采坑
      props: {
        treeData: {
          type: Array,
          default: () => []
        },
        label: {
          type: String,
          default: () => ''
        },
        depth: {
          type: Number,
          default: () => 0
        },
        headImg: {
          type: String,
          default: () => ''
        },
        pkid: {
          type: String,
          default: () => ''
        },
        selectStatus: {
          type: Boolean,
          default: () => null
        }
      },
      computed: {
        indent () {  // 定义不同层级的缩进样式
          return { transform: `translate(${(this.depth - 1) * 15}px)` }
        }
      },
      methods: {
        toggleChildren () {
          this.showChildren = !this.showChildren
        },
        checkBoxSelectChange (e) {
          const checked = e.target.checked
          if (checked) {
           //使用$listeners方法调用祖辈的函数,因为这边是递归组件所以组件之间可能并不是严格的父子关系,所以$emit、$parent等方法都是不合适的
            this.$listeners.addSelectedData(this.currentInfoData)
          }
          if (!checked) {
            this.$listeners.deleteSelectedData(this.currentInfoData)
          }
        },
        getCurrentInfo (label, headImg, pkid) {
          this.currentInfoData = {
            key: pkid,
            title: label,
            head: headImg
          }
        }
      }
    }
    </script>
    
    /*组件调用方法*/
    <div class="tree-scroll">
      <tree-custom
        :label="tree.title"
        :headImg="tree.head"
        :treeData="tree.children"
        :pkid="tree.key"
        :depth="0"
        :selectStatus="tree.selectStatus"
        @addSelectedData="addSelectedData"
        @deleteSelectedData="deleteSelectedData" />
    </div>
    
    展开全文
  • 在Ext官方的例子中只有下拉列表控件,但是在实际业务中只有下拉列表无法满足需求的,对于刚使用Ext的人来说,自定义一个控件好难,下面是具体的实现
  • 自定义Flutter控件

    千次阅读 2018-01-31 14:48:33
    在Flutter开发中,我们...因此,我们可以把那些需要多个控件组合才能实现的功能自定义化,成为一个自定义控件,易于维护。 无状态控件 Flutter框架给我们提供了StatelessWidget和StatefulWidget两个抽象类,用于
  • 著名的自定义表格控件gridctrl使用实例;国外开源自定义控件; 广泛应用于mfc项目;轻量级表格控件,使用很方便快捷;
  • 接上篇,控件的数据库操作
  • Tmytreeview 对treeview控件加强 实现增删改及拖拽操作 实现对数据库存取操作
  • 控件,双击可以修改名字,可以对节点进行复选,快速删除,能显示节点详细信息,类似于资源管理器的样式。
  • VC2010使用自定义树列表视图控件示例代码,自己写的,有待完善。
  • 对CTreeCtrl进行继承,添加了自定义滚动条样式,背景图片,鼠标经过子项样式,对展开时+-图标进行自定义,并保持了对原有功能的完全继承,其中很多资源参考网络
  • 一个CTreeCtrl派生的类,它们都是:一个普通的CTreeCtrl或一个完全自定义的绘制垂直树控件
  • fuelux.tree 自定义属性控件-自定义图标+动态加载数据+添加点击事件。。。。。。。。。。。。。。。。
  • 牛的控件 自定义树形多级目录表单TREEVIEW TREEVIEW菜单栏自定义级别导航 自定义菜单栏 源代码
  • 1.开发环境 Qt版本:Qt 4.8.7 编译器:MinGw 系统:Windows 2.创建Qt4自定义控件 ...此时编译出来Release版本的自定义控件放进Designer目录下仅能在Designer中拖动,在使用该控件的工程中编译将会报错,所...
  • 对于多级的显示其实就是通过数据中各个节点的关系,通过不同的缩进来达到的效果。而数据中主要要把握id,父节点pId,name的关系,来显示其效果。实例详细的实现的多级和全选与反选的过程
  • Qt很好很强大,我很喜欢研究完hello Qt后,开始自己开发一个小东西,Tree控件,首先是Node类:node.h #ifndef NODE_H#define NODE_Hclass Node{public: enum Type{ Root, FileName }; Node(Type typ
  • 比如,我们想要一个TextBox控件,当鼠标点到TextBox控件中时,会在TextBox下面显示一个TreeView树控件,然后可以从TreeView控件中选择一个节点,节点的信息自动加载到TextBox中去,然后TreeView树会自动隐藏,当鼠标...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 35,913
精华内容 14,365
关键字:

自定义树控件