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 = 0, Qt::WindowFlags flags = 0 ); 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 = 0, Qt::WindowFlags f = 0 ); 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 = 0 ); 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 = 0 ); 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, 0, parent ), dialog->name() ); model->setData( model->index( row, 1, parent ), dialog->type() ); if ( dialog->type() != KDGantt::TypeSummary ) { model->setData( model->index( row, 2, parent ), dialog->startDate(), KDGantt::StartTimeRole ); model->setData( model->index( row, 3, parent ), dialog->endDate(), KDGantt::EndTimeRole ); } model->setData( model->index( row, 4, parent ), dialog->completion() ); model->setData( model->index( row, 5, parent ), dialog->legend() ); addConstraint( dialog->depends(), model->index( row, 0, parent ) ); setReadOnly( model->index( row, 0, 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, 0, parent ) ); item->setFlags( readOnly ? item->flags() & ~Qt::ItemIsEditable : item->flags() | Qt::ItemIsEditable ); item = model->itemFromIndex( model->index( row, 1, parent ) ); item->setFlags( readOnly ? item->flags() & ~Qt::ItemIsEditable : item->flags() | Qt::ItemIsEditable ); item = model->itemFromIndex( model->index( row, 2, parent ) ); item->setFlags( readOnly ? item->flags() & ~Qt::ItemIsEditable : item->flags() | Qt::ItemIsEditable ); item = model->itemFromIndex( model->index( row, 3, parent ) ); item->setFlags( readOnly ? item->flags() & ~Qt::ItemIsEditable : item->flags() | Qt::ItemIsEditable ); item = model->itemFromIndex( model->index( row, 4, 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 = 0; row < model->rowCount(); ++row ) addDependItem( model, model->index( row, 0 ) ); 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( 0 ); } 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, 0, parent ) ).toString() ); ui->legend->setText( model->data( model->index( row, 5, parent ) ).toString() ); int idx = ui->type->findData( model->data( model->index( row, 1, parent ) ).toInt() ); ui->type->setCurrentIndex( idx ); ui->startDate->setDateTime( model->data( model->index( row, 2, parent ), KDGantt::StartTimeRole ).toDateTime() ); ui->endDate->setDateTime( model->data( model->index( row, 3, parent ), KDGantt::EndTimeRole ).toDateTime() ); ui->completion->setValue( model->data( model->index( row, 4, parent ) ).toInt() ); ui->readOnly->setChecked( !(model->flags( model->index( row, 0, parent ) ) & Qt::ItemIsEditable) ); QList<KDGantt::Constraint> constraints = constraintModel->constraintsForIndex( model->index( row, 0, parent ) ); if ( constraints.isEmpty() ) return; QModelIndex constraintIndex; for ( int i = 0; 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 ) + 1 ); } 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 = 0; row < model->rowCount( index ); ++row ) addDependItem( model, model->index( row, 0, index ), indent + 2 ); } 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() == 0 ) return QModelIndex(); QPersistentModelIndex index = indexList[ ui->depends->currentIndex() - 1 ]; 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( 0 ), detailedLegend( 0 ), ui( new Ui::MainWindow ) { ui->setupUi( this ); initModel(); initActions(); initItemDelegate(); initGrid(); QTreeView* leftView = qobject_cast<QTreeView*>( ui->ganttView->leftView() ); Q_ASSERT( leftView ); leftView->setColumnHidden( 1, true ); leftView->setColumnHidden( 2, true ); leftView->setColumnHidden( 3, true ); leftView->setColumnHidden( 4, true ); leftView->setColumnHidden( 5, 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( 0, 6, this ); model->setHeaderData( 0, 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( 70 ); 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()[0]; if ( model->data( model->index( selectedIndex.row(), 1 ) ) == KDGantt::TypeEvent || model->data( model->index( selectedIndex.row(), 1 ) ) == 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( 0 ); if ( !model->insertRow( model->rowCount( parent ), parent ) ) return; int row = model->rowCount( parent ) - 1; if ( row == 0 && parent.isValid() ) model->insertColumns( model->columnCount( parent ), 5, parent ); model->setData( model->index( row, 0, parent ), dialog->name() ); model->setData( model->index( row, 1, parent ), dialog->type() ); if ( dialog->type() != KDGantt::TypeSummary ) { model->setData( model->index( row, 2, parent ), dialog->startDate(), KDGantt::StartTimeRole ); model->setData( model->index( row, 3, parent ), dialog->endDate(), KDGantt::EndTimeRole ); } model->setData( model->index( row, 4, parent ), dialog->completion() ); const QString legend( dialog->legend() ); if ( ! legend.isEmpty() ) model->setData( model->index( row, 5, parent ), legend ); addConstraint( dialog->depends(), model->index( row, 0, parent ) ); setReadOnly( model->index( row, 0, 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, 0, parent ) ); item->setFlags( readOnly ? item->flags() & ~Qt::ItemIsEditable : item->flags() | Qt::ItemIsEditable ); item = model->itemFromIndex( model->index( row, 1, parent ) ); item->setFlags( readOnly ? item->flags() & ~Qt::ItemIsEditable : item->flags() | Qt::ItemIsEditable ); item = model->itemFromIndex( model->index( row, 2, parent ) ); item->setFlags( readOnly ? item->flags() & ~Qt::ItemIsEditable : item->flags() | Qt::ItemIsEditable ); item = model->itemFromIndex( model->index( row, 3, parent ) ); item->setFlags( readOnly ? item->flags() & ~Qt::ItemIsEditable : item->flags() | Qt::ItemIsEditable ); item = model->itemFromIndex( model->index( row, 4, 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( 0 ); if ( !index.isValid() ) return; model->removeRow( index.row(), index.parent() ); } void MainWindow::zoomIn() { qreal dayWidth = grid->dayWidth() + 10; if ( dayWidth > 400 ) grid->setScale( KDGantt::DateTimeGrid::ScaleHour ); grid->setDayWidth( dayWidth ); } void MainWindow::zoomOut() { qreal dayWidth = grid->dayWidth() - 10; if ( dayWidth < 10 ) dayWidth = 10; if ( dayWidth <= 400 ) 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(), 0 ) ); if ( span.isValid() ) { span = span.expandedTo( s ); } else { span = s; } } span.setLength( span.length()+20 ); span.setStart( span.start()-10 ); 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())/( 1000.*24.*60.*60. ); qDebug() << view_width << "/" << delta; grid->setDayWidth( view_width/( std::max( (qreal)1., 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(556, 330); 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(0, 0, 556, 29)); 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(439, 206); 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, 0, 0, 1, 1); type = new QComboBox(EntryDialog); type->setObjectName(QString::fromUtf8("type")); gridLayout->addWidget(type, 0, 1, 1, 1); spacerItem = new QSpacerItem(41, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); gridLayout->addItem(spacerItem, 0, 2, 1, 1); label_3 = new QLabel(EntryDialog); label_3->setObjectName(QString::fromUtf8("label_3")); gridLayout->addWidget(label_3, 0, 3, 1, 1); startDate = new QDateTimeEdit(EntryDialog); startDate->setObjectName(QString::fromUtf8("startDate")); startDate->setCalendarPopup(true); gridLayout->addWidget(startDate, 0, 4, 1, 1); label_5 = new QLabel(EntryDialog); label_5->setObjectName(QString::fromUtf8("label_5")); gridLayout->addWidget(label_5, 1, 0, 1, 1); completion = new QSpinBox(EntryDialog); completion->setObjectName(QString::fromUtf8("completion")); completion->setMaximum(100); gridLayout->addWidget(completion, 1, 1, 1, 1); label_EndDate = new QLabel(EntryDialog); label_EndDate->setObjectName(QString::fromUtf8("label_EndDate")); gridLayout->addWidget(label_EndDate, 1, 3, 1, 1); endDate = new QDateTimeEdit(EntryDialog); endDate->setObjectName(QString::fromUtf8("endDate")); endDate->setCalendarPopup(true); gridLayout->addWidget(endDate, 1, 4, 1, 1); readOnly = new QCheckBox(EntryDialog); readOnly->setObjectName(QString::fromUtf8("readOnly")); gridLayout->addWidget(readOnly, 2, 0, 1, 2); dependsLabel = new QLabel(EntryDialog); dependsLabel->setObjectName(QString::fromUtf8("dependsLabel")); gridLayout->addWidget(dependsLabel, 2, 3, 1, 1); depends = new QComboBox(EntryDialog); depends->addItem(QString()); depends->setObjectName(QString::fromUtf8("depends")); gridLayout->addWidget(depends, 2, 4, 1, 1); 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(0, 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, 4):QT += printsupport message( "Building ''$$TARGET'' using LIBS ''$$LIBS''" ) unix|win32: LIBS += -LE:/Qt/Qt5.12.2/5.12.2/msvc2015_64/lib/ -lkdchartd INCLUDEPATH += E:/Qt/Qt5.12.2/5.12.2/msvc2015_64/include DEPENDPATH += E:/Qt/Qt5.12.2/5.12.2/msvc2015_64/include INCLUDEPATH += E:/Qt/Qt5.12.2/5.12.2/msvc2015_64/include/KDChart DEPENDPATH += E:/Qt/Qt5.12.2/5.12.2/msvc2015_64/include/KDChart INCLUDEPATH += E:/Qt/Qt5.12.2/5.12.2/msvc2015_64/include/KDGantt DEPENDPATH += E:/Qt/Qt5.12.2/5.12.2/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(249, KDGantt::ItemColor_R); topitem->setData(171, KDGantt::ItemColor_G); topitem->setData(82, 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( 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(); }
拖动事件:
在文件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&)));
修改显示的日期格式,效果:
上面显示年月,下面显示多少号,显示号很简单:
其中有个格式: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()); // 显示在上面
这部分转自:
https://www.cnblogs.com/qnkk123/p/7685477.html