• Qt 使用 kdChart 自定义甘特图


      Qt绘制甘特图,网上找了很久,只找到kdChart,编译很简单,我是Qt 5.5.0 + VS2013,直接编译就行,kdChart有甘特图例子:

    但是和项目设计有点出入,所以自定义部分显示:

    1.左边的是QTreeView,并为其添加委托,控件变化主要是通过QStandardItem->setData()来区别,这没什么说的,主要记录修改颜色和获取甘特图item拖动事件

    (1).修改颜色(可实现每个item的颜色都不一样):

     这是设置每个item的颜色:

    topitem->setData(249, KDGantt::ItemColor_R);
    topitem->setData(171, KDGantt::ItemColor_G);
    topitem->setData(82, KDGantt::ItemColor_B);

    kdChart中,颜色的修改是:

    void ItemDelegate::paintGanttItem( QPainter* painter,
                                       const StyleOptionGanttItem& opt,
                                       const QModelIndex& idx )

    函数修改:

    void ItemDelegate::paintGanttItem( QPainter* painter,
                                       const StyleOptionGanttItem& opt,
                                       const QModelIndex& idx )
    {
        if ( !idx.isValid() ) return;
    
        const ItemType typ = static_cast<ItemType>( idx.model()->data( idx, ItemTypeRole ).toInt() );
        const QString& txt = opt.text;
        QRectF itemRect = opt.itemRect;
        QRectF boundingRect = opt.boundingRect;
        boundingRect.setY( itemRect.y() );
        boundingRect.setHeight( itemRect.height() );
        painter->save();
    
        int color_r = idx.model()->data( idx, ItemColor_R ).toInt();
        int color_g = idx.model()->data( idx, ItemColor_G ).toInt();
        int color_b = idx.model()->data( idx, ItemColor_B ).toInt();
    
        QColor itemColor(color_r, color_g, color_b);
    
        QPen pen(itemColor);
        if ( opt.state & QStyle::State_Selected ) pen.setWidth( 2*pen.width() );
        painter->setPen( pen );
        painter->setBrush( QBrush(Qt::white, Qt::Dense1Pattern) );
    
        bool drawText = true;
        qreal pw = painter->pen().width()/2.;
        switch ( typ ) {
        case TypeTask:
            if ( itemRect.isValid() ) {
                // TODO
                qreal pw = painter->pen().width()/2.;
                pw-=1;
                QRectF r = itemRect;
                r.translate( 0., r.height()/6. );
                r.setHeight( 2.*r.height()/3. );
                painter->setBrushOrigin( itemRect.topLeft() );
                painter->save();
                painter->translate( 0.5, 0.5 );
                painter->drawRect( r );
                bool ok;
                qreal completion = idx.model()->data( idx, KDGantt::TaskCompletionRole ).toReal( &ok );
                if ( ok ) {
                    qreal h = r.height();
                    QRectF cr( r.x(), r.y()+h/4.,
                               r.width()*completion/100., h/2.+1 /*??*/ );
                    QColor compcolor( painter->pen().color() );
                    compcolor.setAlpha( 150 );
                    painter->fillRect( cr, compcolor );
                }
                painter->restore();
            }
            break;
        case TypeSummary:
            if ( opt.itemRect.isValid() ) {
                // TODO
                pw-=1;
                const QRectF r = QRectF( opt.itemRect ).adjusted( -pw, -pw, pw, pw );
                QPainterPath path;
                const qreal deltaY = r.height()/2.;
                const qreal deltaXBezierControl = .25*qMin( r.width(), r.height() );
                const qreal deltaX = qMin( r.width()/2., r.height() );
                path.moveTo( r.topLeft() );
                path.lineTo( r.topRight() );
                path.lineTo( QPointF( r.right(), r.top() + 2.*deltaY ) );
                //path.lineTo( QPointF( r.right()-3./2.*delta, r.top() + delta ) );
                path.quadTo( QPointF( r.right()-deltaXBezierControl, r.top() + deltaY ), QPointF( r.right()-deltaX, r.top() + deltaY ) );
                //path.lineTo( QPointF( r.left()+3./2.*delta, r.top() + delta ) );
                path.lineTo( QPointF( r.left() + deltaX, r.top() + deltaY ) );
                path.quadTo( QPointF( r.left()+deltaXBezierControl, r.top() + deltaY ), QPointF( r.left(), r.top() + 2.*deltaY ) );
                path.closeSubpath();
                painter->setBrushOrigin( itemRect.topLeft() );
                painter->save();
                painter->translate( 0.5, 0.5 );
                painter->drawPath( path );
                painter->restore();
            }
            break;
        case TypeEvent: /* TODO */
            //qDebug() << opt.boundingRect << opt.itemRect;
            if ( opt.boundingRect.isValid() ) {
                const qreal pw = painter->pen().width() / 2. - 1;
                const QRectF r = QRectF( opt.itemRect ).adjusted( -pw, -pw, pw, pw ).translated( -opt.itemRect.height()/2, 0 );
                QPainterPath path;
                const qreal delta = static_cast< int >( r.height() / 2 );
                path.moveTo( delta, 0. );
                path.lineTo( 2.*delta, delta );
                path.lineTo( delta, 2.*delta );
                path.lineTo( 0., delta );
                path.closeSubpath();
                painter->save();
                painter->translate( r.topLeft() );
                painter->translate( 0, 0.5 );
                painter->drawPath( path );
                painter->restore();
    #if 0
                painter->setBrush( Qt::NoBrush );
                painter->setPen( Qt::black );
                painter->drawRect( opt.boundingRect );
                painter->setPen( Qt::red );
                painter->drawRect( r );
    #endif
            }
            break;
        default:
            drawText = false;
            break;
        }
    
        Qt::Alignment ta;
        switch ( opt.displayPosition ) {
            case StyleOptionGanttItem::Left: ta = Qt::AlignLeft; break;
            case StyleOptionGanttItem::Right: ta = Qt::AlignRight; break;
            case StyleOptionGanttItem::Center: ta = Qt::AlignCenter; break;
            case StyleOptionGanttItem::Hidden: drawText = false; break;
        }
        if ( drawText ) {
            painter->drawText( boundingRect, ta | Qt::AlignVCenter, txt );
        }
    
        painter->restore();
    }

    (2).拖动事件:

     在文件kdganttgraphicsview.h中添加信号

    void signal_dataChanged( const QModelIndex & index );
    void GraphicsView::Private::slotDataChanged( const QModelIndex& topLeft, const QModelIndex& bottomRight )
    {
        const QModelIndex parent = topLeft.parent();
        for ( int row = topLeft.row(); row <= bottomRight.row(); ++row ) {
            scene.updateRow( scene.summaryHandlingModel()->index( row, 0, parent ) );
        }
    
        emit q->signal_dataChanged(topLeft);
    }

    外部使用:

    connect(ui->ganttView->graphicsView(), SIGNAL(signal_dataChanged(const QModelIndex&)), this, SLOT(onCheckTask(const QModelIndex&)));

    修改显示的日期格式,效果:

    上面显示年月,下面显示多少号,显示号很简单:

    grid.setUserDefinedLowerScale(new KDGantt::DateTimeScaleFormatter(KDGantt::DateTimeScaleFormatter::Day,QString::fromLatin1("dd"),QString::fromLatin1("%1"),Qt::AlignHCenter));

    其中有个格式:QString::fromLatin1("dd"),dd:号, ddd:星期几

    使用这个函数,只能显示年或者月或者天,不能组合显示,所有重写DateTimeScaleFormatter;

    class MyDateTimeScaleFormatter : public KDGantt::DateTimeScaleFormatter 
    {
    public:
        MyDateTimeScaleFormatter() : DateTimeScaleFormatter(Month, "MM"){}
    
        /*reimp*/QDateTime nextRangeBegin(const QDateTime& datetime) const
        {
            return currentRangeBegin(datetime).addMonths(1);
        }
        /*reimp*/QDateTime currentRangeBegin(const QDateTime& datetime) const
        {
            return datetime;
        }
    
        /*reimp*/QString text(const QDateTime& dt) const
        {
            return QObject::tr("%1年%2月").arg(dt.date().year()).arg(dt.date().month());
        }
    };
    grid.setUserDefinedUpperScale(new MyDateTimeScaleFormatter()); // 显示在上面

    转载请保留出处!

  • 相关阅读:
    UNIX 环境模拟工具Cygwin安装及使用图文教程
    转转转!SpringMVC访问静态资源的三种方式
    转!!!解释Eclipse下Tomcat项目部署路径问题(.metadata.pluginsorg.eclipse.wst.server.core mp0wtpwebapps)
    JavaWeb中读取文件资源的路径问题 -- 转自新浪博客
    springMVC学习(10)-上传图片
    springMVC学习(9)-全局异常处理
    springMVC学习(8)-数据回显
    springMVC学习(7)-springMVC校验
    springMVC学习(6)-包装pojo类型、数组、list、Map类型参数绑定
    springMVC学习(5)-参数绑定
  • 原文地址:https://www.cnblogs.com/qnkk123/p/7685477.html
Copyright © 2020-2023  润新知