树模型完成器示例

Tree Model Completer Example

树模型完成器示例

The Tree Model Completer example shows how to provide completion facilities for a hierarchical model, using a period as the separator to access Child, GrandChild and GrandGrandChild level objects.

Tree Model Completer示例展示了如何为分层模型提供完成工具,使用句点作为分隔符来访问Child、GrandChild和GrandGrandChill级别的对象。

Similar to the Completer Example, we provide QComboBox objects to enable selection for completion mode and case sensitivity, as well as a QCheckBox for wrap completions.

​与Completer Example类似,我们提供了QComboBox对象以支持完成模式和区分大小写的选择,以及用于包装完成的QCheckBox。

The Resource File

资源文件

The contents of the TreeModelCompleter is read from treemodel.txt. This file is embedded within the treemodelcompleter.qrc resource file, which contains the following:

TreeModelCompleter的内容从treemodel.txt读取。此文件嵌入到treemodelcompleter.qrc资源文件,其中包含以下内容:

<!DOCTYPE RCC><RCC version="1.0">
<qresource prefix="/">
   <file>resources/treemodel.txt</file>
</qresource>
</RCC>

TreeModelCompleter Class Definition

TreeModelCompleter类定义

The TreeModelCompleter is a subclass of QCompleter with two constructors - one with parent as an argument and another with parent and model as arguments.

​TreeModelCompleter是QCompleter的一个子类,有两个构造函数——一个用parent作为参数,另一个用parent和model作为参数。

class TreeModelCompleter : public QCompleter
{
    Q_OBJECT
    Q_PROPERTY(QString separator READ separator WRITE setSeparator)

public:
    explicit TreeModelCompleter(QObject *parent = nullptr);
    explicit TreeModelCompleter(QAbstractItemModel *model, QObject *parent = nullptr);

    QString separator() const;
public slots:
    void setSeparator(const QString &separator);

protected:
    QStringList splitPath(const QString &path) const override;
    QString pathFromIndex(const QModelIndex &index) const override;

private:
    QString sep;
};

The class reimplements the protected functions splitPath() and pathFromIndex() to suit a tree model. For more information on customizing QCompleter to suit tree models, refer to Handling Tree Models.

该类重新实现了受保护的函数splitPath()和pathFromIndex(),以适合树模型。有关自定义QCompleter以适合树模型的更多信息,请参阅处理树模型。

TreeModelCompleter also has a separator property which is declared using the Q_PROPERTY() macro. The separator has READ and WRITE attributes and the corresponding functions separator() and setSeparator(). For more information on Q_PROPERTY(), refer to Qt's Property System.

​TreeModelCompleter还有一个使用Q_property()宏声明的分隔符属性。分隔符具有READ和WRITE属性以及相应的函数separator()和setSeparator()。有关Q_PROPERTY()的详细信息,请参阅Qt的属性系统。

TreeModelCompleter Class Implementation

TreeModelCompleter类实现

The first constructor constructs a TreeModelCompleter object with a parent while the second constructor constructs an object with a parent and a QAbstractItemModelmodel.

第一个构造函数使用父级构造TreeModelCompleter对象,而第二个构造函数则使用父级和QAbstractItemModel模型构造对象。

TreeModelCompleter::TreeModelCompleter(QObject *parent)
    : QCompleter(parent)
{
}

TreeModelCompleter::TreeModelCompleter(QAbstractItemModel *model, QObject *parent)
    : QCompleter(model, parent)
{
}

The separator() function is a getter function that returns the separator string.

separator()函数是一个返回分隔符字符串的getter函数。

QString TreeModelCompleter::separator() const
{
    return sep;
}

As mentioned earlier, the splitPath() function is reimplemented because the default implementation is more suited to QFileSystemModel or list models. In order for QCompleter to split the path into a list of strings that are matched at each level, we split it using QString::split() with sep as its separator.

​如前所述,重新实现了splitPath()函数,因为默认实现更适合QFileSystemModel或列表模型。为了让QCompleter将路径拆分为在每个级别匹配的字符串列表,我们使用QString::split()将其拆分,并使用sep作为分隔符。

QStringList TreeModelCompleter::splitPath(const QString &path) const
{
    return (sep.isNull() ? QCompleter::splitPath(path) : path.split(sep));
}

The pathFromIndex() function returns data for the completionRole() for a tree model. This function is reimplemented as its default implementation is more suitable for list models. If there is no separator, we use QCompleter's default implementation, otherwise we use the prepend() function to navigate upwards and accumulate the data. The function then returns a QStringListdataList, using a separator to join objects of different levels.

