Qt kdChart 甘特图案例
KDChart 甘特图在Qt中的加载使用案例,代码来自官方
mainwindow.h
/****************************************************************************
** Copyright (C) 2001-2018 Klaralvdalens Datakonsult AB. All rights reserved.
**
** This file is part of the KD Chart library.
**
** Licensees holding valid commercial KD Chart licenses may use this file in
** accordance with the KD Chart Commercial License Agreement provided with
** the Software.
**
**
** This file may be distributed and/or modified under the terms of the
** GNU General Public License version 2 and version 3 as published by the
** Free Software Foundation and appearing in the file LICENSE.GPL.txt included.
**
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
**
** Contact info@kdab.com if any conditions of this licensing are not
** clear to you.
**
**********************************************************************/ #ifndef MAINWINDOW_H
#define MAINWINDOW_H #include <QItemSelection>
#include <QMainWindow> QT_BEGIN_NAMESPACE
class QStandardItemModel;
class QCloseEvent;
namespace Ui {
class MainWindow;
}
QT_END_NAMESPACE namespace KDGantt {
class ConstraintModel;
class DateTimeGrid;
class Legend;
} class MainWindow : public QMainWindow {
Q_OBJECT public:
explicit MainWindow( QWidget * parent = , Qt::WindowFlags flags = );
virtual ~MainWindow();
virtual void closeEvent(QCloseEvent *event); private slots:
void addNewEntry();
void removeEntry();
void showContextMenu( const QPoint& );
void enableActions( const QItemSelection& selected );
void zoomIn();
void zoomOut();
void zoomFit();
void scaleAuto();
void scaleHour();
void scaleDay();
void scaleWeek();
void scaleMonth(); private:
void initModel();
void initActions();
void initItemDelegate();
void initGrid(); void setReadOnly( const QModelIndex& index, bool readOnly );
void addConstraint( const QModelIndex& index1, const QModelIndex& index2 ); QStandardItemModel* model;
KDGantt::ConstraintModel* constraintModel;
KDGantt::DateTimeGrid* grid;
KDGantt::Legend* smallLegend;
KDGantt::Legend* detailedLegend; QAction* newEntryAction;
QAction* removeEntryAction;
QAction* zoomInAction;
QAction* zoomOutAction;
QAction* zoomFitAction; Ui::MainWindow* ui;
}; #endif /* MAINWINDOW_H */
entrydialog.h
/****************************************************************************
** Copyright (C) 2001-2018 Klaralvdalens Datakonsult AB. All rights reserved.
**
** This file is part of the KD Chart library.
**
** Licensees holding valid commercial KD Chart licenses may use this file in
** accordance with the KD Chart Commercial License Agreement provided with
** the Software.
**
**
** This file may be distributed and/or modified under the terms of the
** GNU General Public License version 2 and version 3 as published by the
** Free Software Foundation and appearing in the file LICENSE.GPL.txt included.
**
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
**
** Contact info@kdab.com if any conditions of this licensing are not
** clear to you.
**
**********************************************************************/ #ifndef ENTRYDIALOG_H
#define ENTRYDIALOG_H #include <QDateTime>
#include <QDialog>
#include <QModelIndex> QT_BEGIN_NAMESPACE
class QAbstractItemModel;
namespace Ui {
class EntryDialog;
}
QT_END_NAMESPACE namespace KDGantt {
class ConstraintModel;
} class EntryDialog : public QDialog {
Q_OBJECT public:
explicit EntryDialog( const QAbstractItemModel* model, QWidget* parent = , Qt::WindowFlags f = );
void initFrom( const QModelIndex& index, const KDGantt::ConstraintModel* constraintModel ); QString name() const;
int type() const;
QDateTime startDate() const;
QDateTime endDate() const;
int completion() const;
bool readOnly() const;
QModelIndex depends() const;
QString legend() const; private slots:
void updateEndDate( const QDateTime& startDate );
void disableEditing( bool disable );
void typeChanged( int index ); private:
void init();
void addDependItem( const QAbstractItemModel* model, const QModelIndex& index, int indent = ); QList<QPersistentModelIndex> indexList;
const QAbstractItemModel* model;
Ui::EntryDialog* ui;
}; #endif /* ENTRYDIALOG_H */
entrydelegate.h
/****************************************************************************
** Copyright (C) 2001-2018 Klaralvdalens Datakonsult AB. All rights reserved.
**
** This file is part of the KD Chart library.
**
** Licensees holding valid commercial KD Chart licenses may use this file in
** accordance with the KD Chart Commercial License Agreement provided with
** the Software.
**
**
** This file may be distributed and/or modified under the terms of the
** GNU General Public License version 2 and version 3 as published by the
** Free Software Foundation and appearing in the file LICENSE.GPL.txt included.
**
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
**
** Contact info@kdab.com if any conditions of this licensing are not
** clear to you.
**
**********************************************************************/ #ifndef ENTRYDELEGATE_H
#define ENTRYDELEGATE_H #include <QItemDelegate> namespace KDGantt {
class ConstraintModel;
} class EntryDelegate : public QItemDelegate {
public:
explicit EntryDelegate( KDGantt::ConstraintModel* constraintModel, QObject* parent = ); bool editorEvent( QEvent* event, QAbstractItemModel* model, const QStyleOptionViewItem& option, const QModelIndex& index ); private:
void addConstraint(const QModelIndex & index1, const QModelIndex & index2);
void setReadOnly(const QModelIndex & index, bool readOnly); KDGantt::ConstraintModel* constraintModel;
}; #endif /* ENTRYDELEGATE_H */
entrydelegate.cpp
/****************************************************************************
** Copyright (C) 2001-2018 Klaralvdalens Datakonsult AB. All rights reserved.
**
** This file is part of the KD Chart library.
**
** Licensees holding valid commercial KD Chart licenses may use this file in
** accordance with the KD Chart Commercial License Agreement provided with
** the Software.
**
**
** This file may be distributed and/or modified under the terms of the
** GNU General Public License version 2 and version 3 as published by the
** Free Software Foundation and appearing in the file LICENSE.GPL.txt included.
**
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
**
** Contact info@kdab.com if any conditions of this licensing are not
** clear to you.
**
**********************************************************************/ #include "entrydelegate.h" #include "entrydialog.h" #include <KDGanttConstraintModel>
#include <KDGanttGlobal>
#include <QEvent>
#include <QModelIndex>
#include <QStandardItemModel>
#include <QPointer> EntryDelegate::EntryDelegate( KDGantt::ConstraintModel* constraintModel, QObject* parent )
: QItemDelegate( parent )
{
this->constraintModel = constraintModel;
} bool EntryDelegate::editorEvent( QEvent* event, QAbstractItemModel *model, const QStyleOptionViewItem& option, const QModelIndex& index )
{
if ( event->type() != QEvent::MouseButtonDblClick )
return false; if ( !index.isValid() )
return QItemDelegate::editorEvent( event, model, option, index ); QPointer<EntryDialog> dialog = new EntryDialog( model );
dialog->initFrom( index, constraintModel );
dialog->setWindowTitle( tr( "Edit Entry" ) );
dialog->exec();
if ( !dialog )
return false; int row = index.row();
const QModelIndex parent = index.parent();
model->setData( model->index( row, , parent ), dialog->name() );
model->setData( model->index( row, , parent ), dialog->type() );
if ( dialog->type() != KDGantt::TypeSummary ) {
model->setData( model->index( row, , parent ), dialog->startDate(), KDGantt::StartTimeRole );
model->setData( model->index( row, , parent ), dialog->endDate(), KDGantt::EndTimeRole );
}
model->setData( model->index( row, , parent ), dialog->completion() );
model->setData( model->index( row, , parent ), dialog->legend() ); addConstraint( dialog->depends(), model->index( row, , parent ) );
setReadOnly( model->index( row, , parent ), dialog->readOnly() ); delete dialog;
return true;
} void EntryDelegate::setReadOnly(const QModelIndex & index, bool readOnly)
{
int row = index.row();
QModelIndex parent = index.parent();
QStandardItem* item;
const QStandardItemModel* model = qobject_cast<const QStandardItemModel*>( index.model() );
if ( !model )
return; item = model->itemFromIndex( model->index( row, , parent ) );
item->setFlags( readOnly ? item->flags() & ~Qt::ItemIsEditable : item->flags() | Qt::ItemIsEditable ); item = model->itemFromIndex( model->index( row, , parent ) );
item->setFlags( readOnly ? item->flags() & ~Qt::ItemIsEditable : item->flags() | Qt::ItemIsEditable ); item = model->itemFromIndex( model->index( row, , parent ) );
item->setFlags( readOnly ? item->flags() & ~Qt::ItemIsEditable : item->flags() | Qt::ItemIsEditable ); item = model->itemFromIndex( model->index( row, , parent ) );
item->setFlags( readOnly ? item->flags() & ~Qt::ItemIsEditable : item->flags() | Qt::ItemIsEditable ); item = model->itemFromIndex( model->index( row, , parent ) );
item->setFlags( readOnly ? item->flags() & ~Qt::ItemIsEditable : item->flags() | Qt::ItemIsEditable );
} void EntryDelegate::addConstraint(const QModelIndex & index1, const QModelIndex & index2)
{
if ( !index1.isValid() || !index2.isValid() )
return; KDGantt::Constraint c( index1, index2 );
constraintModel->addConstraint( c );
}
entrydialog.cpp
/****************************************************************************
** Copyright (C) 2001-2018 Klaralvdalens Datakonsult AB. All rights reserved.
**
** This file is part of the KD Chart library.
**
** Licensees holding valid commercial KD Chart licenses may use this file in
** accordance with the KD Chart Commercial License Agreement provided with
** the Software.
**
**
** This file may be distributed and/or modified under the terms of the
** GNU General Public License version 2 and version 3 as published by the
** Free Software Foundation and appearing in the file LICENSE.GPL.txt included.
**
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
**
** Contact info@kdab.com if any conditions of this licensing are not
** clear to you.
**
**********************************************************************/ #include "entrydialog.h" #include "ui_entrydialog.h" #include <KDGanttConstraintModel>
#include <KDGanttGlobal>
#include <QAbstractItemModel>
#include <QDateTime>
#include <QPersistentModelIndex> Q_DECLARE_METATYPE( QPersistentModelIndex ); EntryDialog::EntryDialog( const QAbstractItemModel* model, QWidget* parent, Qt::WindowFlags f )
: QDialog( parent, f ),
indexList( QList<QPersistentModelIndex>() ),
ui( new Ui::EntryDialog )
{
ui->setupUi( this );
this->model = model;
init();
} void EntryDialog::init()
{
ui->type->addItem( tr( "Event" ), KDGantt::TypeEvent );
ui->type->addItem( tr( "Task" ), KDGantt::TypeTask );
ui->type->addItem( tr( "Summary" ), KDGantt::TypeSummary );
ui->type->addItem( tr( "Multi" ), KDGantt::TypeMulti ); for (int row = ; row < model->rowCount(); ++row )
addDependItem( model, model->index( row, ) ); connect( ui->startDate, SIGNAL( dateTimeChanged( const QDateTime& ) ), this, SLOT( updateEndDate( const QDateTime& ) ) );
connect( ui->readOnly, SIGNAL( toggled( bool ) ), this, SLOT( disableEditing( bool ) ) );
connect( ui->type, SIGNAL( currentIndexChanged( int ) ), this, SLOT( typeChanged( int ) ) ); ui->startDate->setDateTime( QDateTime::currentDateTime() );
typeChanged( );
} void EntryDialog::initFrom( const QModelIndex & index, const KDGantt::ConstraintModel* constraintModel )
{
int row = index.row();
const QModelIndex parent = index.parent(); ui->name->setText( model->data( model->index( row, , parent ) ).toString() );
ui->legend->setText( model->data( model->index( row, , parent ) ).toString() );
int idx = ui->type->findData( model->data( model->index( row, , parent ) ).toInt() );
ui->type->setCurrentIndex( idx );
ui->startDate->setDateTime( model->data( model->index( row, , parent ), KDGantt::StartTimeRole ).toDateTime() );
ui->endDate->setDateTime( model->data( model->index( row, , parent ), KDGantt::EndTimeRole ).toDateTime() );
ui->completion->setValue( model->data( model->index( row, , parent ) ).toInt() );
ui->readOnly->setChecked( !(model->flags( model->index( row, , parent ) ) & Qt::ItemIsEditable) ); QList<KDGantt::Constraint> constraints = constraintModel->constraintsForIndex( model->index( row, , parent ) );
if ( constraints.isEmpty() )
return; QModelIndex constraintIndex;
for ( int i = ; i < constraints.size(); ++i ) {
KDGantt::Constraint constraint = constraints[i];
if ( constraint.endIndex() == index ) {
constraintIndex = constraint.startIndex();
break;
}
} if ( !constraintIndex.isValid() )
return; ui->depends->setCurrentIndex( indexList.indexOf( constraintIndex ) + );
} void EntryDialog::addDependItem( const QAbstractItemModel* model, const QModelIndex & index, int indent)
{
indexList << QPersistentModelIndex( index );
QString str = QString( "%1%2" ).arg( QString().fill( ' ', indent ) ).arg( model->data( index ).toString() );
ui->depends->addItem( str ); for (int row = ; row < model->rowCount( index ); ++row )
addDependItem( model, model->index( row, , index ), indent + );
} QString EntryDialog::name() const
{
return ui->name->text();
} int EntryDialog::type() const
{
return ui->type->itemData( ui->type->currentIndex() ).toInt();
} QDateTime EntryDialog::startDate() const
{
return ui->startDate->dateTime();
} QDateTime EntryDialog::endDate() const
{
return ui->endDate->dateTime();
} int EntryDialog::completion() const
{
return ui->completion->value();
} void EntryDialog::updateEndDate(const QDateTime & startDate)
{
ui->endDate->setMinimumDate( startDate.date() );
ui->endDate->setMinimumTime( startDate.time() );
} bool EntryDialog::readOnly() const
{
return ui->readOnly->isChecked();
} QModelIndex EntryDialog::depends() const
{
if ( ui->depends->currentIndex() == )
return QModelIndex(); QPersistentModelIndex index = indexList[ ui->depends->currentIndex() - ];
if ( index.isValid() )
return index; return QModelIndex();
} QString EntryDialog::legend() const
{
return ui->legend->text();
} void EntryDialog::disableEditing(bool disable)
{
ui->name->setEnabled( !disable );
ui->type->setEnabled( !disable );
ui->completion->setEnabled( !disable );
ui->startDate->setEnabled( !disable );
ui->endDate->setEnabled( !disable );
ui->depends->setEnabled( !disable );
} void EntryDialog::typeChanged(int index)
{
if ( ! index ) {
ui->label_EndDate->hide();
ui->endDate->hide();
} else {
ui->label_EndDate->show();
ui->endDate->show();
}
}
mainwindow.cpp
/****************************************************************************
** Copyright (C) 2001-2018 Klaralvdalens Datakonsult AB. All rights reserved.
**
** This file is part of the KD Chart library.
**
** Licensees holding valid commercial KD Chart licenses may use this file in
** accordance with the KD Chart Commercial License Agreement provided with
** the Software.
**
**
** This file may be distributed and/or modified under the terms of the
** GNU General Public License version 2 and version 3 as published by the
** Free Software Foundation and appearing in the file LICENSE.GPL.txt included.
**
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
**
** Contact info@kdab.com if any conditions of this licensing are not
** clear to you.
**
**********************************************************************/ #include "mainwindow.h" #include "ui_mainwindow.h"
#include "entrydelegate.h"
#include "entrydialog.h" #include <algorithm> #include <KDGanttConstraintModel>
#include <KDGanttDateTimeGrid>
#include <KDGanttGraphicsView>
#include <KDGanttLegend>
#include <QAbstractItemView>
#include <QDebug>
#include <QHeaderView>
#include <QStandardItemModel>
#include <QTreeView>
#include <QCloseEvent>
#include <QPointer>
#include <QScrollBar> class MyStandardItem : public QStandardItem {
public:
MyStandardItem( const QVariant& v ) : QStandardItem()
{
setData( v, Qt::DisplayRole );
}
MyStandardItem( const QString& v ) : QStandardItem()
{
setData( v, Qt::DisplayRole );
}
}; MainWindow::MainWindow( QWidget* parent, Qt::WindowFlags flags )
: QMainWindow( parent, flags ),
smallLegend( ),
detailedLegend( ),
ui( new Ui::MainWindow )
{
ui->setupUi( this ); initModel();
initActions();
initItemDelegate();
initGrid(); QTreeView* leftView = qobject_cast<QTreeView*>( ui->ganttView->leftView() );
Q_ASSERT( leftView );
leftView->setColumnHidden( , true );
leftView->setColumnHidden( , true );
leftView->setColumnHidden( , true );
leftView->setColumnHidden( , true );
leftView->setColumnHidden( , true );
leftView->header()->setStretchLastSection( true ); connect( ui->ganttView->leftView(), SIGNAL( customContextMenuRequested( const QPoint& ) ),
this, SLOT( showContextMenu( const QPoint& ) ) );
connect( ui->ganttView->selectionModel(), SIGNAL( selectionChanged( const QItemSelection&, const QItemSelection& ) ),
this, SLOT( enableActions( const QItemSelection& ) ) );
} MainWindow::~MainWindow()
{
} void MainWindow::closeEvent(QCloseEvent *event)
{
delete smallLegend;
delete detailedLegend;
event->accept();
} void MainWindow::initModel()
{
model = new QStandardItemModel( , , this );
model->setHeaderData( , Qt::Horizontal, tr( "Tree View of Entries" ) );
ui->ganttView->setModel( model ); QStandardItemModel* lmodel = new QStandardItemModel;
lmodel->appendRow( QList<QStandardItem*>()
<< new MyStandardItem( QVariant() )
<< new MyStandardItem( KDGantt::TypeEvent )
<< new MyStandardItem( QVariant() )
<< new MyStandardItem( QVariant() )
<< new MyStandardItem( QVariant() )
<< new MyStandardItem( QString::fromLatin1("Event") ) );
lmodel->appendRow( QList<QStandardItem*>()
<< new MyStandardItem( QVariant() )
<< new MyStandardItem( KDGantt::TypeTask )
<< new MyStandardItem( QVariant() )
<< new MyStandardItem( QVariant() )
<< new MyStandardItem( QVariant() )
<< new MyStandardItem( QString::fromLatin1("Task") ) );
lmodel->appendRow( QList<QStandardItem*>()
<< new MyStandardItem( QVariant() )
<< new MyStandardItem( KDGantt::TypeSummary )
<< new MyStandardItem( QVariant() )
<< new MyStandardItem( QVariant() )
<< new MyStandardItem( QVariant() )
<< new MyStandardItem( QString::fromLatin1("Summary") ) ); smallLegend = new KDGantt::Legend();
smallLegend->setWindowTitle( tr( "Legend" ) );
smallLegend->show();
smallLegend->setModel( lmodel ); detailedLegend = new KDGantt::Legend();
detailedLegend->setWindowTitle( tr( "List" ) );
detailedLegend->show();
detailedLegend->setModel( model ); constraintModel = new KDGantt::ConstraintModel( this );
ui->ganttView->setConstraintModel( constraintModel );
} void MainWindow::initActions()
{
newEntryAction = new QAction( tr( "New entry" ), this );
newEntryAction->setShortcut( QKeySequence::New );
connect( newEntryAction, SIGNAL( triggered() ), this, SLOT( addNewEntry() ) ); removeEntryAction = new QAction( tr( "Remove entry" ), this );
removeEntryAction->setShortcut( QKeySequence::Delete );
connect( removeEntryAction, SIGNAL( triggered() ), this, SLOT( removeEntry() ) ); zoomInAction = new QAction( tr( "Zoom In" ), this );
zoomInAction->setShortcut( QKeySequence::ZoomIn );
connect( zoomInAction, SIGNAL( triggered() ), this, SLOT( zoomIn() ) ); zoomOutAction = new QAction( tr( "Zoom Out" ), this );
zoomOutAction->setShortcut( QKeySequence::ZoomOut );
connect( zoomOutAction, SIGNAL( triggered() ), this, SLOT( zoomOut() ) ); zoomFitAction = new QAction( tr( "Zoom to Fit" ), this );
connect( zoomFitAction, SIGNAL( triggered() ), this, SLOT( zoomFit() ) ); ui->ganttView->leftView()->setContextMenuPolicy( Qt::CustomContextMenu );
ui->ganttView->leftView()->addAction( newEntryAction );
ui->ganttView->leftView()->addAction( removeEntryAction ); QMenu* entryMenu = menuBar()->addMenu( tr( "Entry" ) );
entryMenu->addAction( newEntryAction );
entryMenu->addAction( removeEntryAction ); QMenu* zoomMenu = menuBar()->addMenu( tr( "Zoom" ) );
zoomMenu->addAction( zoomInAction );
zoomMenu->addAction( zoomOutAction );
zoomMenu->addAction( zoomFitAction ); QMenu* scaleMenu = menuBar()->addMenu( tr( "Scale" ) ); scaleMenu->addAction( tr( "Auto" ), this, SLOT(scaleAuto()) );
scaleMenu->addAction( tr( "Hour" ), this, SLOT(scaleHour()) );
scaleMenu->addAction( tr( "Day" ), this, SLOT(scaleDay()) );
scaleMenu->addAction( tr( "Week" ), this, SLOT(scaleWeek()) );
scaleMenu->addAction( tr( "Month" ), this, SLOT(scaleMonth()) ); enableActions( QItemSelection() );
} void MainWindow::initItemDelegate()
{
EntryDelegate* delegate = new EntryDelegate( constraintModel, this );
ui->ganttView->leftView()->setItemDelegate( delegate );
} void MainWindow::initGrid()
{
grid = new KDGantt::DateTimeGrid();
grid->setDayWidth( );
ui->ganttView->setGrid( grid );
} void MainWindow::showContextMenu( const QPoint& pos )
{
if ( !ui->ganttView->leftView()->indexAt( pos ).isValid() )
ui->ganttView->selectionModel()->clearSelection(); QMenu menu( ui->ganttView->leftView() );
menu.addAction( newEntryAction );
menu.addAction( removeEntryAction );
menu.exec( ui->ganttView->leftView()->viewport()->mapToGlobal( pos ) );
} void MainWindow::enableActions(const QItemSelection & selected)
{
if ( selected.indexes().isEmpty() ) {
newEntryAction->setEnabled( true );
removeEntryAction->setEnabled( false );
return;
} QModelIndex selectedIndex = selected.indexes()[]; if ( model->data( model->index( selectedIndex.row(), ) ) == KDGantt::TypeEvent ||
model->data( model->index( selectedIndex.row(), ) ) == KDGantt::TypeTask ) {
newEntryAction->setEnabled( false );
removeEntryAction->setEnabled( true );
return;
} newEntryAction->setEnabled( true );
removeEntryAction->setEnabled( true );
} void MainWindow::addNewEntry()
{
QPointer<EntryDialog> dialog = new EntryDialog( model );
dialog->setWindowTitle( tr( "New Entry") );
if ( dialog->exec() == QDialog::Rejected || !dialog ) {
delete dialog;
return;
} QModelIndexList selectedIndexes = ui->ganttView->selectionModel()->selectedIndexes();
const QModelIndex parent = selectedIndexes.value( ); if ( !model->insertRow( model->rowCount( parent ), parent ) )
return; int row = model->rowCount( parent ) - ;
if ( row == && parent.isValid() )
model->insertColumns( model->columnCount( parent ), , parent ); model->setData( model->index( row, , parent ), dialog->name() );
model->setData( model->index( row, , parent ), dialog->type() );
if ( dialog->type() != KDGantt::TypeSummary ) {
model->setData( model->index( row, , parent ), dialog->startDate(), KDGantt::StartTimeRole );
model->setData( model->index( row, , parent ), dialog->endDate(), KDGantt::EndTimeRole );
}
model->setData( model->index( row, , parent ), dialog->completion() );
const QString legend( dialog->legend() );
if ( ! legend.isEmpty() )
model->setData( model->index( row, , parent ), legend ); addConstraint( dialog->depends(), model->index( row, , parent ) );
setReadOnly( model->index( row, , parent ), dialog->readOnly() ); delete dialog;
} void MainWindow::setReadOnly(const QModelIndex & index, bool readOnly)
{
int row = index.row();
const QModelIndex parent = index.parent();
QStandardItem* item; item = model->itemFromIndex( model->index( row, , parent ) );
item->setFlags( readOnly ? item->flags() & ~Qt::ItemIsEditable : item->flags() | Qt::ItemIsEditable ); item = model->itemFromIndex( model->index( row, , parent ) );
item->setFlags( readOnly ? item->flags() & ~Qt::ItemIsEditable : item->flags() | Qt::ItemIsEditable ); item = model->itemFromIndex( model->index( row, , parent ) );
item->setFlags( readOnly ? item->flags() & ~Qt::ItemIsEditable : item->flags() | Qt::ItemIsEditable ); item = model->itemFromIndex( model->index( row, , parent ) );
item->setFlags( readOnly ? item->flags() & ~Qt::ItemIsEditable : item->flags() | Qt::ItemIsEditable ); item = model->itemFromIndex( model->index( row, , parent ) );
item->setFlags( readOnly ? item->flags() & ~Qt::ItemIsEditable : item->flags() | Qt::ItemIsEditable );
} void MainWindow::addConstraint(const QModelIndex & index1, const QModelIndex & index2)
{
if ( !index1.isValid() || !index2.isValid() )
return; KDGantt::Constraint c( index1, index2 );
ui->ganttView->constraintModel()->addConstraint( c );
} void MainWindow::removeEntry()
{
QModelIndexList selectedIndexes = ui->ganttView->selectionModel()->selectedIndexes();
QModelIndex index = selectedIndexes.value( ); if ( !index.isValid() )
return; model->removeRow( index.row(), index.parent() );
} void MainWindow::zoomIn()
{
qreal dayWidth = grid->dayWidth() + ;
if ( dayWidth > )
grid->setScale( KDGantt::DateTimeGrid::ScaleHour ); grid->setDayWidth( dayWidth );
} void MainWindow::zoomOut()
{
qreal dayWidth = grid->dayWidth() - ;
if ( dayWidth < )
dayWidth = ; if ( dayWidth <= )
grid->setScale( KDGantt::DateTimeGrid::ScaleDay ); grid->setDayWidth( dayWidth );
} void MainWindow::zoomFit()
{
QModelIndexList selectedIndexes = ui->ganttView->selectionModel()->selectedIndexes(); if ( selectedIndexes.isEmpty() ) {
return;
} KDGantt::Span span;
Q_FOREACH( QModelIndex idx, selectedIndexes ) {
const KDGantt::Span s = grid->mapToChart( grid->model()->index( idx.row(), ) );
if ( span.isValid() ) {
span = span.expandedTo( s );
} else {
span = s;
}
} span.setLength( span.length()+ );
span.setStart( span.start()- ); qDebug() << selectedIndexes << span; const qreal view_width = ui->ganttView->graphicsView()->viewport()->width();
const QDateTime start = grid->mapFromChart( span.start() ).value<QDateTime>();
const QDateTime end = grid->mapFromChart( span.end() ).value<QDateTime>(); qreal delta = start.date().daysTo(end.date());
delta += start.time().msecsTo(end.time())/( .*.*.*. ); qDebug() << view_width << "/" << delta;
grid->setDayWidth( view_width/( std::max( (qreal)., delta ) ) );
qDebug() << "daywidth set to" << grid->dayWidth();
qDebug() << "start scroll to" << grid->mapToChart( start );
ui->ganttView->graphicsView()->horizontalScrollBar()->setValue( grid->mapToChart( start ) );
} void MainWindow::scaleAuto()
{
KDGantt::DateTimeGrid* grid = static_cast<KDGantt::DateTimeGrid*>(ui->ganttView->grid());
grid->setScale( KDGantt::DateTimeGrid::ScaleAuto );
} void MainWindow::scaleHour()
{
KDGantt::DateTimeGrid* grid = static_cast<KDGantt::DateTimeGrid*>(ui->ganttView->grid());
grid->setScale( KDGantt::DateTimeGrid::ScaleHour );
} void MainWindow::scaleDay()
{
KDGantt::DateTimeGrid* grid = static_cast<KDGantt::DateTimeGrid*>(ui->ganttView->grid());
grid->setScale( KDGantt::DateTimeGrid::ScaleDay );
} void MainWindow::scaleWeek()
{
KDGantt::DateTimeGrid* grid = static_cast<KDGantt::DateTimeGrid*>(ui->ganttView->grid());
grid->setScale( KDGantt::DateTimeGrid::ScaleWeek );
} void MainWindow::scaleMonth()
{
KDGantt::DateTimeGrid* grid = static_cast<KDGantt::DateTimeGrid*>(ui->ganttView->grid());
grid->setScale( KDGantt::DateTimeGrid::ScaleMonth );
}
main.cpp
/****************************************************************************
** Copyright (C) 2001-2018 Klaralvdalens Datakonsult AB. All rights reserved.
**
** This file is part of the KD Chart library.
**
** Licensees holding valid commercial KD Chart licenses may use this file in
** accordance with the KD Chart Commercial License Agreement provided with
** the Software.
**
**
** This file may be distributed and/or modified under the terms of the
** GNU General Public License version 2 and version 3 as published by the
** Free Software Foundation and appearing in the file LICENSE.GPL.txt included.
**
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
**
** Contact info@kdab.com if any conditions of this licensing are not
** clear to you.
**
**********************************************************************/ #include <QApplication> #include "mainwindow.h" int main( int argc, char* argv[] )
{
QApplication app( argc, argv ); MainWindow mainWin;
mainWin.show(); return app.exec();
}
ui_mainwindow.h
/********************************************************************************
** Form generated from reading UI file 'mainwindow.ui'
**
** Created by: Qt User Interface Compiler version 5.12.2
**
** WARNING! All changes made in this file will be lost when recompiling UI file!
********************************************************************************/ #ifndef UI_MAINWINDOW_H
#define UI_MAINWINDOW_H #include <KDGanttView>
#include <QtCore/QVariant>
#include <QtWidgets/QApplication>
#include <QtWidgets/QMainWindow>
#include <QtWidgets/QMenuBar>
#include <QtWidgets/QStatusBar>
#include <QtWidgets/QVBoxLayout>
#include <QtWidgets/QWidget> QT_BEGIN_NAMESPACE class Ui_MainWindow
{
public:
QWidget *centralwidget;
QVBoxLayout *vboxLayout;
KDGantt::View *ganttView;
QMenuBar *menubar;
QStatusBar *statusbar; void setupUi(QMainWindow *MainWindow)
{
if (MainWindow->objectName().isEmpty())
MainWindow->setObjectName(QString::fromUtf8("MainWindow"));
MainWindow->resize(, );
MainWindow->setContextMenuPolicy(Qt::DefaultContextMenu);
centralwidget = new QWidget(MainWindow);
centralwidget->setObjectName(QString::fromUtf8("centralwidget"));
vboxLayout = new QVBoxLayout(centralwidget);
vboxLayout->setObjectName(QString::fromUtf8("vboxLayout"));
ganttView = new KDGantt::View(centralwidget);
ganttView->setObjectName(QString::fromUtf8("ganttView")); vboxLayout->addWidget(ganttView); MainWindow->setCentralWidget(centralwidget);
menubar = new QMenuBar(MainWindow);
menubar->setObjectName(QString::fromUtf8("menubar"));
menubar->setGeometry(QRect(, , , ));
MainWindow->setMenuBar(menubar);
statusbar = new QStatusBar(MainWindow);
statusbar->setObjectName(QString::fromUtf8("statusbar"));
MainWindow->setStatusBar(statusbar); retranslateUi(MainWindow); QMetaObject::connectSlotsByName(MainWindow);
} // setupUi void retranslateUi(QMainWindow *MainWindow)
{
MainWindow->setWindowTitle(QApplication::translate("MainWindow", "KD Gantt Example", nullptr));
} // retranslateUi }; namespace Ui {
class MainWindow: public Ui_MainWindow {};
} // namespace Ui QT_END_NAMESPACE #endif // UI_MAINWINDOW_H
ui_entrydialog.h
/********************************************************************************
** Form generated from reading UI file 'entrydialog.ui'
**
** Created by: Qt User Interface Compiler version 5.12.2
**
** WARNING! All changes made in this file will be lost when recompiling UI file!
********************************************************************************/ #ifndef UI_ENTRYDIALOG_H
#define UI_ENTRYDIALOG_H #include <QtCore/QVariant>
#include <QtWidgets/QApplication>
#include <QtWidgets/QCheckBox>
#include <QtWidgets/QComboBox>
#include <QtWidgets/QDateTimeEdit>
#include <QtWidgets/QDialog>
#include <QtWidgets/QDialogButtonBox>
#include <QtWidgets/QGridLayout>
#include <QtWidgets/QHBoxLayout>
#include <QtWidgets/QLabel>
#include <QtWidgets/QLineEdit>
#include <QtWidgets/QSpacerItem>
#include <QtWidgets/QSpinBox>
#include <QtWidgets/QVBoxLayout> QT_BEGIN_NAMESPACE class Ui_EntryDialog
{
public:
QVBoxLayout *vboxLayout;
QHBoxLayout *hboxLayout;
QLabel *label;
QLineEdit *name;
QHBoxLayout *hboxLayout1;
QLabel *label_6;
QLineEdit *legend;
QGridLayout *gridLayout;
QLabel *label_2;
QComboBox *type;
QSpacerItem *spacerItem;
QLabel *label_3;
QDateTimeEdit *startDate;
QLabel *label_5;
QSpinBox *completion;
QLabel *label_EndDate;
QDateTimeEdit *endDate;
QCheckBox *readOnly;
QLabel *dependsLabel;
QComboBox *depends;
QDialogButtonBox *buttonBox; void setupUi(QDialog *EntryDialog)
{
if (EntryDialog->objectName().isEmpty())
EntryDialog->setObjectName(QString::fromUtf8("EntryDialog"));
EntryDialog->resize(, );
vboxLayout = new QVBoxLayout(EntryDialog);
vboxLayout->setObjectName(QString::fromUtf8("vboxLayout"));
hboxLayout = new QHBoxLayout();
hboxLayout->setObjectName(QString::fromUtf8("hboxLayout"));
label = new QLabel(EntryDialog);
label->setObjectName(QString::fromUtf8("label")); hboxLayout->addWidget(label); name = new QLineEdit(EntryDialog);
name->setObjectName(QString::fromUtf8("name")); hboxLayout->addWidget(name); vboxLayout->addLayout(hboxLayout); hboxLayout1 = new QHBoxLayout();
hboxLayout1->setObjectName(QString::fromUtf8("hboxLayout1"));
label_6 = new QLabel(EntryDialog);
label_6->setObjectName(QString::fromUtf8("label_6")); hboxLayout1->addWidget(label_6); legend = new QLineEdit(EntryDialog);
legend->setObjectName(QString::fromUtf8("legend")); hboxLayout1->addWidget(legend); vboxLayout->addLayout(hboxLayout1); gridLayout = new QGridLayout();
gridLayout->setObjectName(QString::fromUtf8("gridLayout"));
label_2 = new QLabel(EntryDialog);
label_2->setObjectName(QString::fromUtf8("label_2")); gridLayout->addWidget(label_2, , , , ); type = new QComboBox(EntryDialog);
type->setObjectName(QString::fromUtf8("type")); gridLayout->addWidget(type, , , , ); spacerItem = new QSpacerItem(, , QSizePolicy::Expanding, QSizePolicy::Minimum); gridLayout->addItem(spacerItem, , , , ); label_3 = new QLabel(EntryDialog);
label_3->setObjectName(QString::fromUtf8("label_3")); gridLayout->addWidget(label_3, , , , ); startDate = new QDateTimeEdit(EntryDialog);
startDate->setObjectName(QString::fromUtf8("startDate"));
startDate->setCalendarPopup(true); gridLayout->addWidget(startDate, , , , ); label_5 = new QLabel(EntryDialog);
label_5->setObjectName(QString::fromUtf8("label_5")); gridLayout->addWidget(label_5, , , , ); completion = new QSpinBox(EntryDialog);
completion->setObjectName(QString::fromUtf8("completion"));
completion->setMaximum(); gridLayout->addWidget(completion, , , , ); label_EndDate = new QLabel(EntryDialog);
label_EndDate->setObjectName(QString::fromUtf8("label_EndDate")); gridLayout->addWidget(label_EndDate, , , , ); endDate = new QDateTimeEdit(EntryDialog);
endDate->setObjectName(QString::fromUtf8("endDate"));
endDate->setCalendarPopup(true); gridLayout->addWidget(endDate, , , , ); readOnly = new QCheckBox(EntryDialog);
readOnly->setObjectName(QString::fromUtf8("readOnly")); gridLayout->addWidget(readOnly, , , , ); dependsLabel = new QLabel(EntryDialog);
dependsLabel->setObjectName(QString::fromUtf8("dependsLabel")); gridLayout->addWidget(dependsLabel, , , , ); depends = new QComboBox(EntryDialog);
depends->addItem(QString());
depends->setObjectName(QString::fromUtf8("depends")); gridLayout->addWidget(depends, , , , ); vboxLayout->addLayout(gridLayout); buttonBox = new QDialogButtonBox(EntryDialog);
buttonBox->setObjectName(QString::fromUtf8("buttonBox"));
buttonBox->setOrientation(Qt::Horizontal);
buttonBox->setStandardButtons(QDialogButtonBox::Cancel|QDialogButtonBox::Ok); vboxLayout->addWidget(buttonBox); retranslateUi(EntryDialog);
QObject::connect(buttonBox, SIGNAL(accepted()), EntryDialog, SLOT(accept()));
QObject::connect(buttonBox, SIGNAL(rejected()), EntryDialog, SLOT(reject())); QMetaObject::connectSlotsByName(EntryDialog);
} // setupUi void retranslateUi(QDialog *EntryDialog)
{
label->setText(QApplication::translate("EntryDialog", "Name", nullptr));
label_6->setText(QApplication::translate("EntryDialog", "Legend", nullptr));
label_2->setText(QApplication::translate("EntryDialog", "Type", nullptr));
label_3->setText(QApplication::translate("EntryDialog", "Start date", nullptr));
label_5->setText(QApplication::translate("EntryDialog", "Completion", nullptr));
completion->setSuffix(QApplication::translate("EntryDialog", "%", nullptr));
label_EndDate->setText(QApplication::translate("EntryDialog", "End date", nullptr));
readOnly->setText(QApplication::translate("EntryDialog", "Read Only", nullptr));
dependsLabel->setText(QApplication::translate("EntryDialog", "Depends on", nullptr));
depends->setItemText(, QApplication::translate("EntryDialog", "- None -", nullptr)); Q_UNUSED(EntryDialog);
} // retranslateUi }; namespace Ui {
class EntryDialog: public Ui_EntryDialog {};
} // namespace Ui QT_END_NAMESPACE #endif // UI_ENTRYDIALOG_H
legend_example.pro
#include( $${TOP_SOURCE_DIR}/examples/examples.pri ) HEADERS += mainwindow.h \
entrydialog.h \
entrydelegate.h SOURCES += main.cpp \
mainwindow.cpp \
entrydialog.cpp \
entrydelegate.cpp FORMS += mainwindow.ui \
entrydialog.ui greaterThan(QT_MAJOR_VERSION, ):QT += printsupport message( "Building ''$$TARGET'' using LIBS ''$$LIBS''" ) unix|win32: LIBS += -LE:/Qt/Qt5.12.2/5.12./msvc2015_64/lib/ -lkdchartd INCLUDEPATH += E:/Qt/Qt5.12.2/5.12./msvc2015_64/include
DEPENDPATH += E:/Qt/Qt5.12.2/5.12./msvc2015_64/include INCLUDEPATH += E:/Qt/Qt5.12.2/5.12./msvc2015_64/include/KDChart
DEPENDPATH += E:/Qt/Qt5.12.2/5.12./msvc2015_64/include/KDChart INCLUDEPATH += E:/Qt/Qt5.12.2/5.12./msvc2015_64/include/KDGantt
DEPENDPATH += E:/Qt/Qt5.12.2/5.12./msvc2015_64/include/KDGantt
运行效果:
----------------------------------------------------------------
QWindowsWindow::setGeometry: Unable to set geometry 439x206+734+412 on QWidgetWindow/'EntryDialogWindow'. Resulting geometry: 452x206+734+412 (frame: 9, 38, 9, 9, custom margin: 0, 0, 0, 0, minimum size: 452x206, maximum size: 16777215x16777215).
QWindowsWindow::setGeometry: Unable to set geometry 439x206+734+412 on QWidgetWindow/'EntryDialogWindow'. Resulting geometry: 452x206+734+412 (frame: 9, 38, 9, 9, custom margin: 0, 0, 0, 0, minimum size: 452x206, maximum size: 16777215x16777215).
QWindowsWindow::setGeometry: Unable to set geometry 439x206+734+412 on QWidgetWindow/'EntryDialogWindow'. Resulting geometry: 452x206+734+412 (frame: 9, 38, 9, 9, custom margin: 0, 0, 0, 0, minimum size: 452x206, maximum size: 16777215x16777215).
QWindowsWindow::setGeometry: Unable to set geometry 439x206+734+412 on QWidgetWindow/'EntryDialogWindow'. Resulting geometry: 452x206+734+412 (frame: 9, 38, 9, 9, custom margin: 0, 0, 0, 0, minimum size: 452x206, maximum size: 16777215x16777215).
QWindowsWindow::setGeometry: Unable to set geometry 439x206+734+412 on QWidgetWindow/'EntryDialogWindow'. Resulting geometry: 452x206+734+412 (frame: 9, 38, 9, 9, custom margin: 0, 0, 0, 0, minimum size: 452x206, maximum size: 16777215x16777215).
Skipping item QModelIndex(3,0,0x1d563494fc0,KDGantt::ProxyModel(0x1d55f32cdd8)) because it doesn't contain QDateTime
Skipping item QModelIndex(3,0,0x1d563494fc0,KDGantt::ProxyModel(0x1d55f32cdd8)) because it doesn't contain QDateTime
Skipping item QModelIndex(3,0,0x1d563494fc0,KDGantt::ProxyModel(0x1d55f32cdd8)) because it doesn't contain QDateTime
Skipping item QModelIndex(3,0,0x1d563494fc0,KDGantt::ProxyModel(0x1d55f32cdd8)) because it doesn't contain QDateTime
Skipping item QModelIndex(3,0,0x1d563494fc0,KDGantt::ProxyModel(0x1d55f32cdd8)) because it doesn't contain QDateTime
QWindowsWindow::setGeometry: Unable to set geometry 439x206+734+412 on QWidgetWindow/'EntryDialogWindow'. Resulting geometry: 452x206+734+412 (frame: 9, 38, 9, 9, custom margin: 0, 0, 0, 0, minimum size: 452x206, maximum size: 16777215x16777215).
Skipping item QModelIndex(3,0,0x1d563494fc0,KDGantt::ProxyModel(0x1d55f32cdd8)) because it doesn't contain QDateTime
Skipping item QModelIndex(3,0,0x1d563494fc0,KDGantt::ProxyModel(0x1d55f32cdd8)) because it doesn't contain QDateTime
Skipping item QModelIndex(3,0,0x1d563494fc0,KDGantt::ProxyModel(0x1d55f32cdd8)) because it doesn't contain QDateTime
Skipping item QModelIndex(3,0,0x1d563494fc0,KDGantt::ProxyModel(0x1d55f32cdd8)) because it doesn't contain QDateTime
QWindowsWindow::setGeometry: Unable to set geometry 439x206+734+412 on QWidgetWindow/'EntryDialogWindow'. Resulting geometry: 452x206+734+412 (frame: 9, 38, 9, 9, custom margin: 0, 0, 0, 0, minimum size: 452x206, maximum size: 16777215x16777215).
Skipping item QModelIndex(3,0,0x1d563494fc0,KDGantt::ProxyModel(0x1d55f32cdd8)) because it doesn't contain QDateTime
Skipping item QModelIndex(3,0,0x1d563494fc0,KDGantt::ProxyModel(0x1d55f32cdd8)) because it doesn't contain QDateTime
Skipping item QModelIndex(3,0,0x1d563494fc0,KDGantt::ProxyModel(0x1d55f32cdd8)) because it doesn't contain QDateTime
Skipping item QModelIndex(3,0,0x1d563494fc0,KDGantt::ProxyModel(0x1d55f32cdd8)) because it doesn't contain QDateTime
QWindowsWindow::setGeometry: Unable to set geometry 439x206+734+412 on QWidgetWindow/'EntryDialogWindow'. Resulting geometry: 452x206+734+412 (frame: 9, 38, 9, 9, custom margin: 0, 0, 0, 0, minimum size: 452x206, maximum size: 16777215x16777215).
Skipping item QModelIndex(3,0,0x1d563494fc0,KDGantt::ProxyModel(0x1d55f32cdd8)) because it doesn't contain QDateTime
Skipping item QModelIndex(3,0,0x1d563494fc0,KDGantt::ProxyModel(0x1d55f32cdd8)) because it doesn't contain QDateTime
QWindowsWindow::setGeometry: Unable to set geometry 439x206+734+412 on QWidgetWindow/'EntryDialogWindow'. Resulting geometry: 452x206+734+412 (frame: 9, 38, 9, 9, custom margin: 0, 0, 0, 0, minimum size: 452x206, maximum size: 16777215x16777215).
Skipping item QModelIndex(3,0,0x1d563494fc0,KDGantt::ProxyModel(0x1d55f32cdd8)) because it doesn't contain QDateTime
Skipping item QModelIndex(3,0,0x1d563494fc0,KDGantt::ProxyModel(0x1d55f32cdd8)) because it doesn't contain QDateTime
Skipping item QModelIndex(3,0,0x1d563494fc0,KDGantt::ProxyModel(0x1d55f32cdd8)) because it doesn't contain QDateTime
Skipping item QModelIndex(3,0,0x1d563494fc0,KDGantt::ProxyModel(0x1d55f32cdd8)) because it doesn't contain QDateTime
QWindowsWindow::setGeometry: Unable to set geometry 439x206+734+412 on QWidgetWindow/'EntryDialogWindow'. Resulting geometry: 452x206+734+412 (frame: 9, 38, 9, 9, custom margin: 0, 0, 0, 0, minimum size: 452x206, maximum size: 16777215x16777215).
Skipping item QModelIndex(4,0,0x1d564202660,KDGantt::ProxyModel(0x1d55f32cdd8)) because it doesn't contain QDateTime
Skipping item QModelIndex(4,0,0x1d564202660,KDGantt::ProxyModel(0x1d55f32cdd8)) because it doesn't contain QDateTime
Skipping item QModelIndex(4,0,0x1d564202660,KDGantt::ProxyModel(0x1d55f32cdd8)) because it doesn't contain QDateTime
Skipping item QModelIndex(4,0,0x1d564202660,KDGantt::ProxyModel(0x1d55f32cdd8)) because it doesn't contain QDateTime
Skipping item QModelIndex(4,0,0x1d564202660,KDGantt::ProxyModel(0x1d55f32cdd8)) because it doesn't contain QDateTime
QWindowsWindow::setGeometry: Unable to set geometry 439x206+734+412 on QWidgetWindow/'EntryDialogWindow'. Resulting geometry: 452x206+734+412 (frame: 9, 38, 9, 9, custom margin: 0, 0, 0, 0, minimum size: 452x206, maximum size: 16777215x16777215).
Skipping item QModelIndex(4,0,0x1d564202660,KDGantt::ProxyModel(0x1d55f32cdd8)) because it doesn't contain QDateTime
Skipping item QModelIndex(4,0,0x1d564202660,KDGantt::ProxyModel(0x1d55f32cdd8)) because it doesn't contain QDateTime
Skipping item QModelIndex(4,0,0x1d564202660,KDGantt::ProxyModel(0x1d55f32cdd8)) because it doesn't contain QDateTime
Skipping item QModelIndex(4,0,0x1d564202660,KDGantt::ProxyModel(0x1d55f32cdd8)) because it doesn't contain QDateTime
QWindowsWindow::setGeometry: Unable to set geometry 439x206+734+412 on QWidgetWindow/'EntryDialogWindow'. Resulting geometry: 452x206+734+412 (frame: 9, 38, 9, 9, custom margin: 0, 0, 0, 0, minimum size: 452x206, maximum size: 16777215x16777215).
Skipping item QModelIndex(4,0,0x1d564202660,KDGantt::ProxyModel(0x1d55f32cdd8)) because it doesn't contain QDateTime
Skipping item QModelIndex(4,0,0x1d564202660,KDGantt::ProxyModel(0x1d55f32cdd8)) because it doesn't contain QDateTime
Skipping item QModelIndex(4,0,0x1d564202660,KDGantt::ProxyModel(0x1d55f32cdd8)) because it doesn't contain QDateTime
Skipping item QModelIndex(4,0,0x1d564202660,KDGantt::ProxyModel(0x1d55f32cdd8)) because it doesn't contain QDateTime
---------------------------------------------------------------- 如果想修改为自定义样式:
参考:https://www.cnblogs.com/qnkk123/p/7685477.html
设置每个item的颜色:
topitem->setData(, KDGantt::ItemColor_R);
topitem->setData(, KDGantt::ItemColor_G);
topitem->setData(, KDGantt::ItemColor_B);
kdChart中,颜色的修改是:
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( *pen.width() );
painter->setPen( pen );
painter->setBrush( QBrush(Qt::white, Qt::Dense1Pattern) ); bool drawText = true;
qreal pw = painter->pen().width()/.;
switch ( typ ) {
case TypeTask:
if ( itemRect.isValid() ) {
// TODO
qreal pw = painter->pen().width()/.;
pw-=;
QRectF r = itemRect;
r.translate( ., r.height()/. );
r.setHeight( .*r.height()/. );
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/.,
r.width()*completion/., h/.+ /*??*/ );
QColor compcolor( painter->pen().color() );
compcolor.setAlpha( );
painter->fillRect( cr, compcolor );
}
painter->restore();
}
break;
case TypeSummary:
if ( opt.itemRect.isValid() ) {
// TODO
pw-=;
const QRectF r = QRectF( opt.itemRect ).adjusted( -pw, -pw, pw, pw );
QPainterPath path;
const qreal deltaY = r.height()/.;
const qreal deltaXBezierControl = .*qMin( r.width(), r.height() );
const qreal deltaX = qMin( r.width()/., r.height() );
path.moveTo( r.topLeft() );
path.lineTo( r.topRight() );
path.lineTo( QPointF( r.right(), r.top() + .*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() + .*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() / . - ;
const QRectF r = QRectF( opt.itemRect ).adjusted( -pw, -pw, pw, pw ).translated( -opt.itemRect.height()/, );
QPainterPath path;
const qreal delta = static_cast< int >( r.height() / );
path.moveTo( delta, . );
path.lineTo( .*delta, delta );
path.lineTo( delta, .*delta );
path.lineTo( ., delta );
path.closeSubpath();
painter->save();
painter->translate( r.topLeft() );
painter->translate( , 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();
}
拖动事件:
在文件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, , parent ) );
} emit q->signal_dataChanged(topLeft);
}
外部使用:
connect(ui->ganttView->graphicsView(), SIGNAL(signal_dataChanged(const QModelIndex&)), this, SLOT(onCheckTask(const QModelIndex&)));
修改显示的日期格式,效果:
上面显示年月,下面显示多少号,显示号很简单:
其中有个格式: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();
}
/*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()); // 显示在上面
这部分转自:
https://www.cnblogs.com/qnkk123/p/7685477.html
Qt kdChart 甘特图案例的更多相关文章
- qt绘制甘特图
重写paintEvent事件,代码如下 void xx::paintEvent(QPaintEvent *event){ QPainter painter(this); //绘制x,y轴,_maxWi ...
- Qt KDChart编译
最近开发中需要用到甘特图,感觉KDChart这个插件不错,在这里记录一下编译过程(其实很好编译,而且一次性就过了) 下载,kdchart-2.6.1-source,解压 打开src目录,用Qt Cre ...
- gantt甘特图的制作过程
甘特图主要是用来做项目管理的,可以清楚的看到任务间的逻辑关系,任务与时间关系和任务间并行关系. 在甘特图中,横轴方向表示时间,纵轴方向并列着活动列表.图表内可以用线条.数字.文字代号等来表示计划(实际 ...
- 甘特图生产排程(APS)定制开发
高速开发完毕APS的数据可视化.订单展示.资源调度.智能排程等差点儿所有功能模块. 自己主动智能排程功能 提供专业需求分析师及开发团队,按需开发"全自己主动智能排程"这一APS的主 ...
- gantt甘特图可拖拽、编辑(vue、react都可用 highcharts)
前言 Excel功能强大,应用广泛.随着web应用的兴起和完善,用户的要求也越来越高.很多Excel的功能都搬到了sass里面.恨不得给他们做个Excel出来...程序员太难了... 去年我遇到了 ...
- Twproject Gantt开源甘特图功能扩展
1.Twproject Gantt甘特图介绍 Twproject Gantt 是一款基于 jQuery 开发的甘特图组件,也可以创建其它图表,例如任务树(Task Trees).内置编辑.缩放和 CS ...
- 从零开始编写自己的C#框架(10)——项目实施计划与甘特图
不知不觉本系列已经写了一个月,编码前的各项工作到此也终于结束了.回头看看这一个月走过来,白天上班晚上码字查资料,写写改改,挺不容易的.很多时候有些知识会用,知道是怎么回事,但并不等于能写出来.错别字. ...
- java实现甘特图的2种方法:SwiftGantt和Jfree (转)
http://blog.sina.com.cn/s/blog_50a7c4a601009817.html 第一种方法使用SwiftGantt实现甘特图(进度图推荐这个) import java.a ...
- 使用Excel 2007绘制甘特图
本文将教大家如何使用Excel 2007制作甘特图.Excel并未提供甘特图类型,但还是可以绘制甘特图的,方法就是通过对堆积条形图类型进行自定义,使之显示任务.任务工期和层次结构. 下面的过程可帮助创 ...
随机推荐
- FRDM-KL43开发板驱动段式液晶SLCD的实现方法
LCD的驱动不像LED那样,加上电压(LED实际上是电流驱动)就可以长期显示的. LCD驱动必须使用交流电压驱动才能保持稳定的显示,如果在LCD上加上稳定的直流电压, 不但不能正常显示,时间久了还会损 ...
- Mybatis3.1-[tp_36-37]-_映射文件_select_resultMap关联查询__分步查询传递多列值&fetchType_discriminator鉴别器
_分步查询传递多列值&fetchType_discriminator鉴别器 笔记要点出错分析与总结 Department.java bean public class Department { ...
- Dubbo中的IoC实现
Dubbo IOC 是通过 setter 方法注入依赖.Dubbo 首先会通过反射获取到实例的所有方法,然后再遍历方法列表,检测方法名是否具有 setter 方法特征.若有,则通过 ObjectFac ...
- 常考JS题笔记
### 1. 原始类型有哪几种?null 是对象吗? 答: Null,undefined,Number,String,Blooean,symbol1)[理解和使用ES6中的Symbol][https: ...
- webpack 配置react脚手架(四):路由配置
1. 由于 react-router 是集成了 react-router-dom 和 react-router-native的一起的,所以这里要使用的是 react-router-dom, 2. 安装 ...
- flask中使用ajax 处理前端请求,每隔一段时间请求一次
需求: flask中使用ajax 处理前端请求,每隔一段时间请求一次,并展示在页面 使用 setInterval(function(){},1000)方法 结果展示: html:(test.html) ...
- 1. let与const
1.ES6 新增了let命令,用来声明变量.它的用法类似于var,但是所声明的变量,只在let命令所在的代码块内有效. var a = []; for (var i = 0;i<10;i++) ...
- jquery判断两次密码不一致
jquery检测输入密码两次不一样提示 输入密码: <input type="password" name="password1" id="pa ...
- MyBatis的关联查询
关联映射的一对多 //查询经理角色 以及 该角色下对应的员工集合 public SmbmsRole getRoleAndUser(Integer id); <resultMap id=" ...
- Codeforces Round #525 (Div. 2)题解
Codeforces Round #525 (Div. 2)题解 题解 CF1088A [Ehab and another construction problem] 依据题意枚举即可 # inclu ...