def dropMimeData(self, data, action, row, column, parent): # If any albums were dropped into another album, # add all the songs in the dropped album # but not the album item itself if parent.isValid(): dummy_model = QStandardItemModel() dummy_model.dropMimeData(data, action, 0, 0, QModelIndex()) indexes = [] for r in range(dummy_model.rowCount()): for c in range(dummy_model.columnCount()): index = dummy_model.index(r, c) # QStandardItemModel doesn't recognize our items as our custom classes # so we have to treat them as QStandardItems item = dummy_model.item(r, c) if item.data( CustomDataRole.ITEMTYPE) == TreeWidgetType.ALBUM: indexes += [ child.index() for child in AlbumTreeWidgetItem. getChildrenFromStandardItem(item) ] elif item.data( CustomDataRole.ITEMTYPE) == TreeWidgetType.SONG: indexes.append(index) data = dummy_model.mimeData(indexes) ret = super().dropMimeData(data, action, row, column, parent) return ret
class MainWindow(QMainWindow): def __init__(self, parent=None, flags=Qt.WindowFlags()): super(MainWindow, self).__init__(parent, flags) self.dayWidth = 70 self.ui = Ui_MainWindow() self.ui.setupUi(self) self.initModel() self.initActions() self.initItemDelegate() self.initGrid() leftView = self.ui.ganttView.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) self.ui.ganttView.leftView().customContextMenuRequested.connect( self.showContextMenu) self.ui.ganttView.selectionModel().selectionChanged.connect( self.enableActions) self.ui.ganttView.graphicsView().clicked.connect(self.slotClicked) self.ui.ganttView.graphicsView().qrealClicked.connect( self.slotDoubleClicked) def initModel(self): self.model = QStandardItemModel(0, 6, self) self.model.setHeaderData(0, Qt.Horizontal, "Task") self.ui.ganttView.setModel(self.model) self.l = QWidget(self) self.l.setWindowTitle("Legend") self.l.show() ##self.l.setModel(self.model) self.constraintModel = ConstraintModel(self) self.ui.ganttView.setConstraintModel(self.constraintModel) def initActions(self): self.newEntryAction = QAction("New entry", self) self.newEntryAction.setShortcut(QKeySequence.New) self.newEntryAction.triggered.connect(self.addNewEntry) self.removeEntryAction = QAction("Remove entry", self) self.removeEntryAction.setShortcut(QKeySequence.Delete) self.removeEntryAction.triggered.connect(self.removeEntry) self.demoAction = QAction("Demo entry", self) self.demoAction.triggered.connect(self.addDemoEntry) self.printAction = QAction("Print Preview...", self) self.printAction.triggered.connect(self.printPreview) self.zoomInAction = QAction("Zoom In", self) self.zoomInAction.setShortcut(QKeySequence.ZoomIn) self.zoomInAction.triggered.connect(self.zoomIn) self.zoomOutAction = QAction("Zoom Out", self) self.zoomOutAction.setShortcut(QKeySequence.ZoomOut) self.zoomOutAction.triggered.connect(self.zoomOut) self.ui.ganttView.leftView().setContextMenuPolicy(Qt.CustomContextMenu) self.ui.ganttView.leftView().addAction(self.newEntryAction) self.ui.ganttView.leftView().addAction(self.removeEntryAction) menuBar = QMenuBar(self) self.setMenuBar(menuBar) entryMenu = menuBar.addMenu("Entry") entryMenu.addAction(self.newEntryAction) entryMenu.addAction(self.removeEntryAction) entryMenu.addSeparator() entryMenu.addAction(self.demoAction) entryMenu.addSeparator() entryMenu.addAction(self.printAction) zoomMenu = menuBar.addMenu("Zoom") zoomMenu.addAction(self.zoomInAction) zoomMenu.addAction(self.zoomOutAction) ##self.enableActions(QItemSelection()) def initItemDelegate(self): delegate = EntryDelegate(self.constraintModel, self) self.ui.ganttView.leftView().setItemDelegate(delegate) def initGrid(self): self.grid = DateTimeGrid() self.grid.setDayWidth(self.dayWidth) self.ui.ganttView.setGrid(self.grid) def showContextMenu(self, pos): if not self.ui.ganttView.leftView().indexAt(pos).isValid(): self.ui.ganttView.selectionModel().clearSelection() menu = QMenu(self.ui.ganttView.leftView()) menu.addAction(self.newEntryAction) menu.addAction(self.removeEntryAction) menu.exec_(self.ui.ganttView.leftView().viewport().mapToGlobal(pos)) def enableActions(self, selected): if len(selected.indexes()) == 0: self.newEntryAction.setEnabled(True) self.removeEntryAction.setEnabled(False) return selectedIndex = selected.indexes()[0] dataType = self.model.data(self.model.index(selectedIndex.row(), 1)) if dataType in [KDGantt.TypeEvent, KDGantt.TypeTask]: self.newEntryAction.setEnabled(False) self.removeEntryAction.setEnabled(True) return self.newEntryAction.setEnabled(True) self.removeEntryAction.setEnabled(True) def addNewEntry(self): dialog = EntryDialog(self.model) dialog.setWindowTitle("New Entry") if dialog.exec_() == QDialog.Rejected: dialog = None return selectedIndexes = self.ui.ganttView.selectionModel().selectedIndexes() if len(selectedIndexes) > 0: parent = selectedIndexes[0] else: parent = QModelIndex() if not self.model.insertRow(self.model.rowCount(parent), parent): return row = self.model.rowCount(parent) - 1 if row == 0 and parent.isValid(): self.model.insertColumns(self.model.columnCount(paren), 5, parent) self.model.setData(self.model.index(row, 0, parent), dialog.name()) self.model.setData(self.model.index(row, 1, parent), dialog.type()) if dialog.type() != KDGantt.TypeSummary: self.model.setData(self.model.index(row, 2, parent), dialog.startDate(), KDGantt.StartTimeRole) self.model.setData(self.model.index(row, 3, parent), dialog.endDate(), KDGantt.EndTimeRole) self.model.setData(self.model.index(row, 4, parent), dialog.completion()) self.model.setData(self.model.index(row, 5, parent), dialog.legend()) self.addConstraint(dialog.depends(), self.model.index(row, 0, parent)) self.setReadOnly(self.model.index(row, 0, parent), dialog.readOnly()) dialog = None def setReadOnly(self, index, readOnly): row = index.row() parent = index.parent() for column in range(0, 5): item = self.model.itemFromIndex( self.model.index(row, column, parent)) flags = None if readOnly: flags = item.flags() & ~Qt.ItemIsEditable else: flags = item.flags() | Qt.ItemIsEditable item.setFlags(flags) def addConstraint(self, index1, index2): if not index1.isValid() or not index2.isValid(): return c = Constraint(index1, index2) self.ui.ganttView.constraintModel().addConstraint(c) def addConstraintFromItem(self, item1, item2): self.addConstraint(self.model.indexFromItem(item1), self.model.indexFromItem(item2)) def removeEntry(self): selectedIndexes = self.ui.ganttView.selectionModel().selectedIndexes() if len(selectedIndexes) > 0: index = selectedIndexes[0] else: index = QModelIndex() if not index.isValid(): return self.model.removeRow(index.row(), index.parent()) def addDemoEntry(self): softwareRelease = MyStandardItem("Software Release") codeFreeze = MyStandardItem("Code Freeze") codeFreeze.setData(KDGantt.TextPositionRole, StyleOptionGanttItem.Right) packaging = MyStandardItem("Packaging") upload = MyStandardItem("Upload") testing = MyStandardItem("Testing") updateDocumentation = MyStandardItem("Update Documentation") now = QDateTime.currentDateTime() softwareRelease.appendRow([ codeFreeze, MyStandardItem(KDGantt.TypeEvent), MyStandardItem(now, KDGantt.StartTimeRole) ]) softwareRelease.appendRow([ packaging, MyStandardItem(KDGantt.TypeTask), MyStandardItem(now.addDays(5), KDGantt.StartTimeRole), MyStandardItem(now.addDays(10), KDGantt.EndTimeRole) ]) softwareRelease.appendRow([ upload, MyStandardItem(KDGantt.TypeTask), MyStandardItem( now.addDays(10).addSecs(2 * 60 * 60), KDGantt.StartTimeRole), MyStandardItem(now.addDays(11), KDGantt.EndTimeRole) ]) softwareRelease.appendRow([ testing, MyStandardItem(KDGantt.TypeTask), MyStandardItem(now.addSecs(3 * 60 * 60), KDGantt.StartTimeRole), MyStandardItem(now.addDays(5), KDGantt.EndTimeRole) ]) softwareRelease.appendRow([ updateDocumentation, MyStandardItem(KDGantt.TypeTask), MyStandardItem(now.addSecs(3 * 60 * 60), KDGantt.StartTimeRole), MyStandardItem(now.addDays(3), KDGantt.EndTimeRole) ]) self.model.appendRow( [softwareRelease, MyStandardItem(KDGantt.TypeSummary)]) self.addConstraintFromItem(codeFreeze, packaging) self.addConstraintFromItem(codeFreeze, testing) self.addConstraintFromItem(codeFreeze, updateDocumentation) self.addConstraintFromItem(packaging, upload) self.addConstraintFromItem(testing, packaging) self.addConstraintFromItem(updateDocumentation, packaging) def zoomIn(self): self.dayWidth += 10 if self.dayWidth > 400: self.grid.setScale(DateTimeGrid.ScaleHour) self.grid.setDayWidth(self.dayWidth) def zoomOut(self): self.dayWidth -= 10 if self.dayWidth < 10: self.dayWidth = 10 if self.dayWidth <= 400: self.grid.setScale(DateTimeGrid.ScaleDay) self.grid.setDayWidth(self.dayWidth) def printPreview(self): preview = QLabel(self, Qt.Window) preview.setAttribute(Qt.WA_DeleteOnClose) preview.setScaledContents(True) preview.setWindowTitle("Print Preview") pix = QPixmap(1000, 300) pix.fill(Qt.white) p = QPainter(pix) p.setRenderHints(QPainter.Antialiasing) self.ui.ganttView.print_(p, pix.rect()) preview.setPixmap(pix) preview.show() def slotClicked(self, index): self.statusBar().showMessage( "(%d,%d,_,%s) clicked" % (index.row(), index.column(), index.model())) def slotDoubleClicked(self, index): self.statusBar().showMessage( "(%d,%d,_,%s) qreal clicked" % (index.row(), index.column(), index.model()))
class MyWidget(QWidget): def __init__(self): super(MyWidget, self).__init__(None) self.view = View() self.grid = DateTimeGrid() self.slider = QSlider() self.model = QStandardItemModel() self.cmodel = ConstraintModel() for h in range(0, 19): topitem = MyStandardItem("Top Item " + str(h)) for i in range(0, 19): item = MyStandardItem("Multi Item " + str(i)) for j in range(0, 29, 3): item.appendRow([ MyStandardItem("Item " + str(j)), MyStandardItem(KDGantt.TypeTask), MyStandardItem(QDateTime.currentDateTime().addDays(j), KDGantt.StartTimeRole), MyStandardItem( QDateTime.currentDateTime().addDays(j + 1 + i / 7), KDGantt.EndTimeRole), MyStandardItem(50) ]) item.appendRow([ MyStandardItem("Event"), MyStandardItem(KDGantt.TypeEvent), MyStandardItem(QDateTime.currentDateTime(), KDGantt.StartTimeRole), MyStandardItem(QDateTime(), KDGantt.EndTimeRole), MyStandardItem("") ]) topitem.appendRow([ item, MyStandardItem(KDGantt.TypeMulti), MyStandardItem(""), MyStandardItem(""), MyStandardItem("") ]) self.model.appendRow([ topitem, MyStandardItem(KDGantt.TypeMulti), MyStandardItem(""), MyStandardItem(""), MyStandardItem("") ]) self.model.appendRow([MyStandardItem("No data")]) ##cmodel.addConstraint( KDGantt::Constraint( proxyModel.index( 0, 3 ), proxyModel.index( 10, 3 ) ) ); ##cmodel.addConstraint( KDGantt::Constraint( proxyModel.index( 10, 3 ), proxyModel.index( 5, 3 ) ) ); pidx = self.model.index(0, 0) pidx = self.model.index(0, 0, pidx) self.cmodel.addConstraint( Constraint(self.model.index(0, 0, pidx), self.model.index(1, 0, pidx))) self.cmodel.addConstraint( Constraint(self.model.index(1, 0, pidx), self.model.index(0, 0, pidx))) self.cmodel.addConstraint( Constraint(self.model.index(1, 0, pidx), self.model.index(10, 0, pidx))) self.cmodel.addConstraint( Constraint(self.model.index(3, 0, pidx), self.model.index(5, 0, pidx))) self.cmodel.addConstraint( Constraint(self.model.index(7, 0, pidx), self.model.index(4, 0, pidx))) self.slider.setOrientation(Qt.Horizontal) self.slider.setRange(1, 10000) self.slider.setValue(100) l = QVBoxLayout(self) l.addWidget(self.view) l.addWidget(self.slider) self.grid.setStartDateTime(QDateTime.currentDateTime().addDays(-3)) self.grid.setDayWidth(100) ##grid.setNoInformationBrush( Qt::NoBrush ); self.view.setGrid(self.grid) self.view.setModel(self.model) ##view.setConstraintModel( &cmodel ); self.slider.valueChanged.connect(self.slotZoom) pb1 = QPushButton("Print Preview...", self) pb2 = QPushButton("Print...", self) l.addWidget(pb1) l.addWidget(pb2) pb1.clicked.connect(self.slotPrintPreview) pb2.clicked.connect(self.slotPrint) gv = self.view.graphicsView() gv.setHeaderContextMenuPolicy(Qt.CustomContextMenu) gv.headerContextMenuRequested.connect(self.slotHeaderMenu) def slotZoom(self, z): self.grid.setDayWidth(z) def slotPrintPreview(self): pix = QPixmap(1000, 200) pix.fill(Qt.white) painter = QPainter(pix) view.print(painter, pix.rect()) painter.end() label = QLabel(this) label.setPixmap(pix) label.show() def slotPrint(self): printer = QPrinter(QPrinter.HighResolution) pd = QPrintDialog(printer, self) if pd.exec_() == QDialog.Accepted: r = self.view.graphicsView().mapToScene( self.view.graphicsView().viewport().rect()).boundingRect() self.view.print(printer, r.left(), r.right()) def slotHeaderMenu(self, pt): menu = QMenu() menu.addAction("This") menu.addAction("is") menu.addAction("just") menu.addAction("a") menu.addAction("test") menu.exec_(pt)
class MyWidget(QWidget): def __init__(self, parent=None): super(MyWidget, self).__init__(parent) self.view = View() self.grid = DateTimeGrid() self.slider = QSlider(self) self.model = QStandardItemModel(self) self.cmodel = ConstraintModel() ## proxyModel.setSourceModel( &model ); for i in range(0, 10): item = MyStandardItem("Multi Item " + str(i)) for j in range(0, 20, 3): item.appendRow([ MyStandardItem("Item " + str(j)), MyStandardItem(KDGantt.TypeTask), MyStandardItem(QDateTime.currentDateTime().addDays(j), KDGantt.StartTimeRole), MyStandardItem( QDateTime.currentDateTime().addDays(j + 1 + i / 7), KDGantt.EndTimeRole), MyStandardItem(50) ]) item.appendRow([ MyStandardItem("Event"), MyStandardItem(KDGantt.TypeEvent), MyStandardItem(QDateTime.currentDateTime(), KDGantt.StartTimeRole), MyStandardItem(QDateTime(), KDGantt.EndTimeRole), MyStandardItem("") ]) self.model.appendRow([ item, MyStandardItem(KDGantt.TypeMulti), MyStandardItem(""), MyStandardItem(""), MyStandardItem("") ]) pidx = self.model.index(0, 0) pidx = self.model.index(0, 0, pidx) self.cmodel.addConstraint( Constraint(self.model.index(0, 0, pidx), self.model.index(1, 0, pidx))) self.cmodel.addConstraint( Constraint(self.model.index(1, 0, pidx), self.model.index(0, 0, pidx))) self.cmodel.addConstraint( Constraint(self.model.index(1, 0, pidx), self.model.index(10, 0, pidx))) self.cmodel.addConstraint( Constraint(self.model.index(3, 0, pidx), self.model.index(5, 0, pidx))) self.cmodel.addConstraint( Constraint(self.model.index(7, 0, pidx), self.model.index(4, 0, pidx))) self.slider.setOrientation(Qt.Horizontal) self.slider.setRange(1, 1000) self.slider.setValue(100) l = QVBoxLayout(self) l.addWidget(self.view) l.addWidget(self.slider) self.grid.setStartDateTime(QDateTime.currentDateTime().addDays(-3)) self.grid.setDayWidth(100) self.grid.setFreeDays([Qt.Saturday, Qt.Sunday]) self.grid.setFreeDaysBrush(QBrush(Qt.red)) lv = MyListView(self) self.view.setLeftView(lv) self.view.setRowController( ListViewRowController(lv, self.view.ganttProxyModel())) self.view.setGrid(self.grid) self.view.setModel(self.model) ##view.setConstraintModel( &cmodel ); self.slider.valueChanged.connect(self.slotZoom) def slotZoom(self, z): self.grid.setDayWidth(z)