AddressWidget类里面还有几个成员函数。
void AddressWidget::showAddEntryDialog()

void AddressWidget::showAddEntryDialog()
{
    AddDialog aDialog;

    if (aDialog.exec()) {   //循环,保证窗口不退出
        QString name = aDialog.nameText->text();             
        QString address = aDialog.addressText->toPlainText();

        addEntry(name, address);
    }
}

connect(addAct, &QAction::triggered, addressWidget, &AddressWidget::showAddEntryDialog);

这个信号槽可以看出,它是与addAct这个动作绑定的。

传递name 和 adress给 addEntry

接着来看看addEntry

void AddressWidget::addEntry(QString name, QString address)
{
    if (!table->getContacts().contains({ name, address })) {  //判断table中 是否存在name和address相同的项
        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));
    }
}

contains的官方注解:Returns true if the list contains an occurrence of value; otherwise returns false.
insertRows的函数申明,这个函数在TableModel类里

bool insertRows(int position, int rows, const QModelIndex &index = QModelIndex()) override;

The QModelIndex class is used to locate data in a data model.

之后就是一系列的插入操作了。

最后就是移除最开始那个AdressBook tab

void AddressWidget::editEntry()

void AddressWidget::editEntry()
{
    QTableView *temp = static_cast<QTableView*>(currentWidget());  //创建一个临时的temp, 赋值为当前的tab
    QSortFilterProxyModel *proxy = static_cast<QSortFilterProxyModel*>(temp->model());  //代理
    QItemSelectionModel *selectionModel = temp->selectionModel();  //置为当前选择的Model

    QModelIndexList indexes = selectionModel->selectedRows();    //index设为当前tab选中的行
    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;   //件里一个dialog
    aDialog.setWindowTitle(tr("Edit a Contact"));    //设置title

    aDialog.nameText->setReadOnly(true);     //只读  所以只能改地址不能改ming'zi
    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);
        }
    }
}

currentWidget():Returns a pointer to the page currently being displayed by the tab dialog. The tab dialog does its best to make sure that this value is never 0 (but if you try hard enough, it can be).

mapToSource(const QModelIndex &proxyIndex):Returns the source model index corresponding to the given proxyIndex from the sorting filter model.

void AddressWidget::removeEntry()

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) {       //如果没有任何项,重新生成Address Book tab
        insertTab(0, newAddressTab, "Address Book");
    }
}

void AddressWidget::readFromFile(const QString &fileName)
这个函数在openFile函数中提到,主要是用于读入文件的

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<Contact> contacts;
    QDataStream in(&file);
    in >> contacts;  //读入文件

    if (contacts.isEmpty()) {
        QMessageBox::information(this, tr("No contacts in file"),
                                 tr("The file you are attempting to open contains no contacts."));
    } else {
        for (const auto &contact: qAsConst(contacts))
            addEntry(contact.name, contact.address);   //添加函数
    }
}

关于Contact,是一个结构体

struct Contact
{
    QString name;
    QString address;

    bool operator==(const Contact &other) const
    {
        return name == other.name && address == other.address;
    }
};

还有一个类似的

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;
    }

    QDataStream out(&file);    //写出
    out << table->getContacts();
}

之后的就下一篇在水了嘿嘿嘿

最后修改:2019 年 04 月 05 日
如果觉得我的文章对你有用,请随意赞赏