Qt:使用 QListView 和 QFileSystemModel 浏览文件系统。如何突出显示文件夹中的第一项?
我正在没有键盘/鼠标的系统上执行该主题所说的操作,因此我需要“通过代码”来完成这项工作。当我更改 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 和 2 中的文件夹4 他们都没有做到我想要的,而 1 和 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 的所有子文件夹中移动。我将重读有关模型/视图、QListView 和 QFileSystemModel 的 Qtdocs,但想发布此内容以防有人理解发生了什么。
I'm doing what the topic says on a system without keyboard/mouse, so I need to make this work "from code". When I change the RootIndex of the QListView I want to highlight the first row.
Here's mainwindow.cpp from a small testproject I've made:
#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;
}
In this example LightItUp 1-3 do what I want, but LightItUp4 does not. If I swap the folders in 2 & 4 both of them fail to do what I want, while 1 & 3 still work. I suspect I have misunderstood something about how to use this Model/View, but have no idea what.
Edit: created a simpler example with the error checking @buck mentioned. See the comments in the source code.
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));
}
I thought that when I do setRootPath(rp) on the model, and then set the view to use the model, the view should able to move around in all subfolders of rp if I set the indexes correctly. I'll reread the Qtdocs on Model/View, QListView and QFileSystemModel, but wanted to post this in case someone understands what is happening.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我从这里得到了一些帮助,这些是我的结论
:为了使 QFileSystemModel 正常工作,GUI 事件循环需要运行。我猜您因此添加了
QTimer::singleShot(...)
行?然而,你只给了它2秒钟。从 QFileSystemModel 的文档中:这意味着在构建 MainWindow 后,您有 2 秒的时间来构建其他所有内容、启动 GUI 事件循环,然后让 QFileSystemModel 填充目录。失败的目录是否很大?我猜是这样。
您可以尝试的是给计时器更长的间隔。更好的解决方案可能是创建一个快捷方式来选择列表中的第一个内容,如下所示:
然后由 LightUpFirst 函数进行选择。希望有帮助!
I had some help from here and these are my conclusions:
In order for the QFileSystemModel to work properly, the GUI event loop needs to be running. I'm guessing you added the
QTimer::singleShot(...)
line because of this? However, you only gave it 2 seconds. From the documentation for QFileSystemModel:This means after your MainWindow is constructed, you have 2 seconds for everything else to be constructed, the GUI event loop to start, and then for the QFileSystemModel to populate the directory. Are the directories where this is failing large? I am guessing so.
What you could try would be to give the timer a longer interval. A better solution may be to create a shortcut that selects the first thing in the list, like this:
and the LightUpFirst function does the selecting. Hope that helps!
我想我现在已经可以使用了。更改列表的 rootIndex 后,我必须等待模型完成其工作。在从模型中获取directoryLoaded 信号之前,我不会在新目录中设置currentIndex。现在重点介绍作品。模型中的数据未排序,因此 row=0 & col=0 毕竟不是列表中的第一项,但那是另一个主题:)
编辑:今晚对此进行了更多修改,并添加了最后的修改。
I think I have it working now. After changing the rootIndex of the list, I have to wait for the model to do its work. I don't set the currentIndex in the new directory until I get the directoryLoaded signal from the model. Now highlighting works. The data from the model is not sorted, so row=0 & col=0 is not the first item in the list after all, but that's another topic :)
Edit: fiddled a bit more with this tonight, and added the final touches.