首先MainWindow类:

fileMenu = menuBar()->addMenu(tr("&File"));  //菜单栏 添加一个文件菜单

openAct = new QAction(tr("&Open..."), this);    //添加一个新的动作

fileMenu->addAction(openAct);   //将上面的openAct添加到fileMenu去

connect(openAct, &QAction::triggered, this, &MainWindow::openFile);  //信号槽,通过openAct去除法openFile对话框

fileMenu->addSeparator();  //菜单添加分割

editAct->setEnabled(false); //使此Action不可用 比如变灰
/*
官方解释:This property holds whether the action is enabled
Disabled actions cannot be chosen by the user. They do not disappear from menus or toolbars, but they are displayed in a way which indicates that they are unavailable. For example, they might be displayed using only shades of gray.
*/

void MainWindow::openFile()
{
    QString fileName = QFileDialog::getOpenFileName(this);
    if (!fileName.isEmpty())
        addressWidget->readFromFile(fileName);
}
//QFileDialog::getOpenFileName(this); //类似的还有getOpenFileNames(), getOpenFileUrl(), getSaveFileUrl(), and getExistingDirectoryUrl().
//官方解释:This is a convenience static function that returns an existing file selected by the user. If the user presses Cancel, it returns a null string.
//就是返回一个已存在文件的地址,如果未选中则返回空
//这个函数的函数声明如下:
/*
QString QFileDialog::getOpenFileName(QWidget *parent = nullptr, const QString &caption = QString(), const QString &dir = QString(), const QString &filter = QString(), QString *selectedFilter = nullptr, QFileDialog::Options options = ...)
*/

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);
    }
}
//这个函数就是让菜单栏的状态更新,如果有选项被选择就enable,否则就disable

AddressWidget类

//首先构造函数:
AddressWidget::AddressWidget(QWidget *parent)
    : QTabWidget(parent)
{
    table = new TableModel(this);
    newAddressTab = new NewAddressTab(this);
    connect(newAddressTab, &NewAddressTab::sendDetails,
        this, &AddressWidget::addEntry);

    addTab(newAddressTab, "Address Book");

    setupTabs();
}

//此类继承自QTabWidget  TableModel也是一个自己定义的类,后面再说
//这里的信号槽中的sendDetails是一个信号,与 addEntry绑定
//然后添加一个名为Address Book 的tab,后面继续安装

void AddressWidget::setupTabs()函数

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(),
            &QItemSelectionModel::selectionChanged,
            this, &AddressWidget::selectionChanged);

        connect(this, &QTabWidget::currentChanged, this, [this](int tabIndex) {
            auto *tableView = qobject_cast<QTableView *>(widget(tabIndex));
            if (tableView)
                emit selectionChanged(tableView->selectionModel()->selection());
        });

        addTab(tableView, str);
    }
}

首先 QStringList 是一个字符串的列表,里面存了一些字符串。

官方文档:The QStringList class provides a list of strings.

接着往 groups 里面写入这些字符串

接着就是代理

官方解释:The QSortFilterProxyModel class provides support for sorting and filtering data passed between another model and a view.

先创建一个代理,然后设定需要代理的对象,过滤选项,之后是过滤的列。

在之后就是tabview的设置了.

两个信号槽,分别对应tabview的选择与改变。

剩下的功能之后再写咯

Last modification:April 5, 2019
If you think my article is useful to you, please feel free to appreciate