問題現象
- 調用QFileDialog的靜态函數(比如getFileName)在客戶環境下會有随機崩潰現象,無法捕獲異常,也沒有任何提示資訊。
- 根據網頁資料 https://www.cnblogs.com/zi-xing/p/6217172.html 推測,懷疑是靜态函數調用的系統資源檔案管理器跟某些軟體沖突導緻。解決方法就是使用QT封裝的檔案對話框代替系統資源檔案管理器。
解決方法
簡單寫法
- 靜态函數調用的時候設定參數:Options options( QFileDialog::DontUseNativeDialog ),意思就是不使用系統資源檔案管理器。這樣代碼代碼改動最小,但是有2個缺點:
- 預設樣式帶問号,不美觀
- 選擇儲存路徑的時候,不自動添加檔案字尾,使用不友善
複雜寫法
- 自定義檔案對話框類FileDialogEx,繼承QFileDialog。
- 構造函數中設定對話框屬性樣式,取消問号
- 封裝對應的靜态接口
對話框樣式屬性設定
FileDialogEx::FileDialogEx(QWidget *parent /*= nullptr*/,
const QString &caption /*= QString()*/,
const QString &directory /*= QString()*/,
const QString &filter /*= QString()*/) :QFileDialog(parent,caption,directory,filter)
{
Qt::WindowFlags flags = Qt::Dialog | Qt::WindowCloseButtonHint;
this->setWindowFlags(flags);
this->setModal(true);
this->setOption(QFileDialog::DontUseNativeDialog); ///< 不是用本地對話框
}
封裝選擇儲存路徑接口,自動添加檔案字尾
QString FileDialogEx::GetSaveFileNameEx()
{
QString strSaveFileName;
this->setAcceptMode(AcceptSave);
if (this->exec() == QDialog::Accepted)
{
strSaveFileName = selectedFiles().value(0);
QString strTempSelectedFilter = selectedNameFilter();
int nStart = strTempSelectedFilter.indexOf("(");
int nEnd = strTempSelectedFilter.indexOf(")");
int nLength = nEnd - nStart -2;
QString strSelectedFilter = strTempSelectedFilter.mid(nStart+2, nLength);
if (!strSaveFileName.endsWith(strSelectedFilter))
{
strSaveFileName.append(strSelectedFilter);
}
}
return strSaveFileName;
}
封裝選擇路徑接口
QString FileDialogEx::GetExistingDirectoryEx()
{
QString strExistingDir;
this->setFileMode(QFileDialog::DirectoryOnly);
if (this->exec() == QDialog::Accepted)
{
strExistingDir = selectedFiles().value(0);
}
return strExistingDir;
}
封裝選擇單個檔案接口
QString FileDialogEx::GetOpenFileNameEx()
{
QString strOpenFileName;
this->setAcceptMode(AcceptOpen);
if (this->exec() == QDialog::Accepted)
{
strOpenFileName = selectedFiles().value(0);
}
return strOpenFileName;
}
封裝選擇多個檔案接口
QStringList FileDialogEx::GetOpenFileNamesEx()
{
QStringList strOpenFileNames;
this->setAcceptMode(AcceptOpen);
this->setFileMode(QFileDialog::ExistingFiles);
if (this->exec() == QDialog::Accepted)
{
strOpenFileNames = selectedFiles();
}
return strOpenFileNames;
}