How to show DotDot path in QTableView using QFileSystemModel? - qt

I apologize in advance for my English. I have QTableView with QFileSystemModel as model in my simple two-panel file manager. It displays files and directories correctly, but I want it to display DotDot line to move to the parent of the current directory. Setting QFileSystemModel::filter(QDir::AllEntries | QDir::NoDot) doesn't help, DotDot still doesn't display in QTableView. All of the above is true for Qt 5.9.1 on Windows 7. But when I build app on Ubuntu, it displays DotDot correctly, and QFileSystemModel::filter() perfectly works depending on it's arguments. Am I able to make it work on Windows 7 or it's a bug?
Here's simplified sample of my code:
QTableView *tableView = new QTableView;
QFileSystemModel *fsModel = new QFileSystemModel;
fsModel->setRootPath(QDir::rootPath());
fsModel->setFilter(QDir::AllEntries | QDir::NoDot);
tableView->setModel(fsModel);
QObject::connect(tableView, &QTableView::doubleClicked, tableView, &QTableView::setRootIndex);
tableView->show();

Make own class inherited from QFileSystemModel. And redefine virtual methods rowCount() and data().
That not simple way, but allow good control about content that show with that model. Of course you can add Dot and DotDot ( and even DotDotDotDot : ) )directories.

Related

Folder browser dialog in Qt

Is there any way to open a folder browser dialog in Qt? When I use QFileDialog with Directory file mode, even if I specify the ShowDirsOnly option, I get the standard file dialog. I would prefer to use a dialog that asks the user to choose a directory from a directory tree.
Here's the PySide code I'm using:
from PySide import QtGui
app = QtGui.QApplication([])
dialog = QtGui.QFileDialog()
dialog.setFileMode(QtGui.QFileDialog.Directory)
dialog.setOption(QtGui.QFileDialog.ShowDirsOnly)
dialog.exec_()
And here's the result I get on Windows 7:
It appears that the order in which you call setFileMode() and setOption() matters. Make sure you're calling setFileMode() first:
QFileDialog dialog;
dialog.setFileMode(QFileDialog::Directory);
dialog.setOption(QFileDialog::ShowDirsOnly);
...
I know, that my answer is some tricky and looks like little hack, but the QFileDialog static methods like getExistingDirectory() use the native dialog, so only limited customization is possible.
However, if you create a QFileDialog instance, you get a dialog that can
be customized -- as long as you're happy messing with a live dialog.
For example, this should show a tree view with expandable directories that
you can select (hope, it must be not a problem port this code to PySide):
QFileDialog *fd = new QFileDialog;
QTreeView *tree = fd->findChild <QTreeView*>();
tree->setRootIsDecorated(true);
tree->setItemsExpandable(true);
fd->setFileMode(QFileDialog::Directory);
fd->setOption(QFileDialog::ShowDirsOnly);
fd->setViewMode(QFileDialog::Detail);
int result = fd->exec();
QString directory;
if (result)
{
directory = fd->selectedFiles()[0];
qDebug()<<directory;
}
Got that method from here
Try this line of code, it show you a folder browse dialog:
ui->txtSaveAddress->setText(folderDlg.getExistingDirectory(0,"Caption",QString(),QFileDialog::ShowDirsOnly));
This worked for me:
def getDir(self):
dialog = QtGui.QFileDialog()
dialog.setFileMode(QtGui.QFileDialog.Directory)
dialog.setOption(QtGui.QFileDialog.ShowDirsOnly)
directory = dialog.getExistingDirectory(self, 'Choose Directory', os.path.curdir)

Strange error with QListWidgetItem that uses QIcon

