《C++ GUI Qt 4 编程》 笔记(三)

第10章 项视图类

MVC
模型代表数据集,它对需要查看数据的获取以及任何存储的改变负责。
每种类型的数据集都有自己的模型,但不管底层的数据集是什么样子,模型提供给视图的API都是相同的。
视图代表的是面向用户的那些数据。
控制器是用户和视图之间的媒介,它把用户的操作转换为浏览或者编辑数据的请求,这部分数据是根据需要由视图传送给模型的数据。

通过把一个模型注册到两个或者多个视图,就可以让用户使用不同的方式查看数据以及和数据交互。

Qt对于多个视图会自动保持同步,对一个视图的改变会影响到全部视图。

例如:QTableView和QSqlTableModel可以组合在一起使用。

QTableWidget::setHorizontalHeaderLabels()
tableWidget->item(row, 0)->setText(...);

QDialog::done()

treeWidget = new QTreeWidget;
treeWidget->setColumnCount(2);
treeWidget->setHeaderLabels(...);
treeWidget->header()->setResizeMode(0, QHeaderView::Stretch);
treeWidget->sortByColumn(0);
treeWidget->setFocus();

预定义模型类
QStringListModel 字符串列表
QStandardItemModel 任意的分层次的数据
QDirModel 封装本地文件系统
QSqlQueryModel 封装一个SQL结果集
QSqlTableModel SQL表
QSqlRelationTableModel 利用外键封装一个SQL表
QSortFilterProxyModel 排序筛选另一个模型

model = new QStringListModel(this/*dialog*/);
model->setStringList(leaders);
listView = new QListView;
listView->setModel(model);
listView->setEditTriggers(QAbstractItemView::AnyKeyPressed | QAbstractItemView::DoubleClicked);
// 添加删除修改模型,会自动同步到视图
// insert槽
int row = listView->currentIndex().row();
model->insertRows(row, 1);
QModelIndex index = model->index(row);
listView->setCurrentIndex(index);
listView->edit(index);

QRegExp::PatternSyntax syntax = ...;
QRegExp regExp(text, Qt::CaseInsensitive, syntax);

自定义模型
reset() 告诉任何一个使用这个模型的视图,它们所有的数据都无效了

在模型中调用emit dataChanged()将通知视图更新

委托delegate 为MVC中的控制器
设置到视图上

QAbstractItemDelegate
createEditor()
setEditorData()
setModelData()
paint()

假设一个表视图,某些单元格显示的是时间,当编辑时需要显示一个时间控件,某些单元格需要显示一个下拉列表框
重写createEditor()创建一个所需的编辑控件
重写setEditorData()将模型数据设置到编辑控件
重写setModelData()将编辑控件中的值设置到模型数据
第11章 容器类

可以使用STL
也可以使用Qt容器类
Qt容器类
1. 在所有平台表现一致
2. 易于使用的迭代器类
3. 在Qt/Embedded Linux支持的一些硬件平台上,通常只能使用Qt容器

QVector<T>
QVector<double> vect(3); // 初始大小
vect[0] = 1.0;
vect.append(1.0);
vect << 1.0 << 2.0;
for (int i=0; i<vect.count(); ++i)
	// ...

QLinkedList<T>
QLinkedList<QString>::iterator i = list.find("Ramones");
list.insert(i, "Tote Hosen");

QList<T> 结合了以上两个容器的优点,支持随机访问。

QStringList 是QList<QString>的子类

QStack<T>
QQueue<T>

派生自QObject的Qt类无法放入以上容器中,因为没有复制构造函数和赋值操作符

java风格的迭代器:
只读迭代器
QVectorIterator<T>
QLinkedListIterator<T>
QListIterator<T>
读写迭代器
QMutableVectorIterator<T>
...

QList<double> list;
QListIterator<double> i(list);
while (i.hasNext())
do_something(i.next());
// remove总是对最后被跳过的项进行操作
QMutableListIterator<double> i(list);
while (i.hasNext())
if (i.next() < 0.0)
i.remove(); // i.setValue(...)

STL风格迭代器
QList<T>::iterator
QList<T>::const_iterator
QList<T>::begin()

Qt对所有的容器和许多其他类都使用隐含共享,包括QByteArray QBrush QFont QImage QPixmap QString,这使得这些类不论是作为函数参数还是作为返回值,都可以非常有效地传递。

编程习惯:
使用at()而不是[]操作符,原因:为了使隐含共享的作用发挥得最好
STL风格迭代器尽量使用const_iterator constBegin() constEnd()

QMap<K, T> // K类型必须提供operator<()
QMultiMap<K, T>
QHash<K, T> // 更快的查找速度,operator==()
// 为键值提供返回哈希值的全局qHash()函数
QCache<K, T>
QSet<K>

QMap<QString, int> map;
map.insert("eins", 1);
map["sieben"] = 7; // 如果项不存在则创建一个新的项
int val = map.value("abc"); // 如果项不存在则返回默认值,不创建新项

// 分别返回键和值的QList
QMap<K, T>::keys()
QMap<K, T>::values()

遍历

QMap<QString, int> map;
QMapIterator<QString, int> i(map);
while (i.hasNext())
{
	// i.next().value();
	i.next();
	QString key = i.key();
	int value = i.value();
}

foreach (QString key, map.keys())
{
	foreach (int value, map.values(key))
		do_something(key, value);
}

通用算法
<QtAlgorithms>
大部分都是在STL风格迭代器上工作

STL的<algorithm>也可以用在Qt容器类上

qFind()
qBinaryFind() 假设项都是以升序的顺序排序
qFill()
qCopy()
qSort() 小于号,也可以用qGreater<T>()
qStableSort() 稳定排序,相同的项排序后顺序不变
qDeleteAll() 对容器中的指针调用delete
qSwap()

<QtGlobal>
qAbs() 绝对值
qMin()
qMax()

格式化字符串

QString str;
str.sprintf("%s %.1f%%", "perfect competition", 100.0);
str = QString("%1 %2").arg("permissive").arg("society");

arg()的重载可以处理各种类型

数字转为字符串

str = QString::number(59.6);
str.setNum(59.6);

字符串转为数字

str.toInt();
str.toLongLong();
str.toDouble();

在控制台上打印
qDebug() << str; <QtDebug>

str.mid()
str.left() str.right()
str.indexOf()
str.startsWith()
str.endsWith()
str.toLower()
str.replace()
str.remove()
str.insert()
str.trimmed()
str.simplified() 去掉头尾的空格,中间的连续空格只留一个空格
str.split()
strList.join() QStringList
str.isEmpty()
str.length()
str.fromAscii() str.toAscii()
qPrintable(str) => str.toAscii().constData()

QByteArray对于存储原始的二进制数据以及8位编码的文本字符串非常有用。

QVariant 以降低效率及可读性为代价

QPair<T1, T2>

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章