22

私が持っているもの:

  1. QTreeViewテーブルデータを持つクラス
  2. そして連結QAbstractTableModelモデル

質問: アイテムの展開状態を保存する方法は? ソリューションを完成させた人はいますか?

PS: このコードを自分で実行できることはわかっていますが、時間があまりありません。これは私たちのプロジェクトの主要な問題ではありませんが、アプリにはそのようなテーブルがたくさん含まれているため、それでも必要です。ツリー項目を展開するたびに煩わしいプロセスです...

4

8 に答える 8

15

まず、Razi for persistentIndexListand isExpandedway に感謝します。

第二に、これは私にとってうまくいくコードです:-)

dialog.hファイル:

class Dialog : public QDialog
{
    Q_OBJECT;

    TreeModel *model;
    TreeView *view;

public:
    Dialog(QWidget *parent = 0);
    ~Dialog(void);

    void reload(void);

protected:
    void createGUI(void);
    void closeEvent(QCloseEvent *);
    void saveState(void);
    void restoreState(void);
};

dialog.cppファイル:

Dialog::Dialog(QWidget *parent)
{
    createGUI();
    reload();
}

Dialog::~Dialog(void) {};

void Dialog::reload(void)
{
    restoreState();
}

void Dialog::createGUI(void)
{
    QFile file(":/Resources/default.txt");
    file.open(QIODevice::ReadOnly);
    model = new TreeModel(file.readAll());
    file.close();

    view = new TreeView(this);
    view->setModel(model);

    QVBoxLayout *mainVLayout = new QVBoxLayout;
    mainVLayout->addWidget(view);

    setLayout(mainVLayout);
}

void Dialog::closeEvent(QCloseEvent *event_)
{
    saveState();
}

void Dialog::saveState(void)
{
    QStringList List;

    // prepare list
    // PS: getPersistentIndexList() function is a simple `return this->persistentIndexList()` from TreeModel model class
    foreach (QModelIndex index, model->getPersistentIndexList())
    {
        if (view->isExpanded(index))
        {
            List << index.data(Qt::DisplayRole).toString();
        }
    }

    // save list
    QSettings settings("settings.ini", QSettings::IniFormat);
    settings.beginGroup("MainWindow");
    settings.setValue("ExpandedItems", QVariant::fromValue(List));
    settings.endGroup();
}

void Dialog::restoreState(void)
{
    QStringList List;

    // get list
    QSettings settings("settings.ini", QSettings::IniFormat);
    settings.beginGroup("MainWindow");
    List = settings.value("ExpandedItems").toStringList();
    settings.endGroup();

    foreach (QString item, List)
    {
        // search `item` text in model
        QModelIndexList Items = model->match(model->index(0, 0), Qt::DisplayRole, QVariant::fromValue(item));
        if (!Items.isEmpty())
        {
            // Information: with this code, expands ONLY first level in QTreeView
            view->setExpanded(Items.first(), true);
        }
    }
}

良い1日を!)


PS: この例はコードに基づいていC:\Qt\4.6.3\examples\itemviews\simpletreemodelます。

于 2010-07-19T07:25:58.117 に答える
8

Raziとmosgのおかげで、これを機能させることができました。拡張状態を再帰的に復元させたので、その部分を共有したいと思いました。

void applyExpandState_sub(QStringList& expandedItems,
                          QTreeView* treeView,
                          QAbstractItemModel* model,
                          QModelIndex startIndex)
{
    foreach (QString item, expandedItems) 
    {
        QModelIndexList matches = model->match( startIndex, Qt::UserRole, item );
        foreach (QModelIndex index, matches) 
        {
            treeView->setExpanded( index, true );
            applyExpandState_sub(expandedItems, 
                                 treeView,
                                 model,
                                 model->index( 0, 0, index ) );
        }
    }
}

次に、次のように使用します。

void myclass::applyExpandState() 
{
    m_treeView->setUpdatesEnabled(false);

    applyExpandState_sub( m_expandedItems,
                          m_treeView,
                          m_model,
                          m_model->index( 0, 0, QModelIndex() ) );

    m_treeView->setUpdatesEnabled(true);
}

