I am currently trying to make a QTreeView to display the contents of the folder on the computer. However, I experienced some weird issue where . and .. are displayed in the tree view which I do not want that to happen. How am I suppose to disable showing . and .. in the tree view?
Here is the code for the QTreeView.
model = new QDirModel(this);
model->setReadOnly(true);
model->setSorting(QDir::DirsFirst | QDir::IgnoreCase | QDir::Name);
model->setFilter(QDir::Dirs);
ui->treeView->setModel(model);
// expand to D: Directory
QModelIndex index = model->index("D:/");
ui->treeView->expand(index);
ui->treeView->scrollTo(index);
ui->treeView->setCurrentIndex(index);
ui->treeView->resizeColumnToContents(0);
Finally figure out the answer:
model->setFilter(QDir::Dirs | QDir::NoDotAndDotDot);
Using the following will not work as the tree view can longer be expanded on each folder:
model->setFilter(QDir::Dirs);
model->setFilter(QDir::NoDotAndDotDot);
You had a look at this?
This is a standard Qt example given out with Qt creator, They are doing exact same what you want to do.
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QFileSystemModel model;
model.setFilter( QDir::Dirs | QDir::NoDotAndDotDot );
model.setRootPath("");
QTreeView tree;
tree.setModel(&model);
// Demonstrating look and feel features
tree.setAnimated(false);
tree.setIndentation(20);
tree.setSortingEnabled(true);
tree.setWindowTitle(QObject::tr("Dir View"));
#if defined(Q_OS_SYMBIAN) || defined(Q_WS_MAEMO_5)
tree.showMaximized();
#else
tree.resize(640, 480);
tree.show();
#endif
return app.exec();
}
Related
I'm trying to generate a simple QTreeView inside another widget (QMainWindow). The following code works as expected and displays the tree-view,
int main(int argc, char *argv[]) {
QApplication app(argc, argv);
MainWindow w;
w.show();
QString rootPath = "C:/";
QFileSystemModel model;
model.setRootPath("");
QTreeView tree;
tree.setModel(&model);
if (!rootPath.isEmpty()) {
const QModelIndex rootIndex = model.index(QDir::cleanPath(rootPath));
if (rootIndex.isValid())
tree.setRootIndex(rootIndex);
}
tree.setParent(&w);
tree.show();
return app.exec();
}
but if I extract the code that generates the tree-view, nothing seems to happen. The extracted function is as follows:
void create_tree(QMainWindow *w) {
QString rootPath = "C:/";
QFileSystemModel model;
model.setRootPath("");
QTreeView tree;
tree.setModel(&model);
if (!rootPath.isEmpty()) {
const QModelIndex rootIndex = model.index(QDir::cleanPath(rootPath));
if (rootIndex.isValid())
tree.setRootIndex(rootIndex);
}
tree.setParent(w);
tree.show();
}
and the corresponding function call in main function is as follows:
int main(int argc, char *argv[]) {
QApplication app(argc, argv);
MainWindow w;
w.show();
create_tree(&w);
return app.exec();
}
How does the extracted function create_tree work and why is it not showing the tree view?
QFileSystemModel model;
and
QTreeView tree;
Are local stack variables, meaning they will be gone once you exit the create_tree function.
You can solve your issue by creating them on the heap by using new, which will keep them alive. Be careful, that you need to think about how you destroy these created objects. The Qt parenting system is a great help there, because the parent will destroy its children when it is destroyed, so your tree view is fine. You should think about good parent for your model to make sure you create no memory leak.
A working version of your function looks like this - be careful that you still need to handle the models deletion:
void create_tree(QMainWindow *w) {
QString rootPath = "C:/";
QFileSystemModel* model = new QFileSystemModel();
model->setRootPath("");
QTreeView* tree = new QTreeView();
tree->setModel(model);
if (!rootPath.isEmpty()) {
const QModelIndex rootIndex = model->index(QDir::cleanPath(rootPath));
if (rootIndex.isValid())
tree->setRootIndex(rootIndex);
}
tree->setParent(w);
tree->show();
}
In my project, I have a QVector full of QStrings containing file paths/names that don't actually exist on any drive:
QVector<QString> fileNames["level.dat", "data/villages.dat", "players/player1.dat"]//etc
I want to create a tree in my QTreeWidget that resembles a sort of file directory like this:
How would I go about creating something like this quickly and efficiently?
Thanks for your time :)
This solution does not avoid duplicate, so if you need that in the future, you could extend this piece of code with adding valiation for that. Anyway, this code produces the exact ame output for me that you have just described to wish to have.
main.cpp
#include <QTreeWidget>
#include <QStringList>
#include <QApplication>
int main(int argc, char **argv)
{
QApplication application(argc, argv);
QStringList fileNames{"level.dat", "data/villages.dat", "players/player1.dat"};
QTreeWidget treeWidget;
treeWidget.setColumnCount(1);
for (const auto& filename : fileNames) {
QTreeWidgetItem *parentTreeItem = new QTreeWidgetItem(&treeWidget);
parentTreeItem->setText(0, filename.split('/').first());
QStringList filenameParts = filename.split('/').mid(1);
for (const auto& filenamePart : filenameParts) {
QTreeWidgetItem *treeItem = new QTreeWidgetItem();
treeItem->setText(0, filenamePart);
parentTreeItem->addChild(treeItem);
parentTreeItem = treeItem;
}
}
treeWidget.show();
return application.exec();
}
main.pro
TEMPLATE = app
TARGET = main
QT += widgets
CONFIG += c++14
SOURCES += main.cpp
Build and Run
qmake && make && ./main
On a site node: you ought to use QStringList rather than QVector. In addition, your current initialization attempt surely results in compiler error. That is invalid initialization.
I'm trying in QFileSystemModel display just files with extention *.txt and the other types shaded/grayed out:
proxy_ is of type QSortFilterProxyModel
model_ is of type QFileSystemModel
Here's my code:
proxy_->setFilterWildcard("*.txt");
proxy_->setSourceModel(model_);
model_->setNameFilters(QStringList(proxy_->filterRegExp().pattern()));
model_->setNameFilterDisables(true);
sel_model_ = (new QItemSelectionModel(proxy_));
treeView->setModel(proxy_);
treeView->setSelectionModel(sel_model_);
...but by doing so nothing is shown in my view. Anyone knows what I'm doing wrong?
You can set a file name filter with QFileSystemModel::setNameFilters.
In the example program below .txt and folders are displayed normally, and other files are disabled (greyed out).
The nameFilterDisables property allows you to choose between filtered out files being disabled or hidden.
#include <QtGui>
int main(int argc, char** argv)
{
QApplication app(argc, argv);
QFileSystemModel model;
model.setRootPath(QDir::rootPath());
QStringList filters;
filters << "*.txt";
model.setNameFilters(filters);
QTreeView view;
view.setModel(&model);
view.show();
return app.exec();
}
Please consider we have a menu which has text set "MyMenu" and I want to change the menu text by clicking a button in the same widget from "MyMenu" to "МойМеню". Could you bring a code snippet please for that operation?
Have a look at "Dynamic Translation", http://doc.qt.io/qt-5/internationalization.html
void MyWidget::changeEvent(QEvent *event)
{
if (e->type() == QEvent::LanguageChange)
{
titleLabel->setText(tr("Document Title"));
...
okPushButton->setText(tr("&OK"));
// You could also use : retranslateUi(QWidget*);
}
else
{
QWidget::changeEvent(event);
}
}
This will be helpful to you as well : http://doc.qt.io/qt-5/qcoreapplication.html#installTranslator
Basically, when you call : qApp->installTranslator(MyAppTranslator) it will create a QEvent::LanguageChange.
So, provide a simple QComboBox with English/Russian, and when the selected language changes, call qApp->installTranslator(MyAppTranslator);. Then make sure your buttons are properly set up in changeEvent, and that's it !
Hope it helps a bit !
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QTextCodec::setCodecForTr(QTextCodec::codecForName("UTF-8"));//this is the solution
.............
}
And in the code you can dynamically change the strings if you set them from the begining by using tr() function [tr("your text")].
I want to be able to stop a user from moving a QSplitter at runtime. Calling setEnabled(false) does this, but it also disables all child widgets - which isn't what I want. Is there a way to achieve this? Do I have to disable the splitter, and then manually re-enable all child widgets? That seems rather cumbersome, for something that must be a reasonably common practise.
Can anyone suggest anything?
Do this:
for (int i = 0; i < splitter->count(); i++)
{
QSplitterHandle *hndl = splitter->handle(i);
hndl->setEnabled(false);
}
Actually, I've never seen anyone ever disable a splitter: They are there so the user can layout the UI as she needs, so why would anyone want to disable this? Either you need a splitter or you can use one of the normal layouts (which the user can't resize).
If you still want to try, I think you should look at closestLegalPosition() or getRange(). If you just return the width of the widget, then resizing should stop working.
You have to do two things. Set the widgets (that shouldn't be resizeable) inside the splitter to FixedSize and change the cursor of the correspondent splitter handles to Qt::ArrowCursor. The handles start with zero (left and not used), so the first handle between two widgets is by index 1.
Here's a sample (put the code in main.cpp):
#include <QtGui>
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QWidget window;
window.resize(800, 300);
window.setWindowTitle("Splitter Test");
window.show();
QSplitter *splitter = new QSplitter(&window);
QListView *listview = new QListView;
QTreeView *treeview = new QTreeView;
QTextEdit *textedit = new QTextEdit;
splitter->addWidget(listview);
splitter->addWidget(treeview);
splitter->addWidget(textedit);
splitter->setChildrenCollapsible(false);
splitter->show();
listview->show();
treeview->show();
textedit->show();
//make the lisview 'fix'
listview->setFixedSize(listview->width(), listview->height());
//change the cursor over the splitter handle between listview and
//treeview to ArrowCursor
splitter->handle(1)->setCursor(Qt::ArrowCursor);;
return app.exec();
}
Now the first splitter handle is disabled and the second works.