practical model view programming
DESCRIPTION
TRANSCRIPT
PRA CT ICA L M OD EL V IEW PROGRA M M IN GCOD E LESS. V IEW M ORE.
Marius Bugge Monsen,MSc (NTNU),Software Developer
Contents
● An Overview of the Q t Model View Architecture● An Introduction to The Model Interface● Advanced Model View Techniques (Q t 4.1+)
A n Overview of the Q t M odel View A rchitecture
M odel
View
Change N otifi cations
Item Selections
U ser Input
Item D elegate
D ata Changes
U ser Input
Item Selection State
Tree W idgetTable W idget List W idget
Item B ased Views (Qt 3 and 4)
Item Selections
M odel
View View
int main(int argc, char *argv[]){
QApplication app(argc, argv);QDirModel model;QTableView view1;QTreeView view2;
view1.setModel(&model);view2.setModel(&model);
view1.setRootIndex(model.index(0, 0));view1.show();view2.show();app.exec();
}
Effi ciency
W hat do you get ?
Flexibility
Maintainability
A n Introduction To T he M odel Interface
class ListModel : public QAbstractListModel{
Q_OBJECTpublic:
ListModel(QObject *parent = 0);~ListModel();
int rowCount(const QModelIndex &parent) const;QVariant data(const QModelIndex &index, int role) const;
};
ListModel::ListModel(QObject *parent): QAbstractListModel(parent) {}
ListModel::~ListModel() {}
int ListModel::rowCount(const QModelIndex &) const{
return 10000;}
QVariant ListModel::data(const QModelIndex &index, int role) const
{if (role == Qt::DisplayRole)
return index.row();return QVariant();
}
0
0
1
2
0
1
2
0 1 2
int main(int, char *[]){
ListModel model;
QModelIndex index = model.index(2);QVariant data = model.data(index, Qt::DisplayRole);
qDebug() << data;}
D ecoration Role
D isplay Role
M y W orld
Type: Image File Size: 1.2 Mb
ToolT ip Role
QVariant ListModel::data(const QModelIndex &index, int role) const
{if (role == Qt::DisplayRole)
return index.row();
if (role == Qt::DecorationRole)return QColor(Qt::green);
return QVariant();}
class ColorDelegate : public QItemDelegate{ Q_OBJECTpublic: ColorDelegate(QObject *parent = 0);protected: void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;};
void ColorDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const{ const QAbstractItemModel *model = index.model();
QVariant decoration = model->data(index, Qt::DecorationRole); if (decoration.type() == QVariant::Color) { QLinearGradient gradient(option.rect.left(), 0, option.rect.width(), 0); QColor left = option.palette.color(QPalette::Background); gradient.setColorAt(0, left); QColor right = qvariant_cast<QColor>(decoration); gradient.setColorAt(1, right); painter->fillRect(option.rect, gradient); } QItemDelegate::paint(painter, option, index);}
One 100 -300 500Two 599 300 233Three 33 -34 -55Four 200 502 200
class TableModel : public QAbstractTableModel{
Q_OBJECTpublic:
TableModel(QObject *parent = 0);~TableModel();int rowCount(const QModelIndex &parent) const;int columnCount(const QModelIndex &parent) const;QVariant data(const QModelIndex &index, int role) const;bool setData(const QModelIndex &index,
const QVariant &value, int role);Qt::ItemFlags flags(const QModelIndex &index) const;// not part of the model interfacebool load(const QString &fileName);bool save(const QString &fileName) const;
private:int rows, columns;QVector<QVariant> table;
};
QVariant TableModel::data(const QModelIndex &index, int role) const
{int i = index.row() * columns + index.column();QVariant value = table.at(i);
if (role == Qt::EditRole || role == Qt::DisplayRole)return value;
if (role == Qt::TextColorRole&& value.type() == QVariant::Int) {
if (value.toInt() < 0)return QColor(Qt::red);return QColor(Qt::blue);
}return QVariant();
}
bool TableModel::setData(const QModelIndex &index, const QVariant &value, int role)
{int i = index.row() * columns + index.column();if (role == Qt::EditRole) {
table[i] = value;QModelIndex topLeft = index;QModelIndex bottomRight = index;emit dataChanged(topLeft, bottomRight);// <<< important!return true;
}return false;
}Qt::ItemFlags TableModel::flags(const QModelIndex &index) const{
return QAbstractTableModel::flags(index)|Qt::ItemIsEditable;}
bool TableModel::load(const QString &fileName){
QFile file(fileName);if (!file.open(QIODevice::ReadOnly|QIODevice::Text))
return false;rows = columns = 0;table.clear();QTextStream in(&file);bool result = parse(in);
reset();// <<< important!
return result;}
A dvanced M odel V iew Techniques (Qt 4.1+)
M odel Proxy View
M odel Sorting View
int main(int argc, char *argv[]){
QApplication app(argc, argv);TableModel model;model.load("table.data");
QSortingProxyModel sorter;sorter.setSourceModel(&model);QTreeView treeview;treeview.setModel(&sorter);
treeview.header()->setClickable(true);treeview.header()->setSortIndicatorShown(true);treeview.show();return app.exec();
}
M odel Filtering View
int main(int argc, char *argv[]){
QApplication app(argc, argv);QWidget widget;QBoxLayout *layout = new QBoxLayout(QBoxLayout::TopToBottom,
&widget);QLineEdit *lineedit = new QLineEdit;layout->addWidget(lineedit);TableModel model;model.load("table.data");QStringFilterModel filter;filter.setSourceModel(&model);QObject::connect(lineedit,SIGNAL(textChanged(const QString&)),
&filter,SLOT(setPattern(const QString&)));QTableView *tableview = new QTableView;tableview->setModel(&filter);layout->addWidget(tableview);widget.show();return app.exec();
}
A ggregating View
M odel 1
M odel 2
int main(int argc, char *argv[]){ QApplication app(argc, argv); QTreeView treeview; QStringListModel model_1(QStringList() << "ALPHA" << "BRAVO" << "CHARLIE" << "DELTA"); QDirModel model_2; QAggregatingProxyModel aggregator; aggregator.appendSourceModel(&model_1); aggregator.appendSourceModel(&model_2); treeview.setModel(&aggregator); treeview.show(); return app.exec();}
● Qt Model View Architecture O verview
● The Model Interface Introduction● Advanced Techniques Using the Model Interface
W hat we have covered
http://doc.trolltech.com/4.0/model-view-programming.html
http://doc.trolltech.com/4.0/model-view.html
M ore Information