ここではQt::UserRoleを使用しています。これは、モデル内の複数のアイテムが同じ表示名を持つ可能性があり、展開状態の復元を台無しにする可能性があるため、UserRoleはその問題を回避するために各アイテムに一意の識別子を提供します。

于 2012-03-04T08:45:40.403 に答える
7

ループを使用するこれらの 2 つの関数は、それを行う必要があります。

QModelIndexList QAbstractItemModel::persistentIndexList () const
bool isExpanded ( const QModelIndex & index ) const
于 2010-07-18T09:20:10.753 に答える
2

iforce2d のソリューションを次のように作り直しました。

 void ApplyExpandState(QStringList & nodes,
                       QTreeView * view,
                       QAbstractItemModel * model,
                       const QModelIndex startIndex,
                       QString path)
{
    path+=QString::number(startIndex.row()) + QString::number(startIndex.column());
    for(int i(0); i < model->rowCount(startIndex); ++i)
    {
        QModelIndex nextIndex = model->index(i, 0, startIndex);
        QString nextPath = path + QString::number(nextIndex.row()) + QString::number(nextIndex.column());
        if(!nodes.contains(nextPath))
            continue;
        ApplyExpandState(nodes, view, model, model->index(i, 0, startIndex), path);
    }
    if(nodes.contains(path))
        view->setExpanded( startIndex.sibling(startIndex.row(), 0), true );
}

void StoreExpandState(QStringList & nodes,
                      QTreeView * view,
                      QAbstractItemModel * model,
                      const QModelIndex startIndex,
                      QString path)
{
    path+=QString::number(startIndex.row()) + QString::number(startIndex.column());
    for(int i(0); i < model->rowCount(startIndex); ++i)
    {
        if(!view->isExpanded(model->index(i, 0, startIndex)))
            continue;
        StoreExpandState(nodes, view, model, model->index(i, 0, startIndex), path);
    }

    if(view->isExpanded(startIndex))
        nodes << path;
}

この方法では、データを一致させる必要はありません。明らかに - このアプローチが機能するには、ツリーは比較的変更されていない必要があります。何らかの方法でツリー項目の順序を変更すると、間違ったノードが展開されます。

于 2012-12-23T10:37:49.173 に答える
0

の場合、QFileSystemModelは使用できませんpersistentIndexList()

これが私の回避策です。自分で言ったとしても、それはかなりうまく機能します。ファイルシステムの読み込みが遅い場合や、ファイルまたはパスを削除した場合にどうなるかはテストしていません。

// scrolling code connection in constructor
model = new QFileSystemModel();

QObject::connect(ui->treeView, &QTreeView::expanded, [=](const QModelIndex &index)
{
    ui->treeView->scrollTo(index, QAbstractItemView::PositionAtTop);//PositionAtCenter);
});

// save state, probably in your closeEvent()
QSettings s;
s.setValue("header_state",ui->treeView->header()->saveState());
s.setValue("header_geometry",ui->treeView->header()->saveGeometry());

if(ui->treeView->currentIndex().isValid())
{
    QFileInfo info = model->fileInfo(ui->treeView->currentIndex());
    QString filename = info.absoluteFilePath();
    s.setValue("last_directory",filename);
}

// restore state, probably in your showEvent()
QSettings s;
ui->treeView->header()->restoreState(s.value("header_state").toByteArray());
ui->treeView->header()->restoreGeometry(s.value("header_geometry").toByteArray());
QTimer::singleShot(1000, [=]() {
    QSettings s;
    QString filename = s.value("last_directory").toString();
    QModelIndex index = model->index(filename);
    if(index.isValid())
    {
        ui->treeView->expand(index);
        ui->treeView->setCurrentIndex(index);

        ui->treeView->scrollTo(index, QAbstractItemView::PositionAtCenter);
        qDebug() << "Expanded" << filename;
    }
    else
        qDebug() << "Invalid index" << filename;
} );

それが誰かを助けることを願っています。

于 2015-01-22T00:04:36.347 に答える