pathFromIndex()函数的作用是:返回树模型的completionRole()的数据。此函数被重新实现,因为它的默认实现更适合列表模型。如果没有分隔符,则使用QCompleter的默认实现,否则使用prepend()函数向上导航并累积数据。然后,该函数返回一个QStringList,dataList,使用分隔符连接不同级别的对象。

QString TreeModelCompleter::pathFromIndex(const QModelIndex &index) const
{
    if (sep.isNull())
        return QCompleter::pathFromIndex(index);

    // navigate up and accumulate data
    QStringList dataList;
    for (QModelIndex i = index; i.isValid(); i = i.parent())
        dataList.prepend(model()->data(i, completionRole()).toString());

    return dataList.join(sep);
}

MainWindow Class Definition

MainWindow类定义

The MainWindow class is a subclass of QMainWindow and implements five custom slots: about()changeCase()changeMode()highlight(), and updateContentsLabel().

​MainWindow类是QMainWindows的子类,它实现了五个自定义槽:about()、changeCase()、changeMode(),highlight()和updateContentsLabel()。

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);

private slots:
    void about();
    void changeCase(int);
    void changeMode(int);
    void highlight(const QModelIndex &index);
    void updateContentsLabel(const QString &sep);

In addition, the class has two private functions, createMenu() and modelFromFile(), as well as private instances of QTreeViewQComboBoxQLabelTreeModelCompleter and QLineEdit.

​此外,该类有两个私有函数createMenu()和modelFromFile(),以及QTreeView、QComboBox、QLabel、TreeModelCompleter和QLineEdit的私有实例。

private:
    void createMenu();
    QAbstractItemModel *modelFromFile(const QString &fileName);

    QTreeView *treeView = nullptr;
    QComboBox *caseCombo = nullptr;
    QComboBox *modeCombo = nullptr;
    QLabel *contentsLabel = nullptr;
    TreeModelCompleter *completer = nullptr;
    QLineEdit *lineEdit = nullptr;
};

MainWindow Class Implementation

MainWindow类实现

The MainWindow's constructor creates a MainWindow object with a parent and initializes the completer and lineEdit. The createMenu() function is invoked to set up the "File" menu and "Help" menu. The completer's model is set to the QAbstractItemModel obtained from modelFromFile(), and the highlighted() signal is connected to MainWindow's highlight() slot.

​MainWindow的构造函数创建一个具有父级的MainWindows对象,并初始化completer和lineEdit。调用createMenu()函数来设置“File”菜单和“Help”菜单。completer的模型设置为从modelFromFile()获取的QAbstractItemModel,highlighted()信号连接到MainWindow的highlight()插槽。

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    createMenu();

    completer = new TreeModelCompleter(this);
    completer->setModel(modelFromFile(":/resources/treemodel.txt"));
    completer->setSeparator(QLatin1String("."));
    QObject::connect(completer, QOverload<const QModelIndex &>::of(&TreeModelCompleter::highlighted),
                     this, &MainWindow::highlight);

    QWidget *centralWidget = new QWidget;

    QLabel *modelLabel = new QLabel;
    modelLabel->setText(tr("Tree Model<br>(Double click items to edit)"));

    QLabel *modeLabel = new QLabel;
    modeLabel->setText(tr("Completion Mode"));
    modeCombo = new QComboBox;
    modeCombo->addItem(tr("Inline"));
    modeCombo->addItem(tr("Filtered Popup"));
    modeCombo->addItem(tr("Unfiltered Popup"));
    modeCombo->setCurrentIndex(1);

    QLabel *caseLabel = new QLabel;
    caseLabel->setText(tr("Case Sensitivity"));
    caseCombo = new QComboBox;
    caseCombo->addItem(tr("Case Insensitive"));
    caseCombo->addItem(tr("Case Sensitive"));
    caseCombo->setCurrentIndex(0);

The QLabel objects modelLabelmodeLabel and caseLabel are instantiated. Also, the QComboBox objects, modeCombo and caseCombo, are instantiated and populated. By default, the completer's mode is "Filtered Popup" and the case is insensitive.

