Qt: Change icon in a QFileInfo object - c++

My foremost question is:
How do I set/change the file icon in a QFileInfo object?
If you look at my code, Qlist<QFileInfo> lists the icon of all my folders in my home directory as gnome-fs-directory. Which means, QFileInfo lists even my desktop folder's icon as plain gnome-fs-directory.
But I want Desktop to have QFileIconProvider::Desktop as icon.
Which consequently leads to the 2nd question:
Is QFileInfo the appropriate class to use to find out the icon that QFileSystemModel would use?
Which leads to the 3rd question:
Why did my QDir not pass QFileSystemModel a QFileInfo list with the appropriate icon role for Desktop?
So the ultimate question is, what do I have to do to ensure QFileSystemModel uses the appropriate icon role, when listing itself in a tree view or list view?
Code to find out the file icon of each folder in the home folder:
void MainWindow::fileIconInfo(QFileSystemModel *model)
{
QFileIconProvider *iconprov = model->iconProvider();
QFileInfoList fileInfoList = QDir::home().entryInfoList();
QFileInfoList::Iterator i;
foreach (QFileInfo fi, fileInfoList){
if (fi.fileName() == QString("Desktop"))
/*change the icon to QFileIconProvider::Desktop*/;
//the following line indicates all my icons are gnome-fs-directory!!*/
std::cout << iconprov->icon(fi).name().toStdString() << std::endl;
}
}
This is my main window:
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
fileSystemTree(ui->listView);
fileSystemTree(ui->treeView);
}
Setting the model for the view:
void MainWindow::fileSystemTree(QAbstractItemView *view) {
QFileSystemModel *model = new QFileSystemModel;
model->setRootPath(QDir::homePath());
view->setModel(model);
view->setRootIndex(model->index(QDir::homePath()));
fileIconInfo(model);
}

I think what you are describing is caused by the fact that QFileIconProvider is detecting that you use Gnome, and the is using Gtk style - no matter what. Could you try to start some other desktop environment and see if problem remains? If it does then I am right and only thing you can do is to subclass QFileSystemModel and change QIcon returned from data method - but this is quite crude and non-flexible solution.

Related

On QTreeView double_Clicked event: how to know which folder was clicked?

I'm still pretty new to C++ and qt creator. I have a TreeView displaying a directory, and upon double-clicking a folder I'd like to be able to get the directory of the folder, so i can do something with the contents. I notice the double_Clicked event passing along a "const QModelIndex& index" and I suppose this holds some information on which folder of the tree was clicked. I can't find any documentation on this signal, and what the "index" passed along could be. Does anyone have an explanation, tutorial, example, documentation, ... for me? I've been searching for awhile and trying things out but I can't find the solution. Or additionally: how can I check what gets passed along? How could I print this, or know what it is?
You can set up your treeView in the constructor like this:
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
model = new QFileSystemModel(this);
model->setRootPath("");
ui->treeView->setModel(model);
ui->treeView->setRootIndex(model->index("/home/waqar/"));
}
And in the double_Clicked() slot, use the QModelIndex to get the name of the folder you clicked on:
void MainWindow::on_treeView_doubleClicked(const QModelIndex &index)
{
//displays the name of the folder you clicked on in the terminal
qDebug () << index.data(Qt::DisplayRole).toString();
//get full path
QString path = model->filePath(index)
}

How to get names of files from a folder and add them to a tree widget as children in qt

I am making a program that needs to be able to output the names of files from a specific folder as items in a Tree Widget but I cannot seem to figure it out. I managed to do it in a list widget without too much hassle but I cant get that code to work with a tree widget. Below is the code I wrote to get the described functionality with a list widget
mainwindow.cpp
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
QString path = "C:/Program Files/GUI_Project/bin";
QDir dir(path);
if (!dir.exists())
{
dir.mkpath(path);
}
QDir myPath(path);
myPath.setFilter(QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot);
MyList = myPath.entryList();
ui->listWidget->addItems(MyList);
}
Another option is to use a QFileSystemModel and use setRootPath("your/path") to create a model of a folder. You can use setFilter() to decide what is shown Filter List.Then you can add that model to a QTreeView. It's just like a QTreeWidget except it has much better performance and is the better option for most use cases imo. For example, if a file gets added or deleted from that directory, the model will change and update in your program. A QTreeWidget can't do that.
QFileSystemModel *dirModel = new QFileSystemModel(); //Create new model
dirModel->setRootPath("C:/Program Files/GUI_Project/bin"); //Set model path
dirModel->setFilter(QDir::Files); //Only show files
ui->treeView->setModel(dirModel); //Add model to QTreeView
QModelIndex idx = dirModel->index("C:/Program Files/GUI_Project/bin"); //Set the root item
ui->treeView->setRootIndex(idx);
If you want to stick with a QTreeWidget however, you will have to recursively iterate over a folders contents and add each item individually.
You simply iterate over your input list and create a QTreeWidgetItem object for each entry.
If you pass the tree widget as the parent it will become a top level item in the tree, if you pass another tree widget item as the parent, it becomes a child entry of that item.

Qt C++ Creating toolbar

