2

一段时间以来,我一直在寻找有关此问题的线索,但没有结果。所以,这里...

我有一个应用程序,我想要一个简单的按钮来打开文件对话框窗口。主窗口上还有其他按钮可以读取或创建/写入文件(在对所选功能进行适当检查之后)。我曾经使用 QFileDialog::getSaveFileName() 函数没有问题,但是在 Windows 7 中,如果文件存在并且是只读的,这将失败。我切换到 getOpenFileName() 来解决这个问题,但现在如果用户尝试选择一个不存在的文件(与保存操作无关),文件对话框将失败。

有没有办法在文件对话框中添加“创建新文件”图标,或者将其添加到文件对话框窗口中的右键菜单中?我真的很讨厌仅仅因为(又一次)Windows 行为改变而不得不重写应用程序。

4

2 回答 2

1

QFileDialog::getOpenFileName()应该只用于打开现有文件。如果您输入一个不存在的文件的名称并且系统抱怨,这是正确的行为。它正确地告诉您无法打开不存在的文件。

如果要写入现有文件或创建新文件,则应使用QFileDialog::getSaveFileName()

如果您尝试写入在操作系统中标记为只读的现有文件,并且您收到一条错误消息,指出该文件是只读的,则该错误是正确的。您不应该被允许写入只读文件,这就是只读的意思。

根据您的解释,这里没有错误。一切都在按应有的方式发生。如果你试图强迫系统做一些不同的事情,不要这样做。您应该尝试并考虑以不同的方式做事。

于 2013-06-16T09:53:38.820 回答
0

好的,因为这里从来没有真正回答过这个问题,而且我已经找到了一个解决方案,我想我会用我正在使用的代码片段来更新它。

void MainWindow::on_tbBrowse_clicked()
{
    // Use the location of already entered file
    QString fileLocation = leFile->text();
    QFileInfo fileinfo(fileLocation);

    // See if there is a user-defined file extension.
    QString fileType = qgetenv("DiskImagerFiles");
    if (fileType.length() && !fileType.endsWith(";;"))
    {
        fileType.append(";;");
    }
    fileType.append(tr("Disk Images (*.img *.IMG);;*.*"));
    // create a generic FileDialog
    QFileDialog dialog(this, tr("Select a disk image"));
    dialog.setNameFilter(fileType);
    dialog.setFileMode(QFileDialog::AnyFile);
    dialog.setViewMode(QFileDialog::Detail);
    dialog.setConfirmOverwrite(false);
    if (fileinfo.exists())
    {
        dialog.selectFile(fileLocation);
    }
    else
    {
        dialog.setDirectory(myHomeDir);
    }

    if (dialog.exec())
    {
        // selectedFiles returns a QStringList - we just want 1 filename,
        //      so use the zero'th element from that list as the filename
        fileLocation = (dialog.selectedFiles())[0];

        if (!fileLocation.isNull())
        {
            leFile->setText(fileLocation);
            QFileInfo newFileInfo(fileLocation);
            myHomeDir = newFileInfo.absolutePath();
        }
        setReadWriteButtonState();
        updateHashControls();
    }
}

setReadWriteButtonState() 将根据文件状态启用按钮:

  • 如果文件是只读的,则仅启用读取按钮
  • 如果文件不存在,则仅启用写入按钮

其他人可以在https://sourceforge.net/projects/win32diskimager/上查看整个代码。我希望这可以帮助下一个正在寻找解决方案的人。如果您使用我们的代码,请注明出处。

于 2019-07-19T22:32:37.007 回答