11.树形Model/View实例

Posted billxyd

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了11.树形Model/View实例相关的知识,希望对你有一定的参考价值。

任务1:显示如图的树形结构

 

思考:

1.使用QTreeView显示。

2.Model使用QStandardItemModel,qt的一个标准model。

3.QStandardItemModel下每一个单元都可以看作QStandardItem。

4.QStandardItemModel中invisibleRootItem()函数返回一个看不到的根。

5.在这个根上添加行。

 

 

代码如下:

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QTreeView>
#include <QStandardItemModel>
#include <QStandardItem>
#include <QList>

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT
    
public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();
    
private:
    Ui::MainWindow *ui;
    QList <QStandardItem *>  createRow(QString str1, QString str2, QString str3);

};

#endif // MAINWINDOW_H

 

mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    QTreeView *treeView = new QTreeView(this);
    setCentralWidget(treeView);
    QStandardItemModel *model = new QStandardItemModel(this);

    QStandardItem *root = model->invisibleRootItem();

    QList <QStandardItem *> firstRow = createRow("first", "second", "third");
    root->appendRow(firstRow);

    QList <QStandardItem *> secondRow = createRow("111", "222", "333");
    firstRow.first()->appendRow(secondRow);

    treeView->setModel(model);
    treeView->expandAll();

}

MainWindow::~MainWindow()
{
    delete ui;
}

QList <QStandardItem *>  MainWindow::createRow(QString str1, QString str2, QString str3)
{
    QList <QStandardItem *> row;

    row << new QStandardItem(str1);
    row << new QStandardItem(str2);
    row << new QStandardItem(str3);


    return row;
}

 

main.cpp

#include "mainwindow.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();
    
    return a.exec();
}

 

任务2: 显示如下的树形结构。点击树形下拉单时候,窗口标题显示当前的内容和等级。顶级树形菜单等级1.

      

 

思考:

1.如何显示这个树形下拉单和第一个例子一样。

2.点击下拉单时,肯定要触发信号。

3.因为你点击不同的下拉单。选择改变了。这个Model是QItemSelectionModel。通过QTreeView中selectionModel()函数得到。

4.QItemSelectionModel文档中发现信号 selectionChanged()信号。我们设计槽处理这个信号就好了。

5.通过QItemSelectionModel可以得到当前选择的ModelIndex,通过ModelIndex得到内容。

6.通过QItemSelectionModel可以得到当前选择的ModelIndex,如果ModelIndex的parent为空,则是顶级ModelIndex。

 

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QTreeView>
#include <QStandardItemModel>
#include <QStandardItem>
#include <QList>

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT
    
public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();
    
private:
    Ui::MainWindow *ui;
    QTreeView * treeView;

private slots:
    void selectionChangedShot(const QItemSelection & selected,const QItemSelection & deselected );


};

#endif // MAINWINDOW_H

mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"

#include <QItemSelectionModel>
#include <QModelIndex>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    treeView = new QTreeView(this);
    setCentralWidget(treeView);
    QStandardItemModel *model = new QStandardItemModel(this);

    QStandardItem *root = model->invisibleRootItem();

    QStandardItem *USA = new QStandardItem("USA");
    QStandardItem *Canada = new QStandardItem("Canada");
    QStandardItem *America = new QStandardItem("America");
    QStandardItem *Boston = new QStandardItem("Boston");
    QStandardItem *Europe = new QStandardItem("Europe");
    QStandardItem *Rome = new QStandardItem("Rome");
    QStandardItem *Italy = new QStandardItem("Italy");
    QStandardItem *Verona = new QStandardItem("Verona");

    root->appendRow(America);
    root->appendRow(Europe);

    America->appendRow(Canada);
    America->appendRow(USA);
    USA->appendRow(Boston);

    Europe->appendRow(Italy);
    Italy->appendRow(Rome);
    Italy->appendRow(Verona);


    treeView->setModel(model);
    treeView->expandAll();

    QItemSelectionModel *selectionModel =  treeView->selectionModel();

    connect(selectionModel, SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
            this, SLOT(selectionChangedShot(QItemSelection, QItemSelection)));

}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::selectionChangedShot(const QItemSelection & selected,const QItemSelection & deselected )
{
    QModelIndex index = treeView->selectionModel()->currentIndex();
    QString text = index.data(Qt::DisplayRole).toString();

    int hierarchy = 1;
    QModelIndex seekRoot = index;
    while(seekRoot.parent() != QModelIndex()) {
        hierarchy++;
        seekRoot = seekRoot.parent();
    }

    QString title = QString("%1,level%2").arg(text).arg(hierarchy);
    setWindowTitle(title);
}

main.cpp

#include "mainwindow.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();
    
    return a.exec();
}

 

以上是关于11.树形Model/View实例的主要内容,如果未能解决你的问题,请参考以下文章

10.model/view实例

model 和 view 实现思考

Qt中如何写一个model

qml----Model/View入门Repeater

片段事务中的实例化错误

Qt中如何写一个model(自定义一个RowNode,我没有碰到过)