【问题标题】:How to create a generic file selection dialog in QT4 for Windows如何在 QT4 for Windows 中创建通用文件选择对话框
【发布时间】:2013-06-15 00:05:37
【问题描述】:

我一直在寻找有关此问题的线索一段时间,但没有结果。所以,就这样吧……

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

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

【问题讨论】:

  • “失败”是什么意思?您的程序是否失败或在 Windows 中是否出现故障?如果您希望写入已经存在并标记为只读的文件,我当然希望 Windows 不会允许它。这不是失败,这是成功。在尝试修改文件之前,您应该始终进行制衡。
  • 失败,我的意思是当您单击确定时,对话框会产生错误并且不会让您继续。在 getSaveFileName 和只读文件的情况下,错误类似于“文件是只读的,无法选择”。在新文件和 getOpenFileName 的情况下,错误是“文件不存在”。在这两种情况下,您都会返回到文件对话框,并且可以选择不需要的文件,或者必须取消。
  • 鉴于这里没有回应(非常令人惊讶),看来我将不得不冒险制作自己的文件对话框。我真的不喜欢必须有两个单独的文件对话框 api 调用,它们基本上不做任何事情,只是将文件名返回给调用函数,但会根据 api 调用创建限制。使用具有多个选项的单个函数会产生相同的结果,这会更好。
  • QFileDialog 的重点是提供文件名和文件路径。它还可以作为底层操作系统的验证器,以便在您开始读取或写入文件之前防止愚蠢的事情发生。如果你真的坚持执行非标准的操作,你一定会想到必须编写并行代码流。

标签: windows qt filedialog


【解决方案1】:

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

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

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

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

【讨论】:

  • 因此出现了“如何向文件对话框添加功能”的问题。我已经知道 getOpenFileName 和 getSaveFileName 的预期行为。我只需要一个 getFileName,因为无论如何程序都会在内部打开。
【解决方案2】:

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

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/ 上查看整个代码。我希望这可以帮助下一个正在寻找解决方案的人。如果您使用我们的代码,请注明出处。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-05
    • 1970-01-01
    • 2013-07-22
    • 1970-01-01
    • 2014-11-26
    • 2013-04-19
    相关资源
    最近更新 更多