(C++) QTreeViewExample3
February 24, 2017 · View on GitHub
(C++) QTreeViewExample3



QTreeView example 3: improved undo/redo and added drag/drop is an example to use a QTreeView.
- View a screenshot of 'CppQTreeViewExample3' (png)
- Download the Qt Creator project 'CppQTreeViewExample3' (zip)
Technical facts
Operating system(s) or programming environment(s)
Lubuntu 15.04 (vivid)
Qt Creator 3.1.1
- G++ 4.9.2
Libraries used:
Qt project file: ./CppQTreeViewExample3/CppQTreeViewExample3.pro
QT += core gui greaterThan(QT_MAJOR_VERSION, 4): QT += widgets TEMPLATE = app SOURCES += \ qtdialog.cpp \ qtmain.cpp \ qtaddrowcommand.cpp \ qtmytreeview.cpp \ qtmyitem.cpp HEADERS += qtdialog.h \ qtaddrowcommand.h \ qtmytreeview.h \ qtmyitem.h FORMS += qtdialog.ui
./CppQTreeViewExample3/qtaddrowcommand.h
#ifndef QTADDROWCOMMAND_H #define QTADDROWCOMMAND_H #include <QModelIndex> #include <QUndoCommand> struct QStandardItemModel; struct QAbstractItemView; struct QtAddRowCommand : public QUndoCommand { QtAddRowCommand( QStandardItemModel * const model, QAbstractItemView * const view, const std::string& text = ""); void redo(); void undo(); private: QStandardItemModel * const m_model; const QModelIndex m_prev_index; std::string m_text; QAbstractItemView * const m_view; }; #endif // QTADDROWCOMMAND_H
./CppQTreeViewExample3/qtaddrowcommand.cpp
#include "qtaddrowcommand.h" #include <QAbstractItemModel> #include <QAbstractItemView> #include <QStandardItemModel> #include "qtmyitem.h" QtAddRowCommand::QtAddRowCommand( QStandardItemModel * const model, QAbstractItemView * const view, const std::string& text) : m_model(model), m_prev_index(view->currentIndex()), m_text(text), m_view(view) { } void QtAddRowCommand::redo() { QtMyItem * const item = new QtMyItem(m_text.c_str()); item->setText(m_text.c_str()); m_model->appendRow(item); m_view->setCurrentIndex(item->index()); this->setText("Added row at index " + QString::number(item->index().row())); } void QtAddRowCommand::undo() { const int n_rows = m_model->rowCount(); QtMyItem * const item = dynamic_cast<QtMyItem *>(m_model->item(n_rows - 1)); if (item) m_text = item->text().toStdString(); m_model->removeRow(n_rows - 1); m_view->setCurrentIndex(m_prev_index); }
./CppQTreeViewExample3/qtdialog.h
#ifndef QTDIALOG_H #define QTDIALOG_H #include <QDialog> namespace Ui { class QtDialog; } struct QStandardItemModel; struct QUndoStack; struct QtMyTreeView; class QtDialog : public QDialog { Q_OBJECT public: explicit QtDialog(QWidget *parent = 0); ~QtDialog(); protected: void keyPressEvent(QKeyEvent *); private slots: void on_button_clicked(); private: Ui::QtDialog *ui; QStandardItemModel * const m_model; QUndoStack * const m_undo_stack; QtMyTreeView * const m_view; }; #endif // QTDIALOG_H
./CppQTreeViewExample3/qtdialog.cpp
#include "qtdialog.h" #include <cassert> #include <boost/lexical_cast.hpp> #include <QKeyEvent> #include <QStandardItemModel> #include <QStyledItemDelegate> #include <QUndoStack> #include "qtaddrowcommand.h" #include "ui_qtdialog.h" #include "qtmytreeview.h" #include "qtmyitem.h" QtDialog::QtDialog(QWidget *parent) : QDialog(parent), ui(new Ui::QtDialog), m_model(new QStandardItemModel), m_undo_stack(new QUndoStack), m_view(new QtMyTreeView) { ui->setupUi(this); assert(ui->scrollAreaWidgetContents->layout()); ui->scrollAreaWidgetContents->layout()->addWidget(m_view); m_view->setModel(m_model); m_view->setItemDelegate(new QStyledItemDelegate); //Initial the QtMyTreeView with some items for (int i=0; i!=26; ++i) { QtAddRowCommand * const cmd = new QtAddRowCommand( m_model, m_view, boost::lexical_cast<std::string,char>('A' + i)); m_undo_stack->push(cmd); } } QtDialog::~QtDialog() { delete ui; delete m_model; delete m_undo_stack; delete m_view; } void QtDialog::keyPressEvent(QKeyEvent * e) { if (e->key() == Qt::Key_Escape) { close(); return; } if ( (e->modifiers() & Qt::ControlModifier) && !(e->modifiers() & Qt::ShiftModifier) && e->key() == Qt::Key_Z) { m_undo_stack->undo(); return; } if ( (e->modifiers() & Qt::ControlModifier) && (e->modifiers() & Qt::ShiftModifier) && e->key() == Qt::Key_Z) { m_undo_stack->redo(); return; } } void QtDialog::on_button_clicked() { QtAddRowCommand * const cmd = new QtAddRowCommand(m_model,m_view); m_undo_stack->push(cmd); const int n_rows = m_model->rowCount(); QtMyItem * const item = dynamic_cast<QtMyItem*>(m_model->item(n_rows - 1)); assert(item); m_view->edit(item->index()); }
./CppQTreeViewExample3/qtmain.cpp
#include <QApplication> #include "qtdialog.h" int main(int argc, char *argv[]) { QApplication a(argc, argv); QtDialog w; w.show(); return a.exec(); }
./CppQTreeViewExample3/qtmyitem.h
#ifndef QTMYITEM_H #define QTMYITEM_H #include <QStandardItem> struct QtMyItem : public QStandardItem { QtMyItem(const QString &text); }; #endif // QTMYITEM_H
./CppQTreeViewExample3/qtmyitem.cpp
#include "qtmyitem.h" QtMyItem::QtMyItem(const QString &text) : QStandardItem(text) { this->setEditable(true); this->setDragEnabled(true); this->setDropEnabled(true); }
./CppQTreeViewExample3/qtmytreeview.h
#ifndef QTMYTREEVIEW_H #define QTMYTREEVIEW_H #include <QTreeView> struct QtMyTreeView : public QTreeView { QtMyTreeView(QWidget * const parent = 0); }; #endif // QTMYTREEVIEW_H
./CppQTreeViewExample3/qtmytreeview.cpp
#include "qtmytreeview.h" #include <QDragEnterEvent> #include <QDropEvent> #include <QDragMoveEvent> QtMyTreeView::QtMyTreeView(QWidget * const parent) : QTreeView(parent) { this->setAcceptDrops(true); this->setAlternatingRowColors(true); this->setAnimated(true); this->setDragDropMode(QAbstractItemView::InternalMove); this->setDragEnabled(true); this->setDropIndicatorShown(true); this->setExpandsOnDoubleClick(true); this->setHeaderHidden(true); this->setItemsExpandable(true); this->setSelectionMode(QAbstractItemView::SingleSelection); this->setWordWrap(true); }