• 12752阅读
  • 13回复

关于QTreeView中显示目录的问题 [复制链接]

上一主题 下一主题
离线溟阡
 
只看楼主 倒序阅读 楼主  发表于: 2009-02-17
— 本帖被 XChinux 从 General Qt Programming 移动到本区(2011-01-02) —
我用QTreeView和QDirModel实现的类似资源管理器的程序,有2个tree,其中treeA在MainWindow的DockWidget中,treeB在CentralWidget上。
现有目录a->b->c->d->e
abcde都是文件夹,我怎样能实现在treeA中只显示a到c这三层目录,然后当点击c的时候在treeB中显示剩下的de,点击ab目录的时候在StatusBar中显示目录的currentPath

麻烦大侠多多指教
[ 此贴被溟阡在2009-02-18 13:20重新编辑 ]
离线溟阡
只看该作者 1楼 发表于: 2009-02-17
没人啊……
离线codespy
只看该作者 2楼 发表于: 2009-02-17
引用楼主溟阡于2009-02-17 14:14发表的 关于QTreeView中显示目录的问题 :
我用QTreeView和QDirWidget实现的类似资源管理器的程序,有2个tree,其中treeA在MainWindow的DockWidget中,treeB在CentralWidget上。
现有目录a->b->c->d->e
abcde都是文件夹,我怎样能实现在treeA中只显示a到c这三层目录,然后当点击c的时候在treeB中显示剩下的de,点击ab目录的时候在StatusBar中显示目录的currentPath
麻烦大侠多多指教

限制目录的深度,具体操作就是重新实现相应的接口
离线weizhy
只看该作者 3楼 发表于: 2009-02-18
在Dock窗口中,可以使用QSortFilterProxyModel限制深度
对于centralWidget,当点击Dock中的目录时,重新设置model的rootIndex就好
离线溟阡
只看该作者 4楼 发表于: 2009-02-18
麻烦楼上说详细点呗~我查了文档,但是没用明白
model = new QDirModel;
tree = new QTreeView;
tree->setModel(model);
貌似是把上面的代码改成下面的?
model = new QDirModel;
tree = new QTreeView;
QSortFilterProxyModel* proxyModel = new QSortFilterProxyModel(this);
proxyModel->setSourceModel(model);
model->setFilter(QDir::AllDirs | QDir::NoDotAndDotDot);
tree->setModel(proxyModel);
可是好像没有什么效果啊?然后应该怎么写呢?

还有在QTreeView中能对目录进行增删改么?应该怎么实现?
有什么放法能让我修改了文件夹后QTreeView会刷新,看到我刚刚修改的结果?
[ 此贴被溟阡在2009-02-18 13:39重新编辑 ]
离线weizhy
只看该作者 5楼 发表于: 2009-02-18
......
如果QSortFilterProxyModel没有经过任何设置,如何实现你的那个功能?

具体为:
继承QSortFilterProxyModel,重载bool QSortFilterProxyModel::filterAcceptsRow ( int source_row, const QModelIndex & source_parent ) const

对于层次大于3的,比如你的QDirModel中 source_parent.index(source_row, 0) 层次大于3, 也就是 source_parent 层次大于2(若source_parent有效)...则filterAcceptsRow返回FALSE,于是乎就不会在View上显示


关于你的第二个问题,
如果你的所谓目录指的是某个固定目录,可以使用QFileSystemWatcher
否则,可以定时刷新(不过效率问题...)
离线溟阡
只看该作者 6楼 发表于: 2009-02-18
比如说我显示的是a目录,假定现在它是空的。我在a中新建一个b,我希望在新建后tree能够刷新
之前试了QFileSystemWatcher,可是没有效果……

至于上一个,我现在去写一下试试~非常感谢~
离线溟阡
只看该作者 7楼 发表于: 2009-02-20
还是没写出来……
编译器告诉我filterAcceptsRow这个是protect……
对于QSortFilterProxyModel类还是没看懂啊……
离线weizhy
只看该作者 8楼 发表于: 2009-02-20
....
俗话说,师傅领进门,修行在个人
你现在应该补一补C++知识

