This example provides an address book that allows contacts to be grouped alphabetically into 9 groups: ABC, DEF, GHI, ... , VW, ..., XYZ. This is achieved by using multiple views on the same model, each of which is filtered using an instance of the QSortFilterProxyModel class.
此示例提供了一個(gè)地址簿,允許將聯(lián)系人按字母順序分組為9組:ABC憎夷,DEF银锻,GHI谆刨,...,VW,...酷窥,XYZ。 這是通過在同一模型上使用多個(gè)視圖來實(shí)現(xiàn)的齐佳,每個(gè)視圖都使用QSortFilterProxyModel類的實(shí)例進(jìn)行過濾增热。
Overview
The address book contains 5 classes: MainWindow, AddressWidget, TableModel, NewAddressTab and AddDialog. The MainWindow class uses AddressWidget as its central widget and provides File and Tools menus.
地址簿包含5個(gè)類:MainWindow顷级、AddressWidget、TableModel错森、NewAddressTab和AddDialog吟宦。MainWindow類使用AddressWidget作為其中心部件,并提供文件和工具菜單涩维。
The AddressWidget class is a QTabWidget subclass that is used to manipulate the 10 tabs displayed in the example: the 9 alphabet group tabs and an instance of NewAddressTab. The NewAddressTab class is a subclass of QWidget that is only used whenever the address book is empty, prompting the user to add some contacts. AddressWidget also interacts with an instance of TableModel to add, edit and remove entries to the address book.
AddressWidget類是一個(gè)QTabWidget子類殃姓,用于操作示例中顯示的10個(gè)選項(xiàng)卡:9個(gè)字母表組選項(xiàng)卡和NewAddressTab實(shí)例。NewAddressTab類是QWidget的一個(gè)子類,它只在地址簿為空時(shí)使用辰狡,提示用戶添加一些聯(lián)系人锋叨。AddressWidget還與TableModel實(shí)例交互,以向地址簿添加宛篇、編輯和刪除條目娃磺。
TableModel is a subclass of QAbstractTableModel that provides the standard model/view API to access data. It also holds a QList of QPairs corresponding to the contacts added. However, this data is not all visible in a single tab. Instead, QTableView is used to provide 9 different views of the same data, according to the alphabet groups.
TableModel是QAbstractTableModel的子類,它提供了訪問數(shù)據(jù)的標(biāo)準(zhǔn)模型/視圖API叫倍。它還包含與添加的聯(lián)系人對(duì)應(yīng)的qpair的QList偷卧。然而,在單個(gè)選項(xiàng)卡中吆倦,這些數(shù)據(jù)并不都是可見的听诸。相反,QTableView被用來提供9個(gè)相同數(shù)據(jù)的不同視圖蚕泽。
QSortFilterProxyModel is the class responsible for filtering the contacts for each group of contacts. Each proxy model uses a QRegExp to filter out contacts that do not belong in the corresponding alphabetical group. The AddDialog class is used to obtain information from the user for the address book. This QDialog subclass is instantiated by NewAddressTab to add contacts, and by AddressWidget to add and edit contacts.
QSortFilterProxyModel是負(fù)責(zé)過濾每組聯(lián)系人的聯(lián)系人的類晌梨。每個(gè)代理模型使用QRegExp過濾掉不屬于相應(yīng)字母組的聯(lián)系人。AddDialog類用于從用戶獲取地址簿的信息须妻。這個(gè)QDialog子類由NewAddressTab實(shí)例化來添加聯(lián)系人仔蝌,由AddressWidget來添加和編輯聯(lián)系人。
We begin by looking at the TableModel implementation.
我們首先看一下TableModel實(shí)現(xiàn)荒吏。
TableModel Class Definition
The TableModel class provides standard API to access data in its QList of QPairs by subclassing QAbstractTableModel. The basic functions that must be implemented in order to do so are: rowCount(), columnCount(), data(), headerData(). For TableModel to be editable, it has to provide implementations insertRows(), removeRows(), setData() and flags() functions.
TableModel類通過子類化QAbstractTableModel敛惊,為訪問其qpair的QList中的數(shù)據(jù)提供了標(biāo)準(zhǔn)API。為此必須實(shí)現(xiàn)的基本函數(shù)有:rowCount()绰更、columnCount()瞧挤、data()、headerData()儡湾。要使TableModel可編輯特恬,它必須提供實(shí)現(xiàn)insertRows()、removeRows()徐钠、setData()和flags()函數(shù)鸵鸥。
class TableModel : public QAbstractTableModel
{
Q_OBJECT
public:
TableModel(QObject *parent = 0);
TableModel(QList<QPair<QString, QString> > listofPairs, QObject *parent = 0);
int rowCount(const QModelIndex &parent) const Q_DECL_OVERRIDE;
int columnCount(const QModelIndex &parent) const Q_DECL_OVERRIDE;
QVariant data(const QModelIndex &index, int role) const Q_DECL_OVERRIDE;
QVariant headerData(int section, Qt::Orientation orientation, int role) const Q_DECL_OVERRIDE;
Qt::ItemFlags flags(const QModelIndex &index) const Q_DECL_OVERRIDE;
bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) Q_DECL_OVERRIDE;
bool insertRows(int position, int rows, const QModelIndex &index = QModelIndex()) Q_DECL_OVERRIDE;
bool removeRows(int position, int rows, const QModelIndex &index = QModelIndex()) Q_DECL_OVERRIDE;
QList<QPair<QString, QString> > getList();
private:
QList<QPair<QString, QString> > listOfPairs;
};
Two constructors are used, a default constructor which uses TableModel's own QList<QPair<QString, QString>> and one that takes QList<QPair<QString, QString> as an argument, for convenience.
使用了兩個(gè)構(gòu)造函數(shù),一個(gè)默認(rèn)構(gòu)造函數(shù)使用TableModel自己的 QList<QPair<QString, QString>> 丹皱,另一個(gè)使用QList<QPair<QString, QString>作為參數(shù),方便使用宋税。
TableModel Class Implementation
We implement the two constructors as defined in the header file. The second constructor initializes the list of pairs in the model, with the parameter value.
我們實(shí)現(xiàn)頭文件中定義的兩個(gè)構(gòu)造函數(shù)摊崭。第二個(gè)構(gòu)造函數(shù)使用參數(shù)值初始化模型中的對(duì)列表。
: QAbstractTableModel(parent)
{
}
TableModel::TableModel(QList<QPair<QString, QString> > pairs, QObject *parent)
: QAbstractTableModel(parent)
{
listOfPairs = pairs;
}
The rowCount() and columnCount() functions return the dimensions of the model. Whereas, rowCount()'s value will vary depending on the number of contacts added to the address book, columnCount()'s value is always 2 because we only need space for the Name and Address columns.
rowCount()和columnCount()函數(shù)返回模型的維度杰赛。然而呢簸,rowCount()的值會(huì)根據(jù)添加到地址簿中的聯(lián)系人的數(shù)量而變化,columnCount()的值總是2,因?yàn)槲覀冎恍枰獮槊Q和地址列留出空間根时。
Note: The Q_UNUSED() macro prevents the compiler from generating warnings regarding unused parameters.
注意:Q_UNUSED() 宏阻止編譯器生成關(guān)于未使用參數(shù)的警告瘦赫。
int TableModel::rowCount(const QModelIndex &parent) const
{
Q_UNUSED(parent);
return listOfPairs.size();
}
int TableModel::columnCount(const QModelIndex &parent) const
{
Q_UNUSED(parent);
return 2;
}
The data() function returns either a Name or Address, based on the contents of the model index supplied. The row number stored in the model index is used to reference an item in the list of pairs. Selection is handled by the QItemSelectionModel, which will be explained with AddressWidget.
函數(shù)的作用是:根據(jù)提供的模型索引的內(nèi)容返回名稱或地址。存儲(chǔ)在模型索引中的行號(hào)用于引用對(duì)列表中的項(xiàng)蛤迎。選擇由QItemSelectionModel處理确虱,它將通過AddressWidget進(jìn)行解釋。
QVariant TableModel::data(const QModelIndex &index, int role) const
{
if (!index.isValid())
return QVariant();
if (index.row() >= listOfPairs.size() || index.row() < 0)
return QVariant();
if (role == Qt::DisplayRole) {
QPair<QString, QString> pair = listOfPairs.at(index.row());
if (index.column() == 0)
return pair.first;
else if (index.column() == 1)
return pair.second;
}
return QVariant();
}
The headerData() function displays the table's header, Name and Address. If you require numbered entries for your address book, you can use a vertical header which we have hidden in this example (see the AddressWidget implementation).
函數(shù)的作用是:顯示表格的標(biāo)題替裆、名稱和地址校辩。如果您需要對(duì)地址簿進(jìn)行編號(hào),那么可以使用我們?cè)诒纠须[藏的垂直標(biāo)題(請(qǐng)參閱AddressWidget實(shí)現(xiàn))辆童。
QVariant TableModel::headerData(int section, Qt::Orientation orientation, int role) const
{
if (role != Qt::DisplayRole)
return QVariant();
if (orientation == Qt::Horizontal) {
switch (section) {
case 0:
return tr("Name");
case 1:
return tr("Address");
default:
return QVariant();
}
}
return QVariant();
}
The insertRows() function is called before new data is added, otherwise the data will not be displayed. The beginInsertRows() and endInsertRows() functions are called to ensure all connected views are aware of the changes.
在添加新數(shù)據(jù)之前調(diào)用insertRows()函數(shù)宜咒,否則將不顯示數(shù)據(jù)。 調(diào)用beginInsertRows()和endInsertRows()函數(shù)以確保所有連接的視圖都知道更改把鉴。
bool TableModel::insertRows(int position, int rows, const QModelIndex &index)
{
Q_UNUSED(index);
beginInsertRows(QModelIndex(), position, position + rows - 1);
for (int row = 0; row < rows; ++row) {
QPair<QString, QString> pair(" ", " ");
listOfPairs.insert(position, pair);
}
endInsertRows();
return true;
}
The removeRows() function is called to remove data. Again, beginRemoveRows() and endRemoveRows() are called to ensure all connected views are aware of the changes.
調(diào)用removeRows()函數(shù)以刪除數(shù)據(jù)故黑。 同樣,調(diào)用beginRemoveRows()和endRemoveRows()以確保所有連接的視圖都知道更改庭砍。
bool TableModel::removeRows(int position, int rows, const QModelIndex &index)
{
Q_UNUSED(index);
beginRemoveRows(QModelIndex(), position, position + rows - 1);
for (int row = 0; row < rows; ++row) {
listOfPairs.removeAt(position);
}
endRemoveRows();
return true;
}
The setData() function is the function that inserts data into the table, item by item and not row by row. This means that to fill a row in the address book, setData() must be called twice, as each row has 2 columns. It is important to emit the dataChanged() signal as it tells all connected views to update their displays.
setData()函數(shù)是將數(shù)據(jù)逐項(xiàng)插入表而不是逐行插入表的函數(shù)场晶。 這意味著要填充地址簿中的一行,必須調(diào)用setData()兩次逗威,因?yàn)槊啃杏?列峰搪。 發(fā)出dataChanged()信號(hào)非常重要,因?yàn)樗嬖V所有連接的視圖更新其顯示凯旭。
bool TableModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
if (index.isValid() && role == Qt::EditRole) {
int row = index.row();
QPair<QString, QString> p = listOfPairs.value(row);
if (index.column() == 0)
p.first = value.toString();
else if (index.column() == 1)
p.second = value.toString();
else
return false;
listOfPairs.replace(row, p);
emit(dataChanged(index, index));
return true;
}
return false;
}
flags()函數(shù)返回給定索引的項(xiàng)標(biāo)志概耻。
Qt::ItemFlags TableModel::flags(const QModelIndex &index) const
{
if (!index.isValid())
return Qt::ItemIsEnabled;
return QAbstractTableModel::flags(index) | Qt::ItemIsEditable;
}
We set the Qt::ItemIsEditable flag because we want to allow the TableModel to be edited. Although for this example we don't use the editing features of the QTableView object, we enable them here so that we can reuse the model in other programs.
我們?cè)O(shè)置了Qt :: ItemIsEditable標(biāo)志,因?yàn)槲覀兿胍试S編輯TableModel罐呼。 雖然在本例中我們不使用QTableView對(duì)象的編輯功能鞠柄,但我們?cè)诖颂巻⒂盟鼈儯员阄覀兛梢栽谄渌绦蛑兄赜迷撃P汀?/p>
The last function in TableModel, getList() returns the QList<QPair<QString, QString>> object that holds all the contacts in the address book. We use this function later to obtain the list of contacts to check for existing entries, write the contacts to a file and read them back. Further explanation is given with AddressWidget.
TableModel中的最后一個(gè)函數(shù)getList()返回保存地址簿中所有聯(lián)系人的QList <QPair <QString嫉柴,QString >>對(duì)象厌杜。 我們稍后使用此功能獲取聯(lián)系人列表以檢查現(xiàn)有條目,將聯(lián)系人寫入文件并將其讀回计螺。 AddressWidget給出了進(jìn)一步的解釋夯尽。
QList< QPair<QString, QString> > TableModel::getList()
{
return listOfPairs;
}
AddressWidget Class Definition
The AddressWidget class is technically the main class involved in this example as it provides functions to add, edit and remove contacts, to save the contacts to a file and to load them from a file.
從技術(shù)上講,AddressWidget類是此示例中涉及的主類登馒,因?yàn)樗峁┝颂砑映孜眨庉嫼蛣h除聯(lián)系人,將聯(lián)系人保存到文件以及從文件加載文件的功能陈轿。
class AddressWidget : public QTabWidget
{
Q_OBJECT
public:
AddressWidget(QWidget *parent = 0);
void readFromFile(const QString &fileName);
void writeToFile(const QString &fileName);
public slots:
void addEntry();
void addEntry(QString name, QString address);
void editEntry();
void removeEntry();
signals:
void selectionChanged (const QItemSelection &selected);
private:
void setupTabs();
TableModel *table;
NewAddressTab *newAddressTab;
QSortFilterProxyModel *proxyModel;
};
AddressWidget extends QTabWidget in order to hold 10 tabs (NewAddressTab and the 9 alphabet group tabs) and also manipulates table, the TableModel object, proxyModel, the QSortFilterProxyModel object that we use to filter the entries, and tableView, the QTableView object.
AddressWidget擴(kuò)展QTabWidget以保存10個(gè)選項(xiàng)卡(NewAddressTab和9個(gè)字母組選項(xiàng)卡)圈纺,還操作表秦忿,TableModel對(duì)象,proxyModel蛾娶,我們用來過濾條目的QSortFilterProxyModel對(duì)象灯谣,以及tableView,QTableView對(duì)象蛔琅。
AddressWidget Class Implementation
The AddressWidget constructor accepts a parent widget and instantiates NewAddressTab, TableModel and QSortFilterProxyModel. The NewAddressTab object, which is used to indicate that the address book is empty, is added and the rest of the 9 tabs are set up with setupTabs().
AddressWidget構(gòu)造函數(shù)接受父窗口小部件并實(shí)例化NewAddressTab胎许,TableModel和QSortFilterProxyModel。 將添加NewAddressTab對(duì)象(用于指示通訊簿為空)揍愁,并使用setupTabs()設(shè)置其余9個(gè)選項(xiàng)卡呐萨。
AddressWidget::AddressWidget(QWidget *parent)
: QTabWidget(parent)
{
table = new TableModel(this);
newAddressTab = new NewAddressTab(this);
connect(newAddressTab, SIGNAL(sendDetails(QString, QString)),
this, SLOT(addEntry(QString, QString)));
addTab(newAddressTab, "Address Book");
setupTabs();
}
The setupTabs() function is used to set up the 9 alphabet group tabs, table views and proxy models in AddressWidget. Each proxy model in turn is set to filter contact names according to the relevant alphabet group using a case-insensitive QRegExp object. The table views are also sorted in ascending order using the corresponding proxy model's sort() function.
setupTabs()函數(shù)用于在AddressWidget中設(shè)置9個(gè)字母組選項(xiàng)卡,表視圖和代理模型莽囤。 每個(gè)代理模型依次設(shè)置為使用不區(qū)分大小寫的QRegExp對(duì)象根據(jù)相關(guān)的字母組過濾聯(lián)系人姓名谬擦。 表視圖也使用相應(yīng)的代理模型的sort()函數(shù)按升序排序。
Each table view's selectionMode is set to QAbstractItemView::SingleSelection and selectionBehavior is set to QAbstractItemView::SelectRows, allowing the user to select all the items in one row at the same time. Each QTableView object is automatically given a QItemSelectionModel that keeps track of the selected indexes.
每個(gè)表視圖的selectionMode設(shè)置為QAbstractItemView :: SingleSelection朽缎,selectionBehavior設(shè)置為QAbstractItemView :: SelectRows惨远,允許用戶同時(shí)選擇一行中的所有項(xiàng)。 每個(gè)QTableView對(duì)象都會(huì)自動(dòng)獲得一個(gè)QItemSelectionModel话肖,用于跟蹤所選索引北秽。
void AddressWidget::setupTabs()
{
QStringList groups;
groups << "ABC" << "DEF" << "GHI" << "JKL" << "MNO" << "PQR" << "STU" << "VW" << "XYZ";
for (int i = 0; i < groups.size(); ++i) {
QString str = groups.at(i);
QString regExp = QString("^[%1].*").arg(str);
proxyModel = new QSortFilterProxyModel(this);
proxyModel->setSourceModel(table);
proxyModel->setFilterRegExp(QRegExp(regExp, Qt::CaseInsensitive));
proxyModel->setFilterKeyColumn(0);
QTableView *tableView = new QTableView;
tableView->setModel(proxyModel);
tableView->setSelectionBehavior(QAbstractItemView::SelectRows);
tableView->horizontalHeader()->setStretchLastSection(true);
tableView->verticalHeader()->hide();
tableView->setEditTriggers(QAbstractItemView::NoEditTriggers);
tableView->setSelectionMode(QAbstractItemView::SingleSelection);
tableView->setSortingEnabled(true);
connect(tableView->selectionModel(),
SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
this, SIGNAL(selectionChanged(QItemSelection)));
addTab(tableView, str);
}
}
The QItemSelectionModel class provides a selectionChanged signal that is connected to AddressWidget's selectionChanged() signal. This signal to signal connection is necessary to enable the Edit Entry... and Remove Entry actions in MainWindow's Tools menu. This connection is further explained in MainWindow's implementation.
QItemSelectionModel類提供一個(gè)selectionChanged信號(hào),該信號(hào)連接到AddressWidget的selectionChanged()信號(hào)最筒。 此信號(hào)與信號(hào)連接是在MainWindow的“工具”菜單中啟用“編輯條目...”和“刪除條目”操作所必需的贺氓。 MainWindow的實(shí)現(xiàn)進(jìn)一步解釋了這種聯(lián)系。
Each table view in the address book is added as a tab to the QTabWidget with the relevant label, obtained from the QStringList of groups.
地址簿中的每個(gè)表視圖都作為選項(xiàng)卡添加到QTabWidget床蜘,其中包含從組的QStringList獲取的相關(guān)標(biāo)簽辙培。
We provide 2 addEntry() functions: 1 which is intended to be used to accept user input, and the other which performs the actual task of adding new entries to the address book. We divide the responsibility of adding entries into two parts to allow newAddressTab to insert data without having to popup a dialog.
我們提供了2個(gè)addEntry()函數(shù):1用于接受用戶輸入,另一個(gè)用于執(zhí)行向地址簿添加新條目的實(shí)際任務(wù)邢锯。 我們將添加條目的責(zé)任分為兩部分扬蕊,以允許newAddressTab插入數(shù)據(jù)而無需彈出對(duì)話框。
The first addEntry() function is a slot connected to the MainWindow's Add Entry... action. This function creates an AddDialog object and then calls the second addEntry() function to actually add the contact to table.
第一個(gè)addEntry()函數(shù)是連接到MainWindow的Add Entry ...動(dòng)作的插槽丹擎。 此函數(shù)創(chuàng)建AddDialog對(duì)象尾抑,然后調(diào)用第二個(gè)addEntry()函數(shù)以實(shí)際將聯(lián)系人添加到表。
void AddressWidget::addEntry()
{
AddDialog aDialog;
if (aDialog.exec()) {
QString name = aDialog.nameText->text();
QString address = aDialog.addressText->toPlainText();
addEntry(name, address);
}
}
Basic validation is done in the second addEntry() function to prevent duplicate entries in the address book. As mentioned with TableModel, this is part of the reason why we require the getter method getList().
基本驗(yàn)證在第二個(gè)addEntry()函數(shù)中完成蒂培,以防止地址簿中的重復(fù)條目再愈。 正如TableModel所提到的,這是我們需要getter方法getList()的部分原因护戳。
void AddressWidget::addEntry(QString name, QString address)
{
QList<QPair<QString, QString> >list = table->getList();
QPair<QString, QString> pair(name, address);
if (!list.contains(pair)) {
table->insertRows(0, 1, QModelIndex());
QModelIndex index = table->index(0, 0, QModelIndex());
table->setData(index, name, Qt::EditRole);
index = table->index(0, 1, QModelIndex());
table->setData(index, address, Qt::EditRole);
removeTab(indexOf(newAddressTab));
} else {
QMessageBox::information(this, tr("Duplicate Name"),
tr("The name \"%1\" already exists.").arg(name));
}
}
If the model does not already contain an entry with the same name, we call setData() to insert the name and address into the first and second columns. Otherwise, we display a QMessageBox to inform the user.
如果模型尚未包含具有相同名稱的條目践磅,我們調(diào)用setData()將名稱和地址插入第一列和第二列。 否則灸异,我們會(huì)顯示一個(gè)QMessageBox來通知用戶府适。
Note: The newAddressTab is removed once a contact is added as the address book is no longer empty.
注意:添加聯(lián)系人后將刪除newAddressTab,因?yàn)橥ㄓ嵅静辉贋榭铡?/p>
Editing an entry is a way to update the contact's address only, as the example does not allow the user to change the name of an existing contact.
編輯條目是一種僅更新聯(lián)系人地址的方法肺樟,因?yàn)樵撌纠辉试S用戶更改現(xiàn)有聯(lián)系人的姓名檐春。
Firstly, we obtain the active tab's QTableView object using QTabWidget::currentWidget(). Then we extract the selectionModel from the tableView to obtain the selected indexes.
首先,我們使用QTabWidget :: currentWidget()獲取活動(dòng)選項(xiàng)卡的QTableView對(duì)象么伯。 然后我們從tableView中提取selectionModel以獲取所選索引疟暖。
void AddressWidget::editEntry()
{
QTableView *temp = static_cast<QTableView*>(currentWidget());
QSortFilterProxyModel *proxy = static_cast<QSortFilterProxyModel*>(temp->model());
QItemSelectionModel *selectionModel = temp->selectionModel();
QModelIndexList indexes = selectionModel->selectedRows();
QString name;
QString address;
int row = -1;
foreach (QModelIndex index, indexes) {
row = proxy->mapToSource(index).row();
QModelIndex nameIndex = table->index(row, 0, QModelIndex());
QVariant varName = table->data(nameIndex, Qt::DisplayRole);
name = varName.toString();
QModelIndex addressIndex = table->index(row, 1, QModelIndex());
QVariant varAddr = table->data(addressIndex, Qt::DisplayRole);
address = varAddr.toString();
}
接下來,我們從用戶想要編輯的行中提取數(shù)據(jù)田柔。 此數(shù)據(jù)顯示在具有不同窗口標(biāo)題的AddDialog實(shí)例中俐巴。 只有在對(duì)dialog中的數(shù)據(jù)進(jìn)行了更改時(shí),才會(huì)更新該表硬爆。
AddDialog aDialog;
aDialog.setWindowTitle(tr("Edit a Contact"));
aDialog.nameText->setReadOnly(true);
aDialog.nameText->setText(name);
aDialog.addressText->setText(address);
if (aDialog.exec()) {
QString newAddress = aDialog.addressText->toPlainText();
if (newAddress != address) {
QModelIndex index = table->index(row, 1, QModelIndex());
table->setData(index, newAddress, Qt::EditRole);
}
}
}
Entries are removed using the removeEntry() function. The selected row is removed by accessing it through the QItemSelectionModel object, selectionModel. The newAddressTab is re-added to the AddressWidget only if the user removes all the contacts in the address book.
使用removeEntry()函數(shù)刪除條目欣舵。 通過QItemSelectionModel對(duì)象,selectionModel訪問選定的行缀磕。 僅當(dāng)用戶刪除通訊簿中的所有聯(lián)系人時(shí)缘圈,newAddressTab才會(huì)重新添加到AddressWidget。
void AddressWidget::removeEntry()
{
QTableView *temp = static_cast<QTableView*>(currentWidget());
QSortFilterProxyModel *proxy = static_cast<QSortFilterProxyModel*>(temp->model());
QItemSelectionModel *selectionModel = temp->selectionModel();
QModelIndexList indexes = selectionModel->selectedRows();
foreach (QModelIndex index, indexes) {
int row = proxy->mapToSource(index).row();
table->removeRows(row, 1, QModelIndex());
}
if (table->rowCount(QModelIndex()) == 0) {
insertTab(0, newAddressTab, "Address Book");
}
}
The writeToFile() function is used to save a file containing all the contacts in the address book. The file is saved in a custom .dat format. The contents of the QList of QPairs are written to file using QDataStream. If the file cannot be opened, a QMessageBox is displayed with the related error message.
writeToFile()函數(shù)用于保存包含通訊簿中所有聯(lián)系人的文件袜蚕。 該文件以自定義.dat格式保存糟把。 使用QDataStream將QPairs的QList的內(nèi)容寫入文件。 如果無法打開文件牲剃,則會(huì)顯示QMessageBox以及相關(guān)的錯(cuò)誤消息遣疯。
void AddressWidget::writeToFile(const QString &fileName)
{
QFile file(fileName);
if (!file.open(QIODevice::WriteOnly)) {
QMessageBox::information(this, tr("Unable to open file"), file.errorString());
return;
}
QList<QPair<QString, QString> > pairs = table->getList();
QDataStream out(&file);
out << pairs;
}
The readFromFile() function loads a file containing all the contacts in the address book, previously saved using writeToFile(). QDataStream is used to read the contents of a .dat file into a list of pairs and each of these is added using addEntry().
readFromFile()函數(shù)加載一個(gè)文件,其中包含以前使用writeToFile()保存的地址簿中的所有聯(lián)系人凿傅。 QDataStream用于將.dat文件的內(nèi)容讀入對(duì)列表中缠犀,并使用addEntry()添加其中的每一個(gè)。
void AddressWidget::readFromFile(const QString &fileName)
{
QFile file(fileName);
if (!file.open(QIODevice::ReadOnly)) {
QMessageBox::information(this, tr("Unable to open file"),
file.errorString());
return;
}
QList<QPair<QString, QString> > pairs = table->getList();
QDataStream in(&file);
in >> pairs;
if (pairs.isEmpty()) {
QMessageBox::information(this, tr("No contacts in file"),
tr("The file you are attempting to open contains no contacts."));
} else {
for (int i=0; i<pairs.size(); ++i) {
QPair<QString, QString> p = pairs.at(i);
addEntry(p.first, p.second);
}
}
}
NewAddressTab Class Definition
The NewAddressTab class provides an informative tab telling the user that the address book is empty. It appears and disappears according to the contents of the address book, as mentioned in AddressWidget's implementation.
NewAddressTab類提供了一個(gè)信息性選項(xiàng)卡狭归,告訴用戶該通訊簿為空夭坪。 它會(huì)根據(jù)地址簿的內(nèi)容顯示和消失,如AddressWidget的實(shí)現(xiàn)中所述过椎。
The NewAddressTab class extends QWidget and contains a QLabel and QPushButton.
NewAddressTab類擴(kuò)展了QWidget并包含QLabel和QPushButton室梅。
class NewAddressTab : public QWidget
{
Q_OBJECT
public:
NewAddressTab(QWidget *parent = 0);
public slots:
void addEntry();
signals:
void sendDetails(QString name, QString address);
private:
QLabel *descriptionLabel;
QPushButton *addButton;
QVBoxLayout *mainLayout;
};
NewAddressTab Class Implementation
The constructor instantiates the addButton, descriptionLabel and connects the addButton's signal to the addEntry() slot.
構(gòu)造函數(shù)實(shí)例化addButton,descriptionLabel并將addButton的信號(hào)連接到addEntry()槽疚宇。
NewAddressTab::NewAddressTab(QWidget *parent)
{
Q_UNUSED(parent);
descriptionLabel = new QLabel(tr("There are currently no contacts in your address book. "
"\nClick Add to add new contacts."));
addButton = new QPushButton(tr("Add"));
connect(addButton, SIGNAL(clicked()), this, SLOT(addEntry()));
mainLayout = new QVBoxLayout;
mainLayout->addWidget(descriptionLabel);
mainLayout->addWidget(addButton, 0, Qt::AlignCenter);
setLayout(mainLayout);
}
The addEntry() function is similar to AddressWidget's addEntry() in the sense that both functions instantiate an AddDialog object. Data from the dialog is extracted and sent to AddressWidget's addEntry() slot by emitting the sendDetails() signal.
addEntry()函數(shù)類似于AddressWidget的addEntry()亡鼠,因?yàn)閮蓚€(gè)函數(shù)都實(shí)例化AddDialog對(duì)象。 通過發(fā)出sendDetails()信號(hào)敷待,提取對(duì)話框中的數(shù)據(jù)并將其發(fā)送到AddressWidget的addEntry()槽间涵。
void NewAddressTab::addEntry()
{
AddDialog aDialog;
if (aDialog.exec()) {
QString name = aDialog.nameText->text();
QString address = aDialog.addressText->toPlainText();
emit sendDetails(name, address);
}
}
AddDialog Class Definition
The AddDialog class extends QDialog and provides the user with a QLineEdit and a QTextEdit to input data into the address book.
AddDialog類擴(kuò)展了QDialog,并為用戶提供了一個(gè)QLineEdit和一個(gè)QTextEdit榜揖,用于將數(shù)據(jù)輸入到地址簿中勾哩。
class AddDialog : public QDialog
{
Q_OBJECT
public:
AddDialog(QWidget *parent = 0);
QLineEdit *nameText;
QTextEdit *addressText;
private:
QLabel *nameLabel;
QLabel *addressLabel;
QPushButton *okButton;
QPushButton *cancelButton;
};
AddDialog Class Implementation
The AddDialog's constructor sets up the user interface, creating the necessary widgets and placing them into layouts.
AddDialog的構(gòu)造函數(shù)設(shè)置用戶界面抗蠢,創(chuàng)建必要的小部件并將它們放入布局中。
AddDialog::AddDialog(QWidget *parent)
: QDialog(parent)
{
nameLabel = new QLabel("Name");
addressLabel = new QLabel("Address");
okButton = new QPushButton("OK");
cancelButton = new QPushButton("Cancel");
nameText = new QLineEdit;
addressText = new QTextEdit;
QGridLayout *gLayout = new QGridLayout;
gLayout->setColumnStretch(1, 2);
gLayout->addWidget(nameLabel, 0, 0);
gLayout->addWidget(nameText, 0, 1);
gLayout->addWidget(addressLabel, 1, 0, Qt::AlignLeft|Qt::AlignTop);
gLayout->addWidget(addressText, 1, 1, Qt::AlignLeft);
QHBoxLayout *buttonLayout = new QHBoxLayout;
buttonLayout->addWidget(okButton);
buttonLayout->addWidget(cancelButton);
gLayout->addLayout(buttonLayout, 2, 1, Qt::AlignRight);
QVBoxLayout *mainLayout = new QVBoxLayout;
mainLayout->addLayout(gLayout);
setLayout(mainLayout);
connect(okButton, SIGNAL(clicked()), this, SLOT(accept()));
connect(cancelButton, SIGNAL(clicked()), this, SLOT(reject()));
setWindowTitle(tr("Add a Contact"));
}
To give the dialog the desired behavior, we connect the OK and Cancel buttons to the dialog's accept() and reject() slots. Since the dialog only acts as a container for name and address information, we do not need to implement any other functions for it.
為了給對(duì)話框提供所需的行為思劳,我們將OK和Cancel按鈕連接到對(duì)話框的accept()和reject()槽迅矛。 由于對(duì)話框僅充當(dāng)名稱和地址信息的容器,因此我們不需要為其實(shí)現(xiàn)任何其他功能潜叛。
MainWindow Class Definition
The MainWindow class extends QMainWindow and implements the menus and actions necessary to manipulate the address book.
MainWindow類擴(kuò)展了QMainWindow并實(shí)現(xiàn)了操作地址簿所需的菜單和操作秽褒。
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow();
private slots:
void updateActions(const QItemSelection &selection);
void openFile();
void saveFile();
private:
void createMenus();
AddressWidget *addressWidget;
QMenu *fileMenu;
QMenu *toolMenu;
QAction *openAct;
QAction *saveAct;
QAction *exitAct;
QAction *addAct;
QAction *editAct;
QAction *removeAct;
};
The MainWindow class uses an AddressWidget as its central widget and provides the File menu with Open, Close and Exit actions, as well as the Tools menu with Add Entry..., Edit Entry... and Remove Entry actions.
MainWindow類使用AddressWidget作為其中心窗口小部件,并為File菜單提供Open威兜,Close和Exit操作销斟,以及帶有Add Entry ...,Edit Entry ...和Remove Entry操作的Tools菜單椒舵。
MainWindow Class Implementation
The constructor for MainWindow instantiates AddressWidget, sets it as its central widget and calls the createMenus() function.
MainWindow的構(gòu)造函數(shù)實(shí)例化AddressWidget蚂踊,將其設(shè)置為其中心窗口小部件并調(diào)用createMenus()函數(shù)。
MainWindow::MainWindow()
{
addressWidget = new AddressWidget;
setCentralWidget(addressWidget);
createMenus();
setWindowTitle(tr("Address Book"));
}
The createMenus() function sets up the File and Tools menus, connecting the actions to their respective slots. Both the Edit Entry... and Remove Entry actions are disabled by default as such actions cannot be carried out on an empty address book. They are only enabled when one or more contacts are added.
createMenus()函數(shù)設(shè)置文件和工具菜單逮栅,將操作連接到各自的插槽悴势。 默認(rèn)情況下禁用“編輯條目...”和“刪除條目”操作,因?yàn)闊o法在空地址簿上執(zhí)行此類操作措伐。 它們僅在添加一個(gè)或多個(gè)聯(lián)系人時(shí)啟用特纤。
void MainWindow::createMenus()
{
fileMenu = menuBar()->addMenu(tr("&File"));
openAct = new QAction(tr("&Open..."), this);
fileMenu->addAction(openAct);
connect(openAct, SIGNAL(triggered()), this, SLOT(openFile()));
...
editAct = new QAction(tr("&Edit Entry..."), this);
editAct->setEnabled(false);
toolMenu->addAction(editAct);
connect(editAct, SIGNAL(triggered()), addressWidget, SLOT(editEntry()));
toolMenu->addSeparator();
removeAct = new QAction(tr("&Remove Entry"), this);
removeAct->setEnabled(false);
toolMenu->addAction(removeAct);
connect(removeAct, SIGNAL(triggered()), addressWidget, SLOT(removeEntry()));
connect(addressWidget, SIGNAL(selectionChanged(QItemSelection)),
this, SLOT(updateActions(QItemSelection)));
}
Apart from connecting all the actions' signals to their respective slots, we also connect AddressWidget's selectionChanged() signal to its updateActions() slot.
除了將所有動(dòng)作的信號(hào)連接到各自的插槽之外,我們還將AddressWidget的selectionChanged()信號(hào)連接到其updateActions()插槽侥加。
The openFile() function allows the user to choose a file with the open file dialog. The chosen file has to be a custom .dat file that contains address book contacts. This function is a slot connected to openAct in the File menu.
openFile()函數(shù)允許用戶使用打開文件對(duì)話框選擇文件捧存。 所選文件必須是包含地址簿聯(lián)系人的自定義.dat文件。 此功能是連接到“文件”菜單中的openAct的插槽担败。
void MainWindow::openFile()
{
QString fileName = QFileDialog::getOpenFileName(this);
if (!fileName.isEmpty())
addressWidget->readFromFile(fileName);
}
The saveFile() function allows the user to save a file with the save file dialog. This function is a slot connected to saveAct in the File menu.
saveFile()函數(shù)允許用戶使用保存文件對(duì)話框保存文件昔穴。 此功能是連接到“文件”菜單中的saveAct的插槽。
void MainWindow::saveFile()
{
QString fileName = QFileDialog::getSaveFileName(this);
if (!fileName.isEmpty())
addressWidget->writeToFile(fileName);
}
The updateActions() function enables and disables Edit Entry... and Remove Entry depending on the contents of the address book. If the address book is empty, these actions are disabled; otherwise, they are enabled. This function is a slot is connected to the AddressWidget's selectionChanged() signal.
updateActions()函數(shù)根據(jù)地址簿的內(nèi)容啟用和禁用編輯條目...和刪除條目提前。 如果地址簿為空吗货,則禁用這些操作; 否則,它們被啟用狈网。 此函數(shù)是一個(gè)插槽連接到AddressWidget的selectionChanged()信號(hào)宙搬。
void MainWindow::updateActions(const QItemSelection &selection)
{
QModelIndexList indexes = selection.indexes();
if (!indexes.isEmpty()) {
removeAct->setEnabled(true);
editAct->setEnabled(true);
} else {
removeAct->setEnabled(false);
editAct->setEnabled(false);
}
}
main() Function
The main function for the address book instantiates QApplication and opens a MainWindow before running the event loop.
地址簿的主要功能實(shí)例化QApplication并在運(yùn)行事件循環(huán)之前打開MainWindow。
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
MainWindow mw;
mw.show();
return app.exec();
}
itemviews/addressbook/adddialog.cpp
/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the examples of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** You may use this file under the terms of the BSD license as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in
** the documentation and/or other materials provided with the
** distribution.
** * Neither the name of The Qt Company Ltd nor the names of its
** contributors may be used to endorse or promote products derived
** from this software without specific prior written permission.
**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "adddialog.h"
#include <QtWidgets>
AddDialog::AddDialog(QWidget *parent)
: QDialog(parent)
{
nameLabel = new QLabel("Name");
addressLabel = new QLabel("Address");
okButton = new QPushButton("OK");
cancelButton = new QPushButton("Cancel");
nameText = new QLineEdit;
addressText = new QTextEdit;
QGridLayout *gLayout = new QGridLayout;
gLayout->setColumnStretch(1, 2);
gLayout->addWidget(nameLabel, 0, 0);
gLayout->addWidget(nameText, 0, 1);
gLayout->addWidget(addressLabel, 1, 0, Qt::AlignLeft|Qt::AlignTop);
gLayout->addWidget(addressText, 1, 1, Qt::AlignLeft);
QHBoxLayout *buttonLayout = new QHBoxLayout;
buttonLayout->addWidget(okButton);
buttonLayout->addWidget(cancelButton);
gLayout->addLayout(buttonLayout, 2, 1, Qt::AlignRight);
QVBoxLayout *mainLayout = new QVBoxLayout;
mainLayout->addLayout(gLayout);
setLayout(mainLayout);
connect(okButton, SIGNAL(clicked()), this, SLOT(accept()));
connect(cancelButton, SIGNAL(clicked()), this, SLOT(reject()));
setWindowTitle(tr("Add a Contact"));
}
itemviews/addressbook/adddialog.h
/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the examples of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** You may use this file under the terms of the BSD license as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in
** the documentation and/or other materials provided with the
** distribution.
** * Neither the name of The Qt Company Ltd nor the names of its
** contributors may be used to endorse or promote products derived
** from this software without specific prior written permission.
**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef ADDDIALOG_H
#define ADDDIALOG_H
#include <QDialog>
class QLabel;
class QPushButton;
class QTextEdit;
class QLineEdit;
class AddDialog : public QDialog
{
Q_OBJECT
public:
AddDialog(QWidget *parent = 0);
QLineEdit *nameText;
QTextEdit *addressText;
private:
QLabel *nameLabel;
QLabel *addressLabel;
QPushButton *okButton;
QPushButton *cancelButton;
};
#endif // ADDDIALOG_H
itemviews/addressbook/addresswidget.cpp
/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the examples of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** You may use this file under the terms of the BSD license as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in
** the documentation and/or other materials provided with the
** distribution.
** * Neither the name of The Qt Company Ltd nor the names of its
** contributors may be used to endorse or promote products derived
** from this software without specific prior written permission.
**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "adddialog.h"
#include "addresswidget.h"
#include <QtWidgets>
AddressWidget::AddressWidget(QWidget *parent)
: QTabWidget(parent)
{
table = new TableModel(this);
newAddressTab = new NewAddressTab(this);
connect(newAddressTab, SIGNAL(sendDetails(QString, QString)),
this, SLOT(addEntry(QString, QString)));
addTab(newAddressTab, "Address Book");
setupTabs();
}
void AddressWidget::addEntry()
{
AddDialog aDialog;
if (aDialog.exec()) {
QString name = aDialog.nameText->text();
QString address = aDialog.addressText->toPlainText();
addEntry(name, address);
}
}
void AddressWidget::addEntry(QString name, QString address)
{
QList<QPair<QString, QString> >list = table->getList();
QPair<QString, QString> pair(name, address);
if (!list.contains(pair)) {
table->insertRows(0, 1, QModelIndex());
QModelIndex index = table->index(0, 0, QModelIndex());
table->setData(index, name, Qt::EditRole);
index = table->index(0, 1, QModelIndex());
table->setData(index, address, Qt::EditRole);
removeTab(indexOf(newAddressTab));
} else {
QMessageBox::information(this, tr("Duplicate Name"),
tr("The name \"%1\" already exists.").arg(name));
}
}
void AddressWidget::editEntry()
{
QTableView *temp = static_cast<QTableView*>(currentWidget());
QSortFilterProxyModel *proxy = static_cast<QSortFilterProxyModel*>(temp->model());
QItemSelectionModel *selectionModel = temp->selectionModel();
QModelIndexList indexes = selectionModel->selectedRows();
QString name;
QString address;
int row = -1;
foreach (QModelIndex index, indexes) {
row = proxy->mapToSource(index).row();
QModelIndex nameIndex = table->index(row, 0, QModelIndex());
QVariant varName = table->data(nameIndex, Qt::DisplayRole);
name = varName.toString();
QModelIndex addressIndex = table->index(row, 1, QModelIndex());
QVariant varAddr = table->data(addressIndex, Qt::DisplayRole);
address = varAddr.toString();
}
AddDialog aDialog;
aDialog.setWindowTitle(tr("Edit a Contact"));
aDialog.nameText->setReadOnly(true);
aDialog.nameText->setText(name);
aDialog.addressText->setText(address);
if (aDialog.exec()) {
QString newAddress = aDialog.addressText->toPlainText();
if (newAddress != address) {
QModelIndex index = table->index(row, 1, QModelIndex());
table->setData(index, newAddress, Qt::EditRole);
}
}
}
void AddressWidget::removeEntry()
{
QTableView *temp = static_cast<QTableView*>(currentWidget());
QSortFilterProxyModel *proxy = static_cast<QSortFilterProxyModel*>(temp->model());
QItemSelectionModel *selectionModel = temp->selectionModel();
QModelIndexList indexes = selectionModel->selectedRows();
foreach (QModelIndex index, indexes) {
int row = proxy->mapToSource(index).row();
table->removeRows(row, 1, QModelIndex());
}
if (table->rowCount(QModelIndex()) == 0) {
insertTab(0, newAddressTab, "Address Book");
}
}
void AddressWidget::setupTabs()
{
QStringList groups;
groups << "ABC" << "DEF" << "GHI" << "JKL" << "MNO" << "PQR" << "STU" << "VW" << "XYZ";
for (int i = 0; i < groups.size(); ++i) {
QString str = groups.at(i);
QString regExp = QString("^[%1].*").arg(str);
proxyModel = new QSortFilterProxyModel(this);
proxyModel->setSourceModel(table);
proxyModel->setFilterRegExp(QRegExp(regExp, Qt::CaseInsensitive));
proxyModel->setFilterKeyColumn(0);
QTableView *tableView = new QTableView;
tableView->setModel(proxyModel);
tableView->setSelectionBehavior(QAbstractItemView::SelectRows);
tableView->horizontalHeader()->setStretchLastSection(true);
tableView->verticalHeader()->hide();
tableView->setEditTriggers(QAbstractItemView::NoEditTriggers);
tableView->setSelectionMode(QAbstractItemView::SingleSelection);
tableView->setSortingEnabled(true);
connect(tableView->selectionModel(),
SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
this, SIGNAL(selectionChanged(QItemSelection)));
addTab(tableView, str);
}
}
void AddressWidget::readFromFile(const QString &fileName)
{
QFile file(fileName);
if (!file.open(QIODevice::ReadOnly)) {
QMessageBox::information(this, tr("Unable to open file"),
file.errorString());
return;
}
QList<QPair<QString, QString> > pairs = table->getList();
QDataStream in(&file);
in >> pairs;
if (pairs.isEmpty()) {
QMessageBox::information(this, tr("No contacts in file"),
tr("The file you are attempting to open contains no contacts."));
} else {
for (int i=0; i<pairs.size(); ++i) {
QPair<QString, QString> p = pairs.at(i);
addEntry(p.first, p.second);
}
}
}
void AddressWidget::writeToFile(const QString &fileName)
{
QFile file(fileName);
if (!file.open(QIODevice::WriteOnly)) {
QMessageBox::information(this, tr("Unable to open file"), file.errorString());
return;
}
QList<QPair<QString, QString> > pairs = table->getList();
QDataStream out(&file);
out << pairs;
}
itemviews/addressbook/addresswidget.h
/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the examples of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** You may use this file under the terms of the BSD license as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in
** the documentation and/or other materials provided with the
** distribution.
** * Neither the name of The Qt Company Ltd nor the names of its
** contributors may be used to endorse or promote products derived
** from this software without specific prior written permission.
**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef ADDRESSWIDGET_H
#define ADDRESSWIDGET_H
#include "newaddresstab.h"
#include "tablemodel.h"
#include <QItemSelection>
#include <QTabWidget>
class QSortFilterProxyModel;
class QItemSelectionModel;
class AddressWidget : public QTabWidget
{
Q_OBJECT
public:
AddressWidget(QWidget *parent = 0);
void readFromFile(const QString &fileName);
void writeToFile(const QString &fileName);
public slots:
void addEntry();
void addEntry(QString name, QString address);
void editEntry();
void removeEntry();
signals:
void selectionChanged (const QItemSelection &selected);
private:
void setupTabs();
TableModel *table;
NewAddressTab *newAddressTab;
QSortFilterProxyModel *proxyModel;
};
#endif // ADDRESSWIDGET_H
itemviews/addressbook/mainwindow.cpp
/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the examples of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** You may use this file under the terms of the BSD license as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in
** the documentation and/or other materials provided with the
** distribution.
** * Neither the name of The Qt Company Ltd nor the names of its
** contributors may be used to endorse or promote products derived
** from this software without specific prior written permission.
**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "mainwindow.h"
#include <QAction>
#include <QFileDialog>
#include <QMenuBar>
MainWindow::MainWindow()
{
addressWidget = new AddressWidget;
setCentralWidget(addressWidget);
createMenus();
setWindowTitle(tr("Address Book"));
}
void MainWindow::createMenus()
{
fileMenu = menuBar()->addMenu(tr("&File"));
openAct = new QAction(tr("&Open..."), this);
fileMenu->addAction(openAct);
connect(openAct, SIGNAL(triggered()), this, SLOT(openFile()));
saveAct = new QAction(tr("&Save As..."), this);
fileMenu->addAction(saveAct);
connect(saveAct, SIGNAL(triggered()), this, SLOT(saveFile()));
fileMenu->addSeparator();
exitAct = new QAction(tr("E&xit"), this);
fileMenu->addAction(exitAct);
connect(exitAct, SIGNAL(triggered()), this, SLOT(close()));
toolMenu = menuBar()->addMenu(tr("&Tools"));
addAct = new QAction(tr("&Add Entry..."), this);
toolMenu->addAction(addAct);
connect(addAct, SIGNAL(triggered()), addressWidget, SLOT(addEntry()));
editAct = new QAction(tr("&Edit Entry..."), this);
editAct->setEnabled(false);
toolMenu->addAction(editAct);
connect(editAct, SIGNAL(triggered()), addressWidget, SLOT(editEntry()));
toolMenu->addSeparator();
removeAct = new QAction(tr("&Remove Entry"), this);
removeAct->setEnabled(false);
toolMenu->addAction(removeAct);
connect(removeAct, SIGNAL(triggered()), addressWidget, SLOT(removeEntry()));
connect(addressWidget, SIGNAL(selectionChanged(QItemSelection)),
this, SLOT(updateActions(QItemSelection)));
}
void MainWindow::openFile()
{
QString fileName = QFileDialog::getOpenFileName(this);
if (!fileName.isEmpty())
addressWidget->readFromFile(fileName);
}
void MainWindow::saveFile()
{
QString fileName = QFileDialog::getSaveFileName(this);
if (!fileName.isEmpty())
addressWidget->writeToFile(fileName);
}
void MainWindow::updateActions(const QItemSelection &selection)
{
QModelIndexList indexes = selection.indexes();
if (!indexes.isEmpty()) {
removeAct->setEnabled(true);
editAct->setEnabled(true);
} else {
removeAct->setEnabled(false);
editAct->setEnabled(false);
}
}
itemviews/addressbook/mainwindow.h
/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the examples of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** You may use this file under the terms of the BSD license as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in
** the documentation and/or other materials provided with the
** distribution.
** * Neither the name of The Qt Company Ltd nor the names of its
** contributors may be used to endorse or promote products derived
** from this software without specific prior written permission.
**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include "addresswidget.h"
#include <QMainWindow>
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow();
private slots:
void updateActions(const QItemSelection &selection);
void openFile();
void saveFile();
private:
void createMenus();
AddressWidget *addressWidget;
QMenu *fileMenu;
QMenu *toolMenu;
QAction *openAct;
QAction *saveAct;
QAction *exitAct;
QAction *addAct;
QAction *editAct;
QAction *removeAct;
};
#endif // MAINWINDOW_H
itemviews/addressbook/newaddresstab.cpp
/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the examples of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** You may use this file under the terms of the BSD license as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in
** the documentation and/or other materials provided with the
** distribution.
** * Neither the name of The Qt Company Ltd nor the names of its
** contributors may be used to endorse or promote products derived
** from this software without specific prior written permission.
**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "adddialog.h"
#include "newaddresstab.h"
#include <QtWidgets>
NewAddressTab::NewAddressTab(QWidget *parent)
{
Q_UNUSED(parent);
descriptionLabel = new QLabel(tr("There are currently no contacts in your address book. "
"\nClick Add to add new contacts."));
addButton = new QPushButton(tr("Add"));
connect(addButton, SIGNAL(clicked()), this, SLOT(addEntry()));
mainLayout = new QVBoxLayout;
mainLayout->addWidget(descriptionLabel);
mainLayout->addWidget(addButton, 0, Qt::AlignCenter);
setLayout(mainLayout);
}
void NewAddressTab::addEntry()
{
AddDialog aDialog;
if (aDialog.exec()) {
QString name = aDialog.nameText->text();
QString address = aDialog.addressText->toPlainText();
emit sendDetails(name, address);
}
}
itemviews/addressbook/newaddresstab.h
/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the examples of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** You may use this file under the terms of the BSD license as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in
** the documentation and/or other materials provided with the
** distribution.
** * Neither the name of The Qt Company Ltd nor the names of its
** contributors may be used to endorse or promote products derived
** from this software without specific prior written permission.
**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef NEWADDRESSTAB_H
#define NEWADDRESSTAB_H
#include <QWidget>
class QLabel;
class QPushButton;
class QVBoxLayout;
class NewAddressTab : public QWidget
{
Q_OBJECT
public:
NewAddressTab(QWidget *parent = 0);
public slots:
void addEntry();
signals:
void sendDetails(QString name, QString address);
private:
QLabel *descriptionLabel;
QPushButton *addButton;
QVBoxLayout *mainLayout;
};
#endif
itemviews/addressbook/tablemodel.cpp
/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the examples of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** You may use this file under the terms of the BSD license as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in
** the documentation and/or other materials provided with the
** distribution.
** * Neither the name of The Qt Company Ltd nor the names of its
** contributors may be used to endorse or promote products derived
** from this software without specific prior written permission.
**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "tablemodel.h"
TableModel::TableModel(QObject *parent)
: QAbstractTableModel(parent)
{
}
TableModel::TableModel(QList<QPair<QString, QString> > pairs, QObject *parent)
: QAbstractTableModel(parent)
{
listOfPairs = pairs;
}
int TableModel::rowCount(const QModelIndex &parent) const
{
Q_UNUSED(parent);
return listOfPairs.size();
}
int TableModel::columnCount(const QModelIndex &parent) const
{
Q_UNUSED(parent);
return 2;
}
QVariant TableModel::data(const QModelIndex &index, int role) const
{
if (!index.isValid())
return QVariant();
if (index.row() >= listOfPairs.size() || index.row() < 0)
return QVariant();
if (role == Qt::DisplayRole) {
QPair<QString, QString> pair = listOfPairs.at(index.row());
if (index.column() == 0)
return pair.first;
else if (index.column() == 1)
return pair.second;
}
return QVariant();
}
QVariant TableModel::headerData(int section, Qt::Orientation orientation, int role) const
{
if (role != Qt::DisplayRole)
return QVariant();
if (orientation == Qt::Horizontal) {
switch (section) {
case 0:
return tr("Name");
case 1:
return tr("Address");
default:
return QVariant();
}
}
return QVariant();
}
bool TableModel::insertRows(int position, int rows, const QModelIndex &index)
{
Q_UNUSED(index);
beginInsertRows(QModelIndex(), position, position + rows - 1);
for (int row = 0; row < rows; ++row) {
QPair<QString, QString> pair(" ", " ");
listOfPairs.insert(position, pair);
}
endInsertRows();
return true;
}
bool TableModel::removeRows(int position, int rows, const QModelIndex &index)
{
Q_UNUSED(index);
beginRemoveRows(QModelIndex(), position, position + rows - 1);
for (int row = 0; row < rows; ++row) {
listOfPairs.removeAt(position);
}
endRemoveRows();
return true;
}
bool TableModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
if (index.isValid() && role == Qt::EditRole) {
int row = index.row();
QPair<QString, QString> p = listOfPairs.value(row);
if (index.column() == 0)
p.first = value.toString();
else if (index.column() == 1)
p.second = value.toString();
else
return false;
listOfPairs.replace(row, p);
emit(dataChanged(index, index));
return true;
}
return false;
}
Qt::ItemFlags TableModel::flags(const QModelIndex &index) const
{
if (!index.isValid())
return Qt::ItemIsEnabled;
return QAbstractTableModel::flags(index) | Qt::ItemIsEditable;
}
QList< QPair<QString, QString> > TableModel::getList()
{
return listOfPairs;
}
itemviews/addressbook/tablemodel.h
/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the examples of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** You may use this file under the terms of the BSD license as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in
** the documentation and/or other materials provided with the
** distribution.
** * Neither the name of The Qt Company Ltd nor the names of its
** contributors may be used to endorse or promote products derived
** from this software without specific prior written permission.
**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef TABLEMODEL_H
#define TABLEMODEL_H
#include <QAbstractTableModel>
#include <QList>
#include <QPair>
class TableModel : public QAbstractTableModel
{
Q_OBJECT
public:
TableModel(QObject *parent = 0);
TableModel(QList<QPair<QString, QString> > listofPairs, QObject *parent = 0);
int rowCount(const QModelIndex &parent) const Q_DECL_OVERRIDE;
int columnCount(const QModelIndex &parent) const Q_DECL_OVERRIDE;
QVariant data(const QModelIndex &index, int role) const Q_DECL_OVERRIDE;
QVariant headerData(int section, Qt::Orientation orientation, int role) const Q_DECL_OVERRIDE;
Qt::ItemFlags flags(const QModelIndex &index) const Q_DECL_OVERRIDE;
bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) Q_DECL_OVERRIDE;
bool insertRows(int position, int rows, const QModelIndex &index = QModelIndex()) Q_DECL_OVERRIDE;
bool removeRows(int position, int rows, const QModelIndex &index = QModelIndex()) Q_DECL_OVERRIDE;
QList<QPair<QString, QString> > getList();
private:
QList<QPair<QString, QString> > listOfPairs;
};
itemviews/addressbook/main.cpp
/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the examples of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** You may use this file under the terms of the BSD license as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in
** the documentation and/or other materials provided with the
** distribution.
** * Neither the name of The Qt Company Ltd nor the names of its
** contributors may be used to endorse or promote products derived
** from this software without specific prior written permission.
**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
MainWindow mw;
mw.show();
return app.exec();
}
itemviews/addressbook/addressbook.pro
QT += widgets
SOURCES = adddialog.cpp \
addresswidget.cpp \
main.cpp \
mainwindow.cpp \
newaddresstab.cpp \
tablemodel.cpp
HEADERS = adddialog.h \
addresswidget.h \
mainwindow.h \
newaddresstab.h \
tablemodel.h
# install
target.path = $$[QT_INSTALL_EXAMPLES]/widgets/itemviews/addressbook
INSTALLS += target