精华内容
下载资源
问答
  • 包括实现文件、基本配置文件、和简单的图片,使用Qt模型视图委托方法进行实现树状导航栏,重要地方都已经加了注释,可以看看我的博客里面介绍了实现
  • Qt QTreeWidget 树形结构实现(一)

    千次阅读 2012-08-01 15:12:17
    Qt中实现树形结构可以使用QTreeWidget类,也可以使用QTreeView类,QTreeWidget继承自QTreeView类。树形效果如下图所示: 这是怎么实现的呢?还有点击节点时会有相应的事件响应。 1. 树形结构实现 QT GUI中有...

    Qt中实现树形结构可以使用QTreeWidget类,也可以使用QTreeView类,QTreeWidget继承自QTreeView类。树形效果如下图所示:

    这是怎么实现的呢?还有点击节点时会有相应的事件响应。

    1. 树形结构实现

    QT GUI中有treeWidget部件,将该控件在Gui中布局好,假设其对象名为treeWidget。

    QTreeWidget类官方文档:http://qt-project.org/doc/qt-4.8/qtreewidget.html

    树形结构通过QTreeWidget类和QTreeWidgetItem类实现,QTreeWidgetItem类实现结点的添加。上图代码实现如下:

     

    按 Ctrl+C 复制代码
    按 Ctrl+C 复制代码

     

    当然,还有其他的一些方法用于设置,具体需要时查查帮助文档学习。

    除了使用上面这种方法之外,还可以使用QList<QTreeWidgetItem *> & items实现结点的添加。QT中对C++中的STL库中的容器使用进行了封装,使用其封装的类可以很方便的解决很多类似很复杂数据结构的问题。实现如下:

    复制代码
    //只写结点的实现
    QList<QTreeWidgetItem *> rootList;
    
    QTreeWidgetItem *imageItem1 = new QTreeWidgetItem;   //添加第一个父节点
    imageItem1->setText(0,tr("图像1"));
    rootList.append(imageItem1);
    
    QTreeWidgetItem *imageItem1_1 = new QTreeWidgetItem(imageItem1,QStringList(QString("Band1"))); //添加子节点
    imageItem1->addChild(imageItem1_1);
    
    QTreeWidgetItem *imageItem2 = new QTreeWidgetItem;   //添加第二个父节点
    imageItem2->setText(0,tr("图像2"));
    rootList.append(imageItem2);
    
    QTreeWidgetItem *imageItem2_1 = new QTreeWidgetItem(imageItem2,QStringList(QString("Band1")));  //添加子节点
    QTreeWidgetItem *imageItem2_2 = new QTreeWidgetItem(imageItem2,QStringList(QString("Band2")));
    imageItem2->addChild(imageItem2_1);
    imageItem2->addChild(imageItem2_2);
    
    ui->treeWidget->insertTopLevelItems(0,rootList);  //将结点插入部件中
    
    ui->treeWidget->expandAll(); //全部展开
    复制代码

    2. 点击节点的事件响应

    首先想到有没有点击某个节点的信号,查看文档,有一个void itemClicked ( QTreeWidgetItem * item, int column )信号,是双击某个节点的信号,将该信号与某个自定义槽相连,当双击节点时触发槽函数。

    看一下这个信号,第一个参数为点击的QTreeWidgetItem类对象,第二个参数为节点所在列号。

    思路:根据点击的QTreeWidgetItem类对象可以通过parent()函数得到父节点,如果QTreeWidgetItem类对象就是最最顶端的节点时,parent()函数返回的就是NULL。通过insertChildren ( int index, const QList<QTreeWidgetItem *> & children )函数可以得到该节点在父节点中的索引值

    目前只能解决只有一个最顶端父节点时的事件响应,当最顶端的父节点有多个(比如本文开头有2个),这时点击子节点时,无法判断子节点的父节点是哪一个(本人愚笨啊!),因此没法为其槽函数执行相应的操作。

    这里就以一个分支为例。

    复制代码
     1 private slots:
     2     void showSelectedImage(QTreeWidgetItem * item, int column); //点击树节点事件
     3 
     4 connect(ui->treeWidget,SIGNAL(itemDoubleClicked(QTreeWidgetItem*,int)),this,SLOT(showSelectedImage(QTreeWidgetItem*,int)));
     5 
     6 void MainWindow::showSelectedImage(QTreeWidgetItem *item, int column)
     7 {
     8     QTreeWidgetItem *parent = item->parent();
     9     if(NULL==parent) //注意:最顶端项是没有父节点的,双击这些项时注意(陷阱)
    10         return;
    11     int col = parent->indexOfChild(item); //item在父项中的节点行号(从0开始)
    12 
    13     if(0==col) //Band1
    14     {
    15         //执行对应操作
    16     }
    17     if(1==col) //Band2
    18     {
    19         //执行对应操作
    20     }
    21 }
    复制代码

    如果不加父节点是否为空的判断,当节点有父节点时,不会出错,当节点没有父节点时,程序会出错(运行错误),判断之后,双击没有父节点的节点就会是树的收缩操作。

     

    转载地址:http://www.cnblogs.com/Romi/archive/2012/04/16/2452709.html

    展开全文
  • 树状导航栏控件是所有控件中最牛逼最经典最厉害的一个,在很多购买者中,使用频率也是最高,因为该导航控件集合了非常多的展示效果,比如左侧图标+右侧箭头+元素前面的图标设置+各种颜色设置等,全部涵盖了,代码量...

    一、前言

    树状导航栏控件是所有控件中最牛逼最经典最厉害的一个,在很多购买者中,使用频率也是最高,因为该导航控件集合了非常多的展示效果,比如左侧图标+右侧箭头+元素前面的图标设置+各种颜色设置等,全部涵盖了,代码量也比较多,该控件前后完善了三年,还提供了角标展示文字信息,纵观市面上web也好,cs架构的程序也好,这种导航条使用非常多,目前只提供了二级菜单,如果需要三级菜单需要自行更改源码才行。

    二、实现的功能

    • 1:设置节点数据相当方便,按照对应格式填入即可,分隔符,
    • 2:可设置提示信息 是否显示+宽度
    • 3:可设置行分隔符 是否显示+高度+颜色
    • 4:可设置选中节点线条突出显示+颜色+左侧右侧位置
    • 5:可设置选中节点三角形突出显示+颜色+左侧右侧位置
    • 6:可设置父节点的 选中颜色+悬停颜色+默认颜色
    • 7:可设置子节点的 选中颜色+悬停颜色+默认颜色
    • 8:可设置父节点文字的 图标边距+左侧距离+字体大小+高度
    • 9:可设置子节点文字的 图标边距+左侧距离+字体大小+高度
    • 10:可设置节点展开模式 单击+双击+禁用

    三、效果图

    63094-20190809150520825-825751365.gif

    四、头文件代码

    #ifndef NAVLISTVIEW_H
    #define NAVLISTVIEW_H
    
    /**
     * 树状导航栏控件 作者:feiyangqingyun(QQ:517216493) 2018-8-15
     * 1:设置节点数据相当方便,按照对应格式填入即可,分隔符,
     * 2:可设置提示信息 是否显示+宽度
     * 3:可设置行分隔符 是否显示+高度+颜色
     * 4:可设置选中节点线条突出显示+颜色+左侧右侧位置
     * 5:可设置选中节点三角形突出显示+颜色+左侧右侧位置
     * 6:可设置父节点的 选中颜色+悬停颜色+默认颜色
     * 7:可设置子节点的 选中颜色+悬停颜色+默认颜色
     * 8:可设置父节点文字的 图标边距+左侧距离+字体大小+高度
     * 9:可设置子节点文字的 图标边距+左侧距离+字体大小+高度
     * 10:可设置节点展开模式 单击+双击+禁用
     */
    
    #include <QStyledItemDelegate>
    #include <QAbstractListModel>
    #include <QListView>
    #include <QStringList>
    
    class NavListView;
    
    class NavDelegate : public QStyledItemDelegate
    {
        Q_OBJECT
    public:
        NavDelegate(QObject *parent);
        ~NavDelegate();
    
    protected:
        QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const ;
        void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;
    
    private:
        NavListView *nav;
        QFont iconFont;
    };
    
    
    class NavModel : public QAbstractListModel
    {
        Q_OBJECT
    public:
        NavModel(QObject *parent);
        ~NavModel();
    
    public:
        struct TreeNode {
            int level;                  //层级,父节点-1,子节点-2
            bool expand;                //是否打开子节点
            bool last;                  //是否末尾元素
            QChar icon;                 //左侧图标
            QString text;               //显示的节点文字
            QString tip;                //右侧描述文字
            QString parentText;         //父节点名称
            QList<TreeNode *> children; //子节点集合
        };
    
        struct ListNode {
            QString text;               //节点文字
            TreeNode *treeNode;         //节点指针
        };
    
    protected:
        int rowCount(const QModelIndex &parent) const;
        QVariant data(const QModelIndex &index, int role) const;
    
    private:
        QList<TreeNode *> treeNode;
        QList<ListNode> listNode;
    
    public Q_SLOTS:
        void setItems(const QStringList &items);
        void expand(const QModelIndex &index);
    
    private:
        void refreshList();
    };
    
    #ifdef quc
    #if (QT_VERSION < QT_VERSION_CHECK(5,7,0))
    #include <QtDesigner/QDesignerExportWidget>
    #else
    #include <QtUiPlugin/QDesignerExportWidget>
    #endif
    
    class QDESIGNER_WIDGET_EXPORT NavListView : public QListView
    #else
    class NavListView : public QListView
    #endif
    
    {
        Q_OBJECT
        Q_ENUMS(ExpendMode)
    
        Q_PROPERTY(QString items READ getItems WRITE setItems)
        Q_PROPERTY(bool rightIconVisible READ getRightIconVisible WRITE setRightIconVisible)
        Q_PROPERTY(bool tipVisible READ getTipVisible WRITE setTipVisible)
        Q_PROPERTY(int tipWidth READ getTipWidth WRITE setTipWidth)
    
        Q_PROPERTY(bool separateVisible READ getSeparateVisible WRITE setSeparateVisible)
        Q_PROPERTY(int separateHeight READ getSeparateHeight WRITE setSeparateHeight)
        Q_PROPERTY(QColor separateColor READ getSeparateColor WRITE setSeparateColor)
    
        Q_PROPERTY(bool lineLeft READ getLineLeft WRITE setLineLeft)
        Q_PROPERTY(bool lineVisible READ getLineVisible WRITE setLineVisible)
        Q_PROPERTY(int lineWidth READ getLineWidth WRITE setLineWidth)
        Q_PROPERTY(QColor lineColor READ getLineColor WRITE setLineColor)
    
        Q_PROPERTY(bool triangleLeft READ getTriangleLeft WRITE setTriangleLeft)
        Q_PROPERTY(bool triangleVisible READ getTriangleVisible WRITE setTriangleVisible)
        Q_PROPERTY(int triangleWidth READ getTriangleWidth WRITE setTriangleWidth)
        Q_PROPERTY(QColor triangleColor READ getTriangleColor WRITE setTriangleColor)
    
        Q_PROPERTY(int parentIconMargin READ getParentIconMargin WRITE setParentIconMargin)
        Q_PROPERTY(int parentMargin READ getParentMargin WRITE setParentMargin)
        Q_PROPERTY(int parentFontSize READ getParentFontSize WRITE setParentFontSize)
        Q_PROPERTY(int parentHeight READ getParentHeight WRITE setParentHeight)
        Q_PROPERTY(QColor parentBgNormalColor READ getParentBgNormalColor WRITE setParentBgNormalColor)
        Q_PROPERTY(QColor parentBgSelectedColor READ getParentBgSelectedColor WRITE setParentBgSelectedColor)
        Q_PROPERTY(QColor parentBgHoverColor READ getParentBgHoverColor WRITE setParentBgHoverColor)
        Q_PROPERTY(QColor parentTextNormalColor READ getParentTextNormalColor WRITE setParentTextNormalColor)
        Q_PROPERTY(QColor parentTextSelectedColor READ getParentTextSelectedColor WRITE setParentTextSelectedColor)
        Q_PROPERTY(QColor parentTextHoverColor READ getParentTextHoverColor WRITE setParentTextHoverColor)
    
        Q_PROPERTY(int childIconMargin READ getChildIconMargin WRITE setChildIconMargin)
        Q_PROPERTY(int childMargin READ getChildMargin WRITE setChildMargin)
        Q_PROPERTY(int childFontSize READ getChildFontSize WRITE setChildFontSize)
        Q_PROPERTY(int childHeight READ getChildHeight WRITE setChildHeight)
        Q_PROPERTY(QColor childBgNormalColor READ getChildBgNormalColor WRITE setChildBgNormalColor)
        Q_PROPERTY(QColor childBgSelectedColor READ getChildBgSelectedColor WRITE setChildBgSelectedColor)
        Q_PROPERTY(QColor childBgHoverColor READ getChildBgHoverColor WRITE setChildBgHoverColor)
        Q_PROPERTY(QColor childTextNormalColor READ getChildTextNormalColor WRITE setChildTextNormalColor)
        Q_PROPERTY(QColor childTextSelectedColor READ getChildTextSelectedColor WRITE setChildTextSelectedColor)
        Q_PROPERTY(QColor childTextHoverColor READ getChildTextHoverColor WRITE setChildTextHoverColor)
    
        Q_PROPERTY(ExpendMode expendMode READ getExpendMode WRITE setExpendMode)
    
    public:
        //节点展开模式
        enum ExpendMode {
            ExpendMode_SingleClick = 0, //单击模式
            ExpendMode_DoubleClick = 1, //双击模式
            ExpendMode_NoClick = 2,     //不可单击双击
        };
    
        NavListView(QWidget *parent = 0);
        ~NavListView();
    
    private:
        NavModel *model;                //数据模型
        NavDelegate *delegate;          //数据委托
        QStringList parentItem;         //父节点数据集合
        QList<QStringList> childItem;   //子节点数据
    
        QString items;                  //节点集合
        bool rightIconVisible;          //右侧图标是否显示
        bool tipVisible;                //是否显示提示信息
        int tipWidth;                   //提示信息宽度
    
        bool separateVisible;           //是否显示行分隔符
        int separateHeight;             //行分隔符高度
        QColor separateColor;           //行分隔符颜色
    
        bool lineLeft;                  //是否显示在左侧
        bool lineVisible;               //是否显示线条
        int lineWidth;                  //线条宽度
        QColor lineColor;               //线条颜色
    
        bool triangleLeft;              //是否显示在左侧
        bool triangleVisible;           //是否显示三角形
        int triangleWidth;              //三角形宽度
        QColor triangleColor;           //三角形颜色
    
        int parentIconMargin;           //父节点图标边距
        int parentMargin;               //父节点边距
        int parentFontSize;             //父节点字体大小
        int parentHeight;               //父节点高度
        QColor parentBgNormalColor;     //父节点正常背景色
        QColor parentBgSelectedColor;   //父节点选中背景色
        QColor parentBgHoverColor;      //父节点悬停背景色
        QColor parentTextNormalColor;   //父节点正常文字颜色
        QColor parentTextSelectedColor; //父节点选中文字颜色
        QColor parentTextHoverColor;    //父节点悬停文字颜色
    
        int childIconMargin;            //子节点图标边距
        int childMargin;                //子节点边距
        int childFontSize;              //子节点字体大小
        int childHeight;                //子节点高度
        QColor childBgNormalColor;      //子节点正常背景色
        QColor childBgSelectedColor;    //子节点选中背景色
        QColor childBgHoverColor;       //子节点悬停背景色
        QColor childTextNormalColor;    //子节点正常文字颜色
        QColor childTextSelectedColor;  //子节点选中文字颜色
        QColor childTextHoverColor;     //子节点悬停文字颜色
    
        ExpendMode expendMode;          //节点展开模式 单击/双击/禁用
    
    private slots:
        void pressed(const QModelIndex &data);
        void setData(const QStringList &listItems);
    
    public:
        QString getItems()              const;
        bool getRightIconVisible()      const;
        bool getTipVisible()            const;
        int getTipWidth()               const;
    
        bool getSeparateVisible()       const;
        int getSeparateHeight()         const;
        QColor getSeparateColor()       const;
    
        bool getLineLeft()              const;
        bool getLineVisible()           const;
        int getLineWidth()              const;
        QColor getLineColor()           const;
    
        bool getTriangleLeft()          const;
        bool getTriangleVisible()       const;
        int getTriangleWidth()          const;
        QColor getTriangleColor()       const;
    
        int getParentIconMargin()       const;
        int getParentMargin()           const;
        int getParentFontSize()         const;
        int getParentHeight()           const;
        QColor getParentBgNormalColor() const;
        QColor getParentBgSelectedColor()const;
        QColor getParentBgHoverColor()  const;
        QColor getParentTextNormalColor()const;
        QColor getParentTextSelectedColor()const;
        QColor getParentTextHoverColor()const;
    
        int getChildIconMargin()        const;
        int getChildMargin()            const;
        int getChildFontSize()          const;
        int getChildHeight()            const;
        QColor getChildBgNormalColor()  const;
        QColor getChildBgSelectedColor()const;
        QColor getChildBgHoverColor()   const;
        QColor getChildTextNormalColor()const;
        QColor getChildTextSelectedColor()const;
        QColor getChildTextHoverColor() const;
    
        ExpendMode getExpendMode()      const;
    
        QSize sizeHint()                const;
        QSize minimumSizeHint()         const;
    
    public Q_SLOTS:
        //设置节点数据
        void setItems(const QString &items);
        //设置选中指定行
        void setCurrentRow(int row);
        //设置父节点右侧图标是否显示
        void setRightIconVisible(bool rightIconVisible);
    
        //设置提示信息 是否显示+宽度
        void setTipVisible(bool tipVisible);
        void setTipWidth(int tipWidth);
    
        //设置行分隔符 是否显示+高度+颜色
        void setSeparateVisible(bool separateVisible);
        void setSeparateHeight(int separateHeight);
        void setSeparateColor(const QColor &separateColor);
    
        //设置线条 位置+可见+宽度+颜色
        void setLineLeft(bool lineLeft);
        void setLineVisible(bool lineVisible);
        void setLineWidth(int lineWidth);
        void setLineColor(const QColor &lineColor);
    
        //设置三角形 位置+可见+宽度+颜色
        void setTriangleLeft(bool triangleLeft);
        void setTriangleVisible(bool triangleVisible);
        void setTriangleWidth(int triangleWidth);
        void setTriangleColor(const QColor &triangleColor);
    
        //设置父节点 图标边距+左侧边距+字体大小+节点高度+颜色集合
        void setParentIconMargin(int parentIconMargin);
        void setParentMargin(int parentMargin);
        void setParentFontSize(int parentFontSize);
        void setParentHeight(int parentHeight);
        void setParentBgNormalColor(const QColor &parentBgNormalColor);
        void setParentBgSelectedColor(const QColor &parentBgSelectedColor);
        void setParentBgHoverColor(const QColor &parentBgHoverColor);
        void setParentTextNormalColor(const QColor &parentTextNormalColor);
        void setParentTextSelectedColor(const QColor &parentTextSelectedColor);
        void setParentTextHoverColor(const QColor &parentTextHoverColor);
    
        //设置子节点 图标边距+左侧边距+字体大小+节点高度+颜色集合
        void setChildIconMargin(int childIconMargin);
        void setChildMargin(int childMargin);
        void setChildFontSize(int childFontSize);
        void setChildHeight(int childHeight);
        void setChildBgNormalColor(const QColor &childBgNormalColor);
        void setChildBgSelectedColor(const QColor &childBgSelectedColor);
        void setChildBgHoverColor(const QColor &childBgHoverColor);
        void setChildTextNormalColor(const QColor &childTextNormalColor);
        void setChildTextSelectedColor(const QColor &childTextSelectedColor);
        void setChildTextHoverColor(const QColor &childTextHoverColor);
    
        //设置节点展开模式
        void setExpendMode(const ExpendMode &expendMode);
    
    Q_SIGNALS:
        void pressed(const QString &text, const QString &parentText);
        void pressed(int index, int parentIndex);
        void pressed(int childIndex);
    };
    
    #endif // NAVLISTVIEW_H
    
    

    五、核心代码

    void NavDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
    {
        painter->setRenderHint(QPainter::Antialiasing);
        NavModel::TreeNode *node = (NavModel::TreeNode *)index.data(Qt::UserRole).toULongLong();
    
        //定义变量存储区域
        QRect optionRect = option.rect;
        int x = optionRect.x();
        int y = optionRect.y();
        int width = optionRect.width();
        int height = optionRect.height();
    
        int fontSize = nav->getParentFontSize();
    
        //父节点和子节点颜色分开设置
        bool parent = (node->level == 1);
    
        //根据不同的状态设置不同的颜色 bgColor-主背景色 textColor-主文字颜色 tipBgColor-提示信息背景颜色 tipTextColor-提示信息文字颜色
        QColor bgColor, textColor, tipBgColor, tipTextColor, iconColor;
        if (option.state & QStyle::State_Selected) {
            bgColor = parent ? nav->getParentBgSelectedColor() : nav->getChildBgSelectedColor();
            textColor = parent ? nav->getParentTextSelectedColor() : nav->getChildTextSelectedColor();
            tipBgColor = parent ? nav->getParentTextSelectedColor() : nav->getChildTextSelectedColor();
            tipTextColor = parent ? nav->getParentBgSelectedColor() : nav->getChildBgSelectedColor();
            iconColor = parent ? nav->getParentTextSelectedColor() : nav->getChildTextSelectedColor();
        } else if (option.state & QStyle::State_MouseOver) {
            bgColor = parent ? nav->getParentBgHoverColor() : nav->getChildBgHoverColor();
            textColor = parent ? nav->getParentTextHoverColor() : nav->getChildTextHoverColor();
            tipBgColor = parent ? nav->getParentTextSelectedColor() : nav->getChildTextSelectedColor();
            tipTextColor = parent ? nav->getParentBgSelectedColor() : nav->getChildBgSelectedColor();
            iconColor = parent ? nav->getParentTextHoverColor() : nav->getChildTextHoverColor();
        } else {
            bgColor = parent ? nav->getParentBgNormalColor() : nav->getChildBgNormalColor();
            textColor = parent ? nav->getParentTextNormalColor() : nav->getChildTextNormalColor();
            tipBgColor = parent ? nav->getParentBgSelectedColor() : nav->getChildBgSelectedColor();
            tipTextColor = parent ? nav->getParentTextSelectedColor() : nav->getChildTextSelectedColor();
            iconColor = parent ? nav->getParentTextNormalColor() : nav->getChildTextNormalColor();
        }
    
        //绘制背景
        painter->fillRect(optionRect, bgColor);
    
        //绘制线条,目前限定子节点绘制,如果需要父节点也绘制则取消parent判断即可
        int lineWidth = nav->getLineWidth();
        if (!parent && nav->getLineVisible() && lineWidth > 0) {
            if ((option.state & QStyle::State_Selected) || (option.state & QStyle::State_MouseOver)) {
                //设置偏移量,不然上下部分会有点偏移
                float offset = (float)lineWidth / 2;
    
                //计算上下两个坐标点
                QPointF pointTop(x, y + offset);
                QPointF pointBottom(x, height + y - offset);
                if (!nav->getLineLeft()) {
                    pointTop.setX(width);
                    pointBottom.setX(width);
                }
    
                //设置线条颜色和宽度
                painter->setPen(QPen(nav->getLineColor(), lineWidth));
                painter->drawLine(pointTop, pointBottom);
            }
        }
    
        //绘制三角形,目前限定子节点绘制,如果需要父节点也绘制则取消parent判断即可
        int triangleWidth = nav->getTriangleWidth();
        if (!parent && nav->getTriangleVisible() && triangleWidth > 0) {
            if ((option.state & QStyle::State_Selected) || (option.state & QStyle::State_MouseOver)) {
                QFont font = iconFont;
                font.setPixelSize(fontSize + triangleWidth);
                painter->setFont(font);
                painter->setPen(nav->getTriangleColor());
    
                //采用图形字体中的三角形绘制
                if (nav->getTriangleLeft()) {
                    painter->drawText(optionRect, Qt::AlignLeft | Qt::AlignVCenter, QChar(0xf0da));
                } else {
                    painter->drawText(optionRect, Qt::AlignRight | Qt::AlignVCenter, QChar(0xf0d9));
                }
            }
        }
    
        //绘制行分隔符
        if (nav->getSeparateVisible()) {
            if (node->level == 1 || (node->level == 2 && node->last)) {
                painter->setPen(QPen(nav->getSeparateColor(), nav->getSeparateHeight()));
                painter->drawLine(QPointF(x, y + height), QPointF(x + width, y + height));
            }
        }
    
        //绘制文字,如果文字为空则不绘制
        QString text = node->text;
        if (!text.isEmpty()) {
            //文字离左边的距离+字体大小
            int margin = nav->getParentMargin();
            if (node->level == 2) {
                margin = nav->getChildMargin();
                fontSize = nav->getChildFontSize();
            }
    
            //计算文字区域
            QRect textRect = optionRect;
            textRect.setWidth(width - margin);
            textRect.setX(x + margin);
    
            QFont font;
            font.setPixelSize(fontSize);
            painter->setFont(font);
            painter->setPen(textColor);
            painter->drawText(textRect, Qt::AlignLeft | Qt::AlignVCenter, text);
        }
    
        //绘制提示信息,如果不需要显示提示信息或者提示信息为空则不绘制
        QString tip = node->tip;
        if (nav->getTipVisible() && !tip.isEmpty()) {
            //如果是数字则将超过999的数字显示成 999+
            //如果显示的提示信息长度过长则将多余显示成省略号 .
            if (tip.toInt() > 0) {
                tip = tip.toInt() > 999 ? "999+" : tip;
            } else if (tip.length() > 2) {
                tip = tip.left(2) + " .";
            }
    
            //计算绘制区域,半径取高度的四分之一
            int radius = height / 4;
            QRect tipRect = optionRect;
            tipRect.setHeight(radius * 2);
            tipRect.moveCenter(optionRect.center());
            tipRect.setLeft(optionRect.right() - nav->getTipWidth() - 5);
            tipRect.setRight(optionRect.right() - 5);
    
            //设置字体大小
            QFont font;
            font.setPixelSize(fontSize - 2);
            painter->setFont(font);
    
            //绘制提示文字的背景
            painter->setPen(Qt::NoPen);
            painter->setBrush(tipBgColor);
            painter->drawRoundedRect(tipRect, radius, radius);
    
            //绘制提示文字
            painter->setPen(tipTextColor);
            painter->setBrush(Qt::NoBrush);
            painter->drawText(tipRect, Qt::AlignCenter, tip);
        }
    
        //计算绘制图标区域
        QRect iconRect = optionRect;
        iconRect.setLeft(parent ? nav->getParentIconMargin() : nav->getChildIconMargin());
    
        //设置图形字体和画笔颜色
        QFont font = iconFont;
        font.setPixelSize(fontSize);
        painter->setFont(font);
        painter->setPen(textColor);
    
        //绘制左侧图标,有图标则绘制图标,没有的话父窗体取 + -
        if (!node->icon.isNull()) {
            painter->drawText(iconRect, Qt::AlignLeft | Qt::AlignVCenter, node->icon);
        } else if (parent) {
            if (node->expand) {
                painter->drawText(iconRect, Qt::AlignLeft | Qt::AlignVCenter, QChar(0xf067));
            } else {
                painter->drawText(iconRect, Qt::AlignLeft | Qt::AlignVCenter, QChar(0xf068));
            }
        }
    
        //绘制父节点右侧图标
        iconRect.setRight(optionRect.width() - 10);
        if (!(nav->getTipVisible() && !node->tip.isEmpty()) && nav->getRightIconVisible() && parent) {
            if (node->expand) {
                painter->drawText(iconRect, Qt::AlignRight | Qt::AlignVCenter, QChar(0xf054));
            } else {
                painter->drawText(iconRect, Qt::AlignRight | Qt::AlignVCenter, QChar(0xf078));
            }
        }
    }
    

    六、控件介绍

    1. 超过150个精美控件,涵盖了各种仪表盘、进度条、进度球、指南针、曲线图、标尺、温度计、导航条、导航栏,flatui、高亮按钮、滑动选择器、农历等。远超qwt集成的控件数量。
    2. 每个类都可以独立成一个单独的控件,零耦合,每个控件一个头文件和一个实现文件,不依赖其他文件,方便单个控件以源码形式集成到项目中,较少代码量。qwt的控件类环环相扣,高度耦合,想要使用其中一个控件,必须包含所有的代码。
    3. 全部纯Qt编写,QWidget+QPainter绘制,支持Qt4.6到Qt5.12的任何Qt版本,支持mingw、msvc、gcc等编译器,支持任意操作系统比如windows+linux+mac+嵌入式linux等,不乱码,可直接集成到Qt Creator中,和自带的控件一样使用,大部分效果只要设置几个属性即可,极为方便。
    4. 每个控件都有一个对应的单独的包含该控件源码的DEMO,方便参考使用。同时还提供一个所有控件使用的集成的DEMO。
    5. 每个控件的源代码都有详细中文注释,都按照统一设计规范编写,方便学习自定义控件的编写。
    6. 每个控件默认配色和demo对应的配色都非常精美。
    7. 超过130个可见控件,6个不可见控件。
    8. 部分控件提供多种样式风格选择,多种指示器样式选择。
    9. 所有控件自适应窗体拉伸变化。
    10. 集成自定义控件属性设计器,支持拖曳设计,所见即所得,支持导入导出xml格式。
    11. 自带activex控件demo,所有控件可以直接运行在ie浏览器中。
    12. 集成fontawesome图形字体+阿里巴巴iconfont收藏的几百个图形字体,享受图形字体带来的乐趣。
    13. 所有控件最后生成一个dll动态库文件,可以直接集成到qtcreator中拖曳设计使用。
    14. 目前已经有qml版本,后期会考虑出pyqt版本,如果用户需求量很大的话。

    七、SDK下载

    • SDK下载链接:https://pan.baidu.com/s/1A5Gd77kExm8Co5ckT51vvQ 提取码:877p
    • 下载链接中包含了各个版本的动态库文件,所有控件的头文件,使用demo,自定义控件+属性设计器。
    • 自定义控件插件开放动态库dll使用(永久免费),无任何后门和限制,请放心使用。
    • 目前已提供26个版本的dll,其中包括了qt5.12.3 msvc2017 32+64 mingw 32+64 的。
    • 不定期增加控件和完善控件,不定期更新SDK,欢迎各位提出建议,谢谢!
    • widget版本(QQ:517216493)qml版本(QQ:373955953)三峰驼(QQ:278969898)。
    • 涛哥的知乎专栏 Qt进阶之路 https://zhuanlan.zhihu.com/TaoQt
    • 欢迎关注微信公众号【高效程序员】,C++/Python、学习方法、写作技巧、热门技术、职场发展等内容,干货多多,福利多多!
    • Qt入门书籍推荐霍亚飞的《Qt Creator快速入门》《Qt5编程入门》,Qt进阶书籍推荐官方的《C++ GUI Qt4编程》。
    • 强烈推荐程序员自我修养和规划系列书《大话程序员》《程序员的成长课》《解忧程序员》,受益匪浅,受益终生!

    转载于:https://www.cnblogs.com/feiyangqingyun/p/11327261.html

    展开全文
  • Qt使用的QTreeView对象实现树状链表简单显示。

    万次阅读 多人点赞 2018-08-11 16:19:47
    本人目的是为了实现一个显示网络数状拓扑结构图,简单的说就是实现树形结构链表,对比二叉树,我们知道二叉树中一个节点的最近子节点只有两个,一个左孩子和一个右孩子。但是本人的需求是每个节点都能有0个或0个以上...

    简言:

      本人并不专研Qt,只是写小项目时遇到问题和为了解决这个某个问题,特意学习了QTreeView的知识点。本人目的是为了实现一个显示网络数状拓扑结构图,简单的说就是实现树形结构链表,对比二叉树,我们知道二叉树中一个节点的最近子节点只有两个,一个左孩子和一个右孩子。但是本人的需求是每个节点都能有0个或0个以上的节点,故在寻找解决问题时偶然看到了QTreeView,因本人图形界面实现只学了Qt基础,所以选择用它。下图是本人写小项目的结果如下。

     学习心得:

    我们在Qt designer下拖入这个窗体Tree View

    接下来需要一个模型对象QStandardItemModel,初始化时要把该对象导入该TreeView窗体中,同时要把这个对象的头文件包含进来,例子如下:

    model = new QStandardItemModel(ui->treeView);//创建模型
    ui->treeView->setModel(model);//导入模型

    有时我们的需求会有每列都应该有个标签在头顶,实现方式如下:

    model->setHorizontalHeaderLabels(QStringList()<<QStringLiteral("项目名")<<QStringLiteral("相关信息1")<<QStringLiteral("相关信息2"));

    此时构建执行的效果:

    尝试在里面添加第一个条目,需要一个QStandardItem对象,实现代码如下:

    QStandardItem * item = new QStandardItem(tr("item one"));//创建一个条目对象
    model->appendRow(item);//通过模型对象添加这个条目

    效果如下:

    QStandardItemModel模型对象添加条目的函数也有另一种方式,函数原型是void QStandardItemModel::setItem(int row, int column, QStandardItem *item)或void QStandardItemModel::setItem(int row, QStandardItem *item)

    下面举例子从上面的代码添加测试代码如下:

    model->setItem(0,0,new QStandardItem(tr("item two")));
    model->setItem(2,0,new QStandardItem(tr("item three")));

    结果会是如下:

    原来的item one 不见了,原因是前面的setItem(0,0,**),的位置恰好就是索引的第0行第0列,因此把item one 占用了,item three的索引是第3行第0列,故item two和item three中间会隔一行。

    如果想在item two 条目下再生成子条目,此时用的对象就不是model来添加而是子条目,而是用item two对象来添加子条目,函数也是appendRow,也可以用setChild函数。由上面的实现,发现本人用的是匿名对象设置条目,比如我们想获取项目名为item two的条目对象,假设我们知道item two的行号为0行则可以model->item(0);获取该对象,然后该对象再添加子条目,实现例子如下:

    model->item(0)->appendRow(new QStandardItem(tr("item four")));

     效果如下:

    假设我们只知道有个item two的条目,却不知道行号,我们通过函数实现搜索到该对象,该函数原型是:

    QList<QStandardItem *> QStandardItemModel::findItems(const QString &text, Qt::MatchFlags flags = Qt::MatchExactly, int column = 0) 

    该函数的返回值是一个list链表,故我们可以通过遍历每个对象来获取它,因为我们上面的历程只有一个item two,故这个链表的长度为1.实现参考如下:

    QList<QStandardItem*> list = model->findItems(tr("item two"));
    for(int i = 0;i<list.length();i++)
    {
        qDebug() << tr("list has ").append(list.at(i)->text());//打印该条目的文本
    }

    效果在调试终端显示如下:

    如果要搜索到item four,由于它是条目的子条目,即item four是item two的子条目,所以调用的对象是条目对象而不是model对象。原理和model类似,QStandardItem对象常见的函数有:

    • QStandardItem *QStandardItem::child(int row, int column = 0) 返回子条目列中的某行或某行某列的一个条目,model的函数是Item。
    • bool QStandardItem::hasChildren() 判断返回是否有子条目,model的函数是hasItem
    • int QStandardItem::rowCount() 返回有多少个子条目
    • int QStandardItem::row() const返回该条目所在父条目的行号

    • QStandardItem *QStandardItem::parent() const返回父条目对象

     接下来如果想在item two后面第二列即相关信息1或相关信息2列那添加条目,综合上述的代码添加最下几行代码如下:

    model = new QStandardItemModel(ui->treeView);
    ui->treeView->setModel(model);
    model->setHorizontalHeaderLabels(QStringList()<<QStringLiteral("项目名")<<QStringLiteral("相关信息1")<<QStringLiteral("相关信息2"));
    QStandardItem * item = new QStandardItem(tr("item one"));
    model->appendRow(item);
    model->setItem(0,0,new QStandardItem(tr("item two")));
    model->setItem(2,0,new QStandardItem(tr("item three")));
    model->item(0)->appendRow(new QStandardItem(tr("item four")));
    QList<QStandardItem*> list = model->findItems(tr("item two"));
    /*以下是添加部分*/
    for(int i = 0;i<list.length();i++)//list.length在本历程中返回值是 1 ,故只遍历一次
    {
        //item变量指向这个Item two这个对象
        QStandardItem* item = list.at(i);
        /*参数1:item-row()是获取在上一级model或条目下自己所在的行号
          参数2: 1  是第1列,从第0列开始计数,故是相关信息1下的条目列
          参数3: 是创建一个对象,文本信息是item two msg*/
        model->setItem(item->row(),1,new QStandardItem(tr("item two msg")));
    }

    效果如下:

     若要在item four的的位置后面添加相关信息1,思路首先是获取item four这个条目对象,既然要获取item four这个对象,前提又要获取去item two这个条目对象,那如果不知item two的位置,因此用数据结构的思路写一个查询函数的代码,实现如下:

    QStandardItem *Widget::getItem(QStandardItemModel *model, QString s)
    {
        QStandardItem *getitem = NULL;
        if(!model->hasChildren())//判断是否有孩子,没有则返回0
            return NULL;
        QList<QStandardItem*> list = model->findItems(s);
        qDebug() << tr("list is %1").arg(list.length());
        if(list.length() == 0)//如果链表长度为0,即没找到文本为s的条目
        {
            //将搜索子条目是否存在文本为s的条目
            for(int i = 0;i < model->rowCount()&& getitem == NULL;i++)//遍历model下的所有条目,如果getitem有获得对象,则退出循环
            {
                getitem = getItem(model->item(i),s);//寻找第i行条目下的子条目列中是否存在文本为s的条目。
            }
        }
        else
        {
            return list.at(0);
        }
        return getitem;
    }
    
    QStandardItem *Widget::getItem(QStandardItem *item, QString s)
    {
        if(item == NULL)
            return NULL;
        qDebug() << tr("fine %1").arg(item->text());
        QStandardItem *getitem = NULL;
        if(item->text().compare(s) == 0)
            return item;
        if(!item->hasChildren())//判断是否有孩子,没有则返回0
            return NULL;
        for(int i = 0;i < item->rowCount() && getitem == NULL;i++)//遍历item下所有子条目,若果getitme有获得对象,则退出循环
        {
            QStandardItem * childitem = item->child(i);
            getitem = getItem(childitem,s);//寻找这个子条目的所有子条目是否存在文本为s的条目。
        }
        return getitem;
    }

    两个函数的关系是重载关系,参数不同,以实现递归查找,注意所有项目名条目中不能有两个或两个以上的相同的文本,不然以上函数只能返回其中一个最先找的文本为s的条目对象。如要找到多个s,则返回的对象应该是个链表,如有兴趣大家自己去实现吧。

    测试一下用例,代码如下:

    QStandardItem * getitem = getItem(model,tr("item four"));
    getitem->parent()->setChild(getitem->row(),1,new QStandardItem(tr("item four msg")));

    效果如下:

    分析结果该函数实现过程正常。 

    展开全文
  • Qt Designer中有很多UI界面组件,每种组件相对应有可设置的属性,本篇博文来让我们简单了解一下吧~
    展开全文
  • Qt QtreeWidget树形结构图表

    千次阅读 2017-10-17 13:22:42
    view->horizontalHeader()->setDefaultAlignment(Qt::AlignCenter); // view->show(); QTreeWidget *treewidget= new QTreeWidget ; //treewidget->setFixedWidth(300); //treewidget->...
  • qt快速界面设计

    千次阅读 2011-11-16 23:09:13
    ui文件我们可以用utrleditor(windows 下面)或者kwriter(linux)打开,其实里面就是一个xml格式的文件,这个文件中用树状结构描述了,整个界面的组织结构,每个界面元素的描述,大小,名字,位置等等。 用qmake来...
  • Qt Assistant 介绍

    万次阅读 多人点赞 2015-12-06 19:26:44
    Qt Assistant也就是我们常说的Qt助手,是一款用于呈现在线文档的工具。简介 一分钟学会使用 Qt参考文档 Qt Assistant详解 命令行选项 工具窗口 文档窗口 工具栏 菜单 文件菜单 编辑菜单 查看菜单 前往菜单 书签菜单 ...
  • Qt中实现树形结构可以使用QTreeWidget类,也可以使用QTreeView类,QTreeWidget继承自QTreeView类。树形效果如下图所示: 这是怎么实现的呢?还有点击节点时会有相应的事件响应。 1. 树形结构实现 QT ...
  • QT】QObject简介

    千次阅读 2017-08-16 19:33:26
    1、简介QObject类是所有Qt对象的基类,是Qt对象模型的核心,这个模型的主要特征为信号与槽,信号与槽是一个非常重要的机制,用于对象间的通信。连接信号与槽使用connect()函数,断开连接使用disconnect()函数,...
  • Qt综述

    千次阅读 2014-08-27 10:40:07
    Qt sf2gis@163.com 2014年8月1日创建 2014年8月17日 增加国际化内容 2014年8月27日QtCreator 添加工具条   1 总述 Qt程序为C++程序的基础上开发的。 以main开始。 Qt程序有一个唯一的代表本程序的类...
  • QT入门

    千次阅读 2011-10-02 20:21:42
    Qt学习之路(1):前言 Qt是一个著名的C++库——或许并不能说这只是一个GUI库,因为Qt十分庞大,并不仅仅是GUI。使用Qt,在一定程序上你获得的是一个“一站式”的 服务:不再需要研究STL,不再需要C++的,因为Qt有它...
  • 本系列面向 Python 小白,从零开始实战解说应用 QtDesigner 进行 PyQt5 的项目实战。 什么叫从零开始?从软件安装、环境配置开始。不跳过一个细节,不漏掉一行代码,不省略一个例图。 本节讲解:1. 安装 PyQt5 和 Qt...
  • 通过学习Qt自带的例子和帮助文档,简化了其中的一个例子,来学习如何自定义TreeView的Model。 以下是自定义一个只读的TreeView的Model,实际中可以直接...这是简单的树状结构,可以看出行的结构,但是缺乏列的信息。...
  • Qt Assistant介绍

    2017-05-26 09:30:53
    Qt Assistant也就是我们常说的Qt助手,是一款用于呈现在线文档的工具。 简介一分钟学会使用Qt参考文档Qt Assistant详解 命令行选项工具窗口文档窗口工具栏菜单 文件菜单编辑菜单查看菜单前往菜单...
  • QT性能总结

    千次阅读 2018-07-19 14:29:38
    这两年做过大大小小的任务,但客户端程序都是围绕QT进行的,windows上和MAC上都开发过,甚至做过nvr上的linux系统界面。抛开其他写的工具库、算法库,今天总结一下QT 的性能。以前在学校做项目时用过MFC,所以有必要...
  • QT5 仿360 11 设置界面, 可以直接拿到项目中使用,不错的代码
  • 读取输入文件3.1链接文件3.2读取表格3.3解析为树状结构4.输出文件4.1 拆分文件5.合并文件5.1 合并文件参考文章 1. 概述 这是一篇excel开发培训的示例教程。用考勤表作为示例进行演示: 如何创建QT界面, 如何衔接...
  • 那毕竟3dMax动画那边结课了,我怎么就不能再发一篇笔记(极其嚣张)QT其实会去好好学的,虽然最近为了选修结课又得恶补一波不过以后给策划造编辑器是要用的,这篇笔记以后系统去学习QT的时候会进行再更新(但应该是...
  • QT qt图形界面编程入门 目录说明 experiment 实验一 程序1.编写一个C++风格的程序,用动态分配空间的方法计算Fibonacci数列的前20项并存储到动态分配的空间中。 程序2.定义一个时间类Time,能提供和设置由时、...
  • 由于表格的结构和数据库存储类似,所以qt提供一个类来实现表格视图和数据库的直接连接。但是对于树形结构,在数据库中的表达和视图的表达有较大差异,qt尚未提供相关的功能。 本文的背景是要做一个模板的管理功能。...
  • 什么是树形浏览 ...像这种需要提升而来的QT控件,首先我们要拿到树形浏览的.cpp和.h头文件,可自行到官网下载,也可私信小编一键获取。把他们添加到我们的工程即可。 image文件主要是要里面的图标文件
  • 树部件(Tree Widget)是Qt Designer中 Item Widgets(Item-Based)部件中提供的一个Model/View便利部件,对应类为QTreeWidget类。 QTreeWidget类从QTreeView派生(继承关系请参考《PyQt学习随笔:Qt中Mod...
  • Qt Assistant也就是我们常说的Qt助手,是一款用于呈现在线文档的工具。 简介 一分钟学会使用 Qt参考文档 Qt Assistant详解 命令行选项 工具窗口 文档窗口 工具栏 菜单 文件菜单 编辑菜单 查看菜单 前往菜单 ...
  • 文章目录参考文献 本文为文献1的阅读笔记,主要记录自己不太熟悉的内容,补充知识盲区。个人对这个资料的初步印象不错,先学习一下。 参考文献 Qt5编程入门教程 ↩︎ ...

空空如也

空空如也

1 2 3 4
收藏数 69
精华内容 27
关键字:

qtdesigner树状结构