Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

QFileDialog has memory



  • I've got an mf that operates on a QFileDialog member variable.

    If I call it the first time the filename field at the bottom is empty:

    a7f7da23-bf20-4b62-8278-a3a4e4b8db8c-image.png

    If I then select (say) three files, select Open to open the files and then reinvoke the mf, the filename field now contains the first of the files I selected on the previous invocation:

    b74f507d-0b57-4b67-b730-38b6bd45f502-image.png

    How do I prevent that memory effect? I already tried fileDialog.selectFile(QString());

    My code:

    void CStackingDlg::OnAddpictures()
    {
    	ZFUNCTRACE_RUNTIME();
    	QSettings			settings;
    	QString				directory;
    	QString				extension;
    	uint				filterIndex = 0;
    	QString				strTitle;
    
    	directory = settings.value("Folders/AddPictureFolder").toString();
    
    	extension = settings.value("Folders/AddPictureExtension").toString();
    
    	filterIndex = settings.value("Folders/AddPictureIndex", 0U).toUInt();
    	
    	if (extension.isEmpty())
    		extension = "bmp";			// Note that Qt doesn't want/ignores leading . in file extensions
    
    	fileDialog.setWindowTitle(QCoreApplication::translate("StackingDlg", "Open Light Frames...", "IDS_TITLE_OPENLIGHTFRAMES"));
    	fileDialog.setDefaultSuffix(extension);
    	fileDialog.setFileMode(QFileDialog::ExistingFiles);
    
    	const QStringList filters({
    		QCoreApplication::translate("StackingDlg", "Picture Files (*.bmp *.jpg *.jpeg *.tif *.tiff *.png *.fit *.fits *.fts *.cr2 *.cr3 *.crw *.nef *.mrw *.orf *.raf *.pef *.x3f *.dcr *.kdc *.srf *.arw *.raw *.dng *.ia *.rw2)"),
    		QCoreApplication::translate("StackingDlg", "Windows Bitmaps (*.bmp)"),
    		QCoreApplication::translate("StackingDlg", "JPEG or PNG Files (*.jpg *.jpeg *.png)"),
    		QCoreApplication::translate("StackingDlg", "TIFF Files (*.tif *.tiff)"),
    		QCoreApplication::translate("StackingDlg", "RAW Files (*.cr2 *.cr3 *.crw *.nef *.mrw *.orf *.raf *.pef *.x3f *.dcr *.kdc *.srf *.arw *.raw *.dng *.ia *.rw2)"),
    		QCoreApplication::translate("StackingDlg", "FITS Files (*.fits *.fit *.fts)"),
    		QCoreApplication::translate("StackingDlg", "All Files (*)")
    		});
    
    	fileDialog.setNameFilters(filters);
    	fileDialog.selectFile(QString());		// No file(s) selected
    	if (!directory.isEmpty())
    		fileDialog.setDirectory(directory);
    
    	//
    	// A value of zero for filterIndex means that the user hasn't previously chosen a name filter.
    	// 
    	// If the user *has* previously chosen a name filter, then that index is 1 based, not zero based.
    	// This means that the index must be decremented to index into the list of name filters.
    	//
    	// Should a name filter not have been chosen the system will initially select the first one.
    	//
    	if (filterIndex > 0)
    	{
    		fileDialog.selectNameFilter(filters.at(filterIndex-1));
    	}
    
    	ZTRACE_RUNTIME("About to show file open dlg");
    	if (QDialog::Accepted == fileDialog.exec())
    	{
    		QGuiApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
    		QStringList files = fileDialog.selectedFiles();
    		for (int i = 0; i < files.size(); i++)
    		{
    			fs::path file(files.at(i).toStdU16String());		// as UTF-16
    
    			m_Pictures.AddFile((LPCTSTR)file.generic_wstring().c_str(), m_Pictures.GetCurrentGroupID(), m_Pictures.GetCurrentJobID());
    			directory = QString::fromStdU16String(file.remove_filename().generic_u16string());
    			extension = QString::fromStdU16String(file.extension().generic_u16string());
    		};
    		QGuiApplication::restoreOverrideCursor();
    		m_Pictures.RefreshList();
    
    		//
    		// What filter has the user actually selected, or has been auto-selected?
    		// Note that the index value we store is 1 based, not zero based, so add one to the selected index.
    		// 
    		filterIndex = filters.indexOf(fileDialog.selectedNameFilter());
    		filterIndex++;		
    		settings.setValue("Folders/AddPictureFolder", directory);
    		settings.setValue("Folders/AddPictureExtension", extension);
    		settings.setValue("Folders/AddPictureIndex", filterIndex);
    
    		UpdateGroupTabs();
    	};
    	UpdateListInfo();
    }
    

  • Lifetime Qt Champion

    @Perdrix One easy solution would be to create one dialog instance each time you need one, instead of reusing the same instance. Or use static https://doc.qt.io/qt-5/qfiledialog.html#getOpenFileNames



  • @jsulm
    Correct, but this is a reasonable request from @Perdrix. It does seem there isn't a way to clear what has been typed into the File name: box (e.g. https://forum.qt.io/topic/60821/clear-file-selection-in-a-qfiledialog). If the OP tries fileDialog.selectFile("") instead of fileDialog.selectFile(QString()), just in case, and that still does not clear, is there really no way to re-use a dialog instance which has previously had a name typed into it? Seems like a strange omission....


  • Lifetime Qt Champion

    @Perdrix @JonB I could not find anything. A change request in Qt bug-tracker would make sense.


Log in to reply