I am building up a QListWidget, browsing through a directory so that every ".png" gets listed with a preview icon.
The core of my populating loop looks like this:
new QListWidgetItem( QIcon(act_fullname), act_filename);
Right after the whole list is ready, the app crashes.
The error is many times repeated and says this:
On Mac OS X, you might be loading two sets of Qt binaries into the
same process. Check that all plugins are compiled against the right Qt
binaries. Export DYLD_PRINT_LIBRARIES=1 and check that only one set of
binaries are being loaded. QObject::moveToThread: Current thread
(0x103339cb0) is not the object's thread (0x10a848670). Cannot move to
target thread (0x103339cb0)
On Mac OS X, you might be loading two sets of Qt binaries into the
same process. Check that all plugins are compiled against the right Qt
binaries. Export DYLD_PRINT_LIBRARIES=1 and check that only one set of
binaries are being loaded.
Do you have any ideas?
Thanks for your help!
EDIT:
If I skip the icons there is no problem. I have also tried going
QListWidgetItem *item = new QListWidgetItem(act_filename);
ui->listWidget->addItem(item);
item->setIcon(QIcon(act_fullname));
and got no difference.
EDIT 2:
I do not call QObject::moveToThread(QThread*) I don't even use threads (deliberately at least).
Also, the errors appear to come after the loop. I have cout-ed every iteration and the end of the loop and right after my "end loop cout msg" I see that
objc[56963]: Class QCocoaColorPanelDelegate is implemented in both
/Users/Barnabas/QtSDK/Desktop/Qt/4.8.1/gcc/lib/QtGui.framework/Versions/4/QtGui
and
/Users/Barnabas/Programming/Qt/demo_OpenCV-build-desktop-Desktop_Qt_4_8_1_for_GCC__Qt_SDK__Release/demo_OpenCV.app/Contents/MacOS/../Frameworks/QtGui.framework/Versions/4/QtGui.
One of the two will be used. Which one is undefined.
Here, too, I do not use QCocoaColorPanelDelegate. I don't even know what it is ... :(
But here is my more detailed code:
boost::filesystem::path p("/path/to/dir");
if(boost::filesystem::is_directory(p))
{
for(boost::filesystem::directory_iterator it(p); it!=boost::filesystem::directory_iterator(); ++it)
{
if(it->path().extension().string()==".png")
{
std::cout<< it->path() <<std::endl;
QString item_name( it->path.stem().c_str() );
QString screen_file( it->path.c_str() );
QListWidgetItem *item = new QListWidgetItem(item_name);
QIcon *icon = new QIcon(screen_file);
item->setIcon(*icon); // if I comment this one out, everything is fine.
ui->imageList->addItem(item);
}
}
}
I have also tested it with a single .png and the image was displayed properly in the list but crash followed with the very same messages.
I have finally found the solution: manually removed the Debug and the Release directories.
For those whose similar problem is not solved by this see: this link.

QFileDialog::getExistingDirectory does not close after choosing a folder

In Qt,
QFileDialog *dlg = new QFileDialog();
QDir dir = dlg->getExistingDirectory(this, tr("Choose folder"), qgetenv("HOME"));
opens a folder choose dialog. Once I select a folder (press choose button) the folder is not closing automatically. So I tried:
if(dlg->close() == true) delete(dlg);
When I debug the dlg->close() returns true and the code delete(dlg) is hit. Still the Folder chooser dialog box is not closing.
I am using Ubuntu 11.10 64 bit OS. Using Qt libraries from the repository.
My ultimate aim is just to show a folder chooser dialog and once the folder is chosen the dialog should close. After that processing should continue. How to do this?
Thanks in advance.
Even if QFileDialog::getExistingDirectory is static and doesn't need a QFileDialog object to work, it should close the dialog window when a directory is finally chosen.
By default that function tries to open a native file dialog window, which seems to cause some problems on some platforms.
You should try forcing a non-native dialog by adding the option DontUseNativeDialog:
QString dir = QFileDialog::getExistingDirectory(
this,
tr("Choose folder"),
QDesktopServices::storageLocation(QDesktopServices::HomeLocation),
QFileDialog::ShowDirsOnly | QFileDialog::DontUseNativeDialog);
And remove the two other lines (with new QFileDialog and if(dlg->close()) ...).
getExistingDirectory(...) is a static function.
To add to cmannett85's answer:
You should not make an instance of QDialog. If you do, it's up to you to hide it. Modify your code to read
const QString home = QDesktopServices::storageLocation(QDesktopServices::HomeLocation);
const QDir dir = QFileDialog:getExistingDirectory(this, tr("Choose folder"), home);
This code should be relatively portable. qgetenv("HOME") is Unix-specific. You should not introduce gratuituous platform-specific code in Qt-based projects -- it sort of defeats the purpose of using Qt in the first place.

