5

我正在一个没有键盘/鼠标的系统上做主题所说的事情,所以我需要“从代码”中完成这项工作。当我更改 QListView 的 RootIndex 时,我想突出显示第一行。

这是我制作的一个小型测试项目的 mainwindow.cpp:

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

#include <QEvent>
#include <QKeyEvent>
#include <QDebug>
#include <QTimer>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    model = new QFileSystemModel;
    model->setRootPath("/Users/anders/Downloads/Browser");

    listView = new QListView;
    listView->setModel(model);
    listView->show();

    QTimer::singleShot(2000, this, SLOT(LightItUp1()));

}

void MainWindow::LightItUp1()
{
    qDebug("LightItUp1");
    listView->setRootIndex(model->index("/Users/anders/Downloads"));
    listView->setCurrentIndex(model->index(0, 0, listView->rootIndex()));

    QTimer::singleShot(2000, this, SLOT(LightItUp2()));
}

void MainWindow::LightItUp2()
{
    qDebug("LightItUp2");
    listView->setRootIndex(model->index("/Users/anders/Downloads/Browser"));
    listView->setCurrentIndex(model->index(0, 0, listView->rootIndex()));

    QTimer::singleShot(2000, this, SLOT(LightItUp3()));
}


void MainWindow::LightItUp3()
{
    qDebug("LightItUp3");
    listView->setRootIndex(model->index("/Users/anders/Downloads"));
    listView->setCurrentIndex(model->index(0, 0, listView->rootIndex()));

    QTimer::singleShot(2000, this, SLOT(LightItUp4()));
}


void MainWindow::LightItUp4()
{
    QString p = "/Users/anders/Downloads/Mail";
    listView->setRootIndex(model->index(p));
    listView->setCurrentIndex(model->index(0, 0, listView->rootIndex()));
}

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

在这个例子中,LightItUp 1-3 做我想做的事,但 LightItUp4 没有。如果我交换 2 和 4 中的文件夹,它们都无法执行我想要的操作,而 1 和 3 仍然可以工作。我怀疑我对如何使用这个模型/视图有误解,但不知道是什么。

编辑:创建了一个更简单的示例,其中提到了@buck 的错误检查。请参阅源代码中的注释。

const QString rp = "/home/anders/src/";

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    model = new QFileSystemModel;
    model->setRootPath(rp); //using model->setRootPath(rp + "/trunk") instead works

    listView = new QListView;
    listView->setModel(model);
    listView->show();

    QTimer::singleShot(2000, this, SLOT(LightItUp1()));

}

void MainWindow::LightItUp1()
{
    qDebug("LightItUp1");
    QModelIndex p = model->index(rp + "/trunk");
    if (!p.isValid()) {
        qDebug("index not valid\n");
        return;
    }

    //model->setRootPath(rp + "/trunk") here does not make it work
    listView->setRootIndex(p);
    listView->setCurrentIndex(model->index(0, 0, p));
}

我认为当我在模型上执行 setRootPath(rp),然后将视图设置为使用模型时,如果我正确设置索引,视图应该能够在 rp 的所有子文件夹中移动。我将重读关于 Model/View、QListView 和 QFileSystemModel 的 Qtdocs,但我想发布这个以防有人了解正在发生的事情。

4

2 回答 2

2

我从这里得到了一些帮助,这些是我的结论:

为了使 QFileSystemModel 正常工作,需要运行 GUI 事件循环。我猜你是QTimer::singleShot(...)因为这个添加了这条线?但是,您只给了它 2 秒。从QFileSystemModel的文档中:

在模型填充目录之前,对 rowCount() 的调用将返回 0。

这意味着在构建 MainWindow 之后,您有 2 秒的时间来构建其他所有内容,启动 GUI 事件循环,然后让 QFileSystemModel 填充目录。失败的目录是否很大?我猜是这样。

您可以尝试给计时器更长的间隔。更好的解决方案可能是创建一个选择列表中第一件事的快捷方式,如下所示:

QShortcut* sh = new QShortcut(QKeySequence("Ctrl+1"), this);
connect(sh, SIGNAL(activated()), this, SLOT(LightUpFirst()));

并且 LightUpFirst 函数进行选择。希望有帮助!

于 2011-08-11T15:40:22.340 回答
2

我想我现在可以工作了。更改列表的 rootIndex 后,我必须等待模型完成其工作。在从模型中获得 directoryLoaded 信号之前,我不会在新目录中设置 currentIndex。现在突出作品。模型中的数据没有排序,所以 row=0 & col=0 毕竟不是列表中的第一项,但那是另一个话题 :)

编辑:今晚稍微摆弄了一下,并添加了最后的润色。

const QString rp = "/home/anders/src";

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    model = new QFileSystemModel;
    model->setRootPath(rp);

    list = new QListView;
    list->setModel(model);
    list->show();

    connect(model,
            SIGNAL(directoryLoaded(QString)),
            this,
            SLOT(model_directoryLoaded(QString)));

    QTimer::singleShot(2000, this, SLOT(changeRoot()));
}

void MainWindow::model_directoryLoaded(QString path)
{
    qDebug() << "loaded" << path;
    model->sort(0, Qt::AscendingOrder);
    list->setCurrentIndex(model->index(0, 0, list->rootIndex()));
}

void MainWindow::changeRoot()
{
    qDebug() << "changeRoot";
    model->setRootPath(rp + "/trunk");
    list->setRootIndex(model->index(rp + "/trunk"));
}

MainWindow::~MainWindow()
{
    delete list;
    delete model;
    delete ui;
}
于 2011-08-12T08:02:12.350 回答