I am learning Qt and trying some examples in the book "Foundations of Qt Development".
In the book, there is a section teaching Single Document Interface with an example creating a simple app like a notepad.
However I am having problem with toolbar creating.
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
setAttribute(Qt::WA_DeleteOnClose);
setWindowTitle(QString("%1[*] - %2").arg("unnamed").arg("SDI"));
connect(ui->docWidget->document(), SIGNAL(modificationChanged(bool)), this, SLOT(setWindowModified(bool)));
createActions();
createMenu();
createToolbars();
statusBar()->showMessage("Done");
}
It is the constructor of the main window.
void MainWindow::createToolbars()
{
QToolBar* toolbar;
toolbar = addToolBar(tr("File"));
toolbar->addAction(anyaction);
}
This is how the book create the toolbar.
However, when I try to run the program, there are two toolbars created.
One is the toolbar created by the code and called "File"
Another is a blank toolbar created by the ui designer ie. *ui.toolbar.
In order to get rid of two toolbars, I tried using only the *ui.toolbar.
It's working. The code is shown below.
void MainWindow::createToolbars()
{
ui->toolBar->addAction(anyaction);
}
But I tried to create the toolbar by code only, ie. not adding a toolbar in the ui designer.
So I write this:
void MainWindow::createToolbars()
{
QToolBar* FileBar = this->addToolBar(tr("File"));
FileBar->addAction(anyaction);
}
However, there is a compile error.
The compiler use this function:
void QMainWindow::addToolBar(QT::ToolBarArea area, QToolBar * toolbar)
instead of what I want:
QToolBar * QMainWindow::addToolBar(const QString & title)
http://doc.qt.io/qt-5/qmainwindow.html#addToolBar-3
What is my mistake here?
When you removed QToolBar from MainWindow QtCreator automatically removed import of QToolBar class.
Just add this to the top of mainwindow.h:
#include <QToolBar>
And it is better to define QToolBar* FileBar in private section of MainWindow in mainwindow.h. Then you will be able to access it from any method of MainWindow class.
void MainWindow::createToolbars()
{
FileBar = this->addToolBar(tr("File"));
FileBar->addAction(anyaction);
}
When you see such message:
must point to class/struct/union/generic type
First of all try to include headers for necessary class.

QSystemTrayIcon shows only place holder and not the real icon

My code below brings up the icon but its like empty with nothing in it. if I move the mouse cursor over the expected icon location (last one) in system tray, its there but it doesn't show the real icon. It's more like just a place holder for the icon.
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
systemTray = new QSystemTrayIcon();
systemTray->setIcon( QIcon::fromTheme("edit-undo") ); // stock icon but I have tried use local icon file too with same result
systemTray->setVisible( true ); // extra insurance
systemTray->show();
}
What am I doing wrong? I am using Qt 5.4 and Windows 7
I don't know why the stock icon doesn't work but it was a syntax and qmake issue. I had the path given as ":/icons/file.ico" or "icons/file.ico". The correct syntax is below otherwise it will not show the actual icon. Also I had to 'run qmake' apparently needed when new icon is added to qrc because even when the syntax was right, the problem was still there.
systemTray->setIcon( QIcon(":icons/file.ico") );

How to add tabs dynamically in a Qt?

I want to add tabs dynamically in a Qt application depending on user inputs.
One tab is to be there all the time by default. For convenience, it would be great if I could create the layout and features of this tab in the graphic editor. Then I would like to transfer this layout into code, put in a class constructor and add tabs like:
ui->tabWidget->addTab(new myTabClass(), "Tab 2");
I want to promote this tab programatically as well. Is that possible?
For adding tabs dynamically and constructed by a class, you can use an additional .ui file. This way you can do all the layout stuff with the Qt Designer GUI.
1) Create an empty tab widget in the mainwindow.ui. (eg. named myTabWidget)
2) Add to your project directory a new “Qt Design Form Class” as QWidget class, not as QTabWidget (eg. named MyTabPage):
Right click project -> Add new -> Qt -> Qt Design Form Class
3) In the mytabpage.ui you make the design as you want it to be inserted in myTabWidget.
4) The next step you can instantiate MyTabPage in the MainWindow constructer or elsewhere and add it to myTabWidget. The empty tab in myTabWidget can be removed before. To access paramaters form myNewTab you need a function declared in MyTabPage.
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
MyTabPage *myNewTab = new MyTabPage;
ui-> myTabWidget ->removeTab(0);
ui-> myTabWidget ->addTab(myNewTab, tr("name"))
myNewTab->functionDeclaredInMyTabPage (); //access parameters of myNewTab
}
PS: I am aware the question is old. But I want to offer a step by step solution to others cause I had to struggle with it for my self recently.
You can insert tab by int QTabWidget::insertTab ( int index, QWidget * page, const QIcon & icon, const QString & label ) which inserts a tab with the given label, page, and icon into the tab widget at the specified index :
ui->tabWidget->insertTab(1,new myTabClass(),QIcon(QString(":/SomeIcon.ico")),"TabText");
Also removing a tab is done by QTabWidget::removeTab ( int index ).