Qt - Selecting multiple folders/directories using a dialog

I want to achieve something like the following:
Where I can select multiple folders across multiple drives and retrieve the folder paths of those selected. Qt only has a crude multi-folder selection feature, but it does not support selected folders from other drives etc.
Can anyone guide me on how to create such a dialog? Better yet, does any one have any sample code I could use (this is an extension to an old project, and I'd much rather save my time and not re-invent the wheel!)
Thanks
You can use QFileSystemModel for represent filesystem on QTreeView. This example explains how to do that.
For checkbox issue, according to this list archives:
The simplest way to do this (I can think of, at least) is to subclass
QDirModel and override flags, data and setData:
flags should add Qt::ItemIsUserCheckable to the returned flags
data should return the Qt::CheckState of the queried index if the role parameter is Qt::CheckStateRole
setData should store the check state of the index
Or, even better, this should work with a QProxyModel pretty much the
same way (after all, "favor object composition over class
inheritance").
Note that QDirModel class is obsolete. You may not use that on newer Qt versions. I recommend to use QFileSystemModel.
####### Retrieve a list of directories with wxPython-Phoenix - tested on python3.5
### installation instruction for wxPython-Phoenix : https://wiki.wxpython.org/How%20to%20install%20wxPython#Installing_wxPython-Phoenix_using_pip
### modified from : https://wxpython.org/Phoenix/docs/html/wx.lib.agw.multidirdialog.html
import os
import wx
import wx.lib.agw.multidirdialog as MDD
# Our normal wxApp-derived class, as usual
app = wx.App(0)
dlg = MDD.MultiDirDialog(None, title="Custom MultiDirDialog", defaultPath=os.getcwd(), # defaultPath="C:/Users/users/Desktop/",
agwStyle=MDD.DD_MULTIPLE|MDD.DD_DIR_MUST_EXIST)
if dlg.ShowModal() != wx.ID_OK:
print("You Cancelled The Dialog!")
dlg.Destroy()
paths = dlg.GetPaths()
#Print directories' path and files
for path in enumerate(paths):
print(path[1])
directory= path[1].replace('OS (C:)','C:')
print(directory)
for file in os.listdir(directory):
print(file)
dlg.Destroy()
app.MainLoop()

how to connect QActions to SLOTS using qt designer

I have created a nice looking toolbar using qt Designer and populated it with some actions.
I tried to connect the actions to slots visually from qt designer by clicking edit> signals and slots. This DID NOT WORK because i could not find any QAction signals.
Question.
Is there a way to connect the QAction SIGNAL(triggered()) to my slots within QT designer?
Please help.
PS:
I am currently being forced to connect through code:
QObject::connect(myAction, SIGNAL(triggered()),this, SLOT(myActionWasTriggered()))
but ia am lazy and i wish to connect using qt designer.
There's "Signal/Slot Editor" docked panel (Toggled with View->Signal/Slot Editor).
You can connect your actions there.
You may also need to add your custom slots via the "Change signals/slots" form context menu.
To save yourself some work, use the auto-connection feature (see QMetaObject::connectSlotsByName). Basically, all slots named with a specific pattern of on_objectName_signalName will be auto-connected.
Look here in Docs Designer Connection Mode... How to autconnect in the designer
Use the "Action editor" panel. You can find it near "Signals & Slots editor".
If you have menu, Please name your actions object according to menus , Suppose you have:
File Edit View Tools Help
You have 5 menus bar,
So you'll have a set of action_x , x is a number.Please naming your x according to your menu.
more explaintion:
File = 1
Edit = 2
View = 3
Tools = 4
Help = 5
And suppose :
File---> Open ..Close
Edit---> find...replace
View---> ZoomIn ... ZoomOut
Tools--->calender... prefrences
help---> help... about
You have 5x2 = 10 , you have 10 action, please manage such as:
action_11 == File>Open
action_12 == File>close
action_21 == Edit>find
and so on..
Above type of managing make easy your coding .....

Resources