下面是限制 QDirModel 目录层次为3层的代码,其实很简单,你看了就知道了

main.cpp
------------
#include <QtGui/QApplication>
#include <QtGui/QTreeView>
#include <QtGui/QDirModel>

#include "myproxymodel.h"

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    QDirModel *model = new QDirModel;
    model->setReadOnly(true);

    MyProxyModel *proxyModel = new MyProxyModel;
    proxyModel->setSourceModel(model);

    QTreeView *view = new QTreeView;
    view->setModel(proxyModel);

    view->resize(800,600);
    view->show();


    return a.exec();
}




myproxymodel.h(太简单,我甚至连cpp都没有写)
---------------------
#ifndef MYPROXYMODEL_H
#define MYPROXYMODEL_H

#include <QtGui/QSortFilterProxyModel>

class MyProxyModel : public QSortFilterProxyModel
{
public:
    MyProxyModel()
    {
    }

    virtual bool filterAcceptsRow ( int source_row, const QModelIndex & source_parent ) const
    {
        Q_UNUSED(source_row);

        if (!source_parent.isValid())
            return true;

        const QModelIndex& parent = source_parent.parent();
        if (!parent.isValid())
            return true;

        const QModelIndex& parent2 = parent.parent();
        if (!parent2.isValid())
            return true;

        return false;
    }
};

#endif // MYPROXYMODEL_H


附件是运行结果:
离线rae007
只看该作者 9楼 发表于: 2009-02-20
我这里还有个问题:
不能用setRootIndex(index)改变路径了
加上这句就什么都不显示了……
int main(int argc, char *argv[])
{
      QApplication a(argc, argv);

      QDirModel *model = new QDirModel();
      model->setReadOnly(true);

      QModelIndex index = model->index("/root");

      MyProxyModel *proxyModel = new MyProxyModel;
      proxyModel->setSourceModel(model);

      QTreeView *view = new QTreeView();
      view->setModel(proxyModel);
      view->setRootIndex(index);
      view->resize(800,600);
      view->show();

      return a.exec();
}

就是改成上面这样,这是为什么呢?
但是如果不用QSortFilterProxyModel就能够显示出来

我想要设定某一个路径作为显示的跟路径
[ 此贴被rae007在2009-02-20 16:36重新编辑 ]
离线weizhy
只看该作者 10楼 发表于: 2009-02-20
...

你的这个所谓index是 model的index,
而你现在使用的是proxyModel
所以,

你的:
view->setRootIndex(index);
应该改为 :
view->setRootIndex(proxyModel->mapFromSource(index));

proxyModel 和 index 没有关系
要让 view(只知道 proxyModel,不知道 model) 使用只有model知道的index
必须使用
QModelIndex QSortFilterProxyModel::mapFromSource ( const QModelIndex & sourceIndex ) const
离线rae007
只看该作者 11楼 发表于: 2009-02-20
但是不行啊……
比如说我给它的index是/root/Desktop
运行确实没有问题了,但是它把这个Desktop好像当成了第3层目录……
结果显示出来的就是空的了
离线weizhy
只看该作者 12楼 发表于: 2009-02-20
我懒得说了,直接发个代码
附件: test4.zip (1173 K) 下载次数:39
离线sbtree
只看该作者 13楼 发表于: 2009-02-21
引用第11楼rae007于2009-02-20 17:11发表的  :
但是不行啊……
比如说我给它的index是/root/Desktop
运行确实没有问题了,但是它把这个Desktop好像当成了第3层目录……
结果显示出来的就是空的了

没错,weizhy的方法不是从view->setRootIndex(proxyModel->mapFromSource(index))的地方算起的,而是从当前层向顶层回溯计算的,最多三层
windows 7 + VC++2008 + Qt4.5.2
快速回复
限100 字节
 
上一个 下一个