​将实例化QLabel对象modelLabel、modeLabel和caseLabel。此外,QComboBox对象modeCombo和caseCombo也被实例化并填充。默认情况下,completer的模式为“过滤弹出窗口”,大小写不敏感。

    QLabel *separatorLabel = new QLabel;
    separatorLabel->setText(tr("Tree Separator"));

    QLineEdit *separatorLineEdit = new QLineEdit;
    separatorLineEdit->setText(completer->separator());
    connect(separatorLineEdit, &QLineEdit::textChanged,
            completer, &TreeModelCompleter::setSeparator);

    QCheckBox *wrapCheckBox = new QCheckBox;
    wrapCheckBox->setText(tr("Wrap around completions"));
    wrapCheckBox->setChecked(completer->wrapAround());
    connect(wrapCheckBox, &QAbstractButton::clicked, completer, &QCompleter::setWrapAround);

    contentsLabel = new QLabel;
    contentsLabel->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
    connect(separatorLineEdit, &QLineEdit::textChanged,
            this, &MainWindow::updateContentsLabel);

    treeView = new QTreeView;
    treeView->setModel(completer->model());
    treeView->header()->hide();
    treeView->expandAll();

    connect(modeCombo, &QComboBox::activated,
            this, &MainWindow::changeMode);
    connect(caseCombo, &QComboBox::activated,
            this, &MainWindow::changeMode);

    lineEdit = new QLineEdit;
    lineEdit->setCompleter(completer);

We use a QGridLayout to place all the objects in the MainWindow.

​我们使用QGridLayout将所有对象放置在主窗口中。

    QGridLayout *layout = new QGridLayout;
    layout->addWidget(modelLabel, 0, 0); layout->addWidget(treeView, 0, 1);
    layout->addWidget(modeLabel, 1, 0);  layout->addWidget(modeCombo, 1, 1);
    layout->addWidget(caseLabel, 2, 0);  layout->addWidget(caseCombo, 2, 1);
    layout->addWidget(separatorLabel, 3, 0); layout->addWidget(separatorLineEdit, 3, 1);
    layout->addWidget(wrapCheckBox, 4, 0);
    layout->addWidget(contentsLabel, 5, 0, 1, 2);
    layout->addWidget(lineEdit, 6, 0, 1, 2);
    centralWidget->setLayout(layout);
    setCentralWidget(centralWidget);

    changeCase(caseCombo->currentIndex());
    changeMode(modeCombo->currentIndex());

    setWindowTitle(tr("Tree Model Completer"));
    lineEdit->setFocus();

The createMenu() function sets up the QAction objects required and adds them to the "File" menu and "Help" menu. The triggered() signals from these actions are connected to their respective slots.

​createMenu()函数设置所需的QAction对象,并将其添加到“File”菜单和“Help”菜单。这些动作的triggered()信号连接到各自的插槽。

void MainWindow::createMenu()
{
    QAction *exitAction = new QAction(tr("Exit"), this);
    QAction *aboutAct = new QAction(tr("About"), this);
    QAction *aboutQtAct = new QAction(tr("About Qt"), this);

    connect(exitAction, &QAction::triggered, qApp, &QApplication::quit);
    connect(aboutAct, &QAction::triggered, this, &MainWindow::about);
    connect(aboutQtAct, &QAction::triggered, qApp, &QApplication::aboutQt);

    QMenu *fileMenu = menuBar()->addMenu(tr("File"));
    fileMenu->addAction(exitAction);

    QMenu *helpMenu = menuBar()->addMenu(tr("About"));
    helpMenu->addAction(aboutAct);
    helpMenu->addAction(aboutQtAct);
}

The changeMode() function accepts an index corresponding to the user's choice of completion mode and changes the completer's mode accordingly.

changeMode()函数接受与用户选择的完成模式相对应的索引,并相应地更改完成模式。

void MainWindow::changeMode(int index)
{
    QCompleter::CompletionMode mode;
    if (index == 0)
        mode = QCompleter::InlineCompletion;
    else if (index == 1)
        mode = QCompleter::PopupCompletion;
    else
        mode = QCompleter::UnfilteredPopupCompletion;

    completer->setCompletionMode(mode);
}

The about() function provides a brief description on the Tree Model Completer example.

about()函数对Tree Model Completer示例进行了简要描述。

void MainWindow::about()
{
    QMessageBox::about(this, tr("About"), tr("This example demonstrates how "
        "to use a QCompleter with a custom tree model."));
}

The changeCase() function alternates between Case Sensitive and Case Insensitive modes, depending on the value of cs.

​changeCase()函数根据cs的值,在区分大小写和不区分大小写模式之间切换。

void MainWindow::changeCase(int cs)
{
    completer->setCaseSensitivity(cs ? Qt::CaseSensitive : Qt::CaseInsensitive);
}

main() Function

main()函数

The main() function instantiates MainWindow and invokes the show() function to display it.

​main()函数实例化MainWindow并调用show()函数来显示它。

int main(int argc, char *argv[])
{
    Q_INIT_RESOURCE(treemodelcompleter);

    QApplication app(argc, argv);
    MainWindow window;
    window.show();
    return app.exec();
}

Example project @ code.qt.io

© 2022 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值