《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>

